<?php
/*
 * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

class sly_Controller_Rbac extends sly_Controller_Backend implements sly_Controller_Interface {
	private function pageHeader() {
		$layout = sly_Core::getLayout();
		$layout->pageHeader(t('rbac'));
	}

	public function indexAction() {
		$this->pageHeader();
		$this->listView();
	}

	protected function listView() {
		$service = pac_RoleService::getInstance();
		$roles   = $service->getAllRoles();
		$data    = array('roles' => array());

		foreach ($roles as $id => $role) {
			$count = $service->getUsersWithRole($role);
			$data['roles'][$id] = array('role' => $role, 'count' => $count);
		}

		$this->render('index.phtml', $data, false);
	}

	public function addroleAction() {
		$save = sly_post('save', 'boolean', false);

		if ($save) {
			$title    = sly_post('role_title', 'string', '');
			$includes = sly_postArray('role_includes', 'int', array());

			try {
				pac_RoleService::getInstance()->createRole($title, $includes);
				$this->pageHeader();
				print sly_Helper_Message::info(t('rbac_role_added'));
				$this->listView();
			}
			catch (pac_Exception $e) {
				$this->pageHeader();
				print sly_Helper_Message::warn(t('rbac_error_role_add'));

				$data = array(
					'role'          => null,
					'roleId'        => -1,
					'role_title'    => $title,
					'role_includes' => $includes,
					'title'         => t('rbac_add_role')
				);

				$this->render('edit_role.phtml', $data, false);
			}
		}
		else {
			$this->pageHeader();

			$data = array(
				'role'          => null,
				'roleId'        => -1,
				'role_title'    => '',
				'role_includes' => array(),
				'title'         => t('rbac_add_role')
			);

			$this->render('edit_role.phtml', $data, false);
		}
	}

	public function editroleAction() {
		$this->pageHeader();

		$roleService = pac_RoleService::getInstance();
		$roleId      = sly_request('role_id', 'int', -1);
		$save        = sly_post('save', 'boolean', false);
		$dispatcher  = sly_Core::dispatcher();

		$roleService->validate($roleId);

		if ($save) {
			$title    = sly_post('role_title', 'string', '');
			$includes = sly_postArray('role_includes', 'int', array());

			try {
				$roleService->editRole($roleId, $title, $includes);

				$permissions       = sly_post('wv42_perm', 'array');
				$destinationConfig = sly_Authorisation::getConfig();

				foreach ($destinationConfig as $destination => $config) {
					$destPermissions = isset($permissions[$destination]) ? $permissions[$destination] : array();
					$values          = array();

					if (isset($config['list'])) {
						foreach ($destPermissions as $objectId => $tokens) {
							foreach ($tokens as $token) {
								$values[$token][] = $objectId;
							}
						}
					}
					else {
						foreach ($destPermissions as $token) {
							$values[$token] = true;
						}
					}

					$values = $dispatcher->filter('WV42_DESTINATION_VALUES', $values, array('destination' => $destination, 'config' => $config));
					$roleService->setDestinationValues($roleId, $destination, $values);
				}

				print sly_Helper_Message::info(t('rbac_role_edited'));
			}
			catch (pac_Exception $e) {
				print sly_Helper_Message::warn($e->getMessage());
				print sly_Helper_Message::warn(t('rbac_error_role_edit'));
			}
		}

		WV42_UserCache::flush();

		if ($_SERVER['REQUEST_METHOD'] === 'GET' || sly_post('apply', 'string')) {
			$role = $roleService->getRoleById($roleId);
			$data = array(
				'role'          => $role,
				'roleId'        => $roleId,
				'role_title'    => $role->getTitle(),
				'role_includes' => $role->getIncludes(),
				'action'        => 'index.php?page=rbac&func=doEditRole',
				'title'         => t('rbac_edit_role'),
				'roles'         => $roleService->getAllRoles()
			);

			$this->render('edit_role.phtml', $data, false);
		}
		else {
			$this->listView();
		}
	}

	public function deleteroleAction() {
		$roleId = sly_request('role_id', 'int', -1);

		$roleService = pac_RoleService::getInstance();
		$roleService->validate($roleId);
		$roleService->deleteRole($roleId);

		$this->pageHeader();
		print sly_Helper_Message::info(t('rbac_role_deleted'));
		$this->listView();
	}

	protected function getViewFolder() {
		return SLY_RBAC_PATH.'views'.DIRECTORY_SEPARATOR;
	}

	public function checkPermission($action) {
		$user = sly_Util_User::getCurrentUser();
		return $user !== null && $user->isAdmin();
	}

	protected function getModules() {
		$service = sly_Service_Factory::getModuleService();
		return $service->getModules();
	}

	protected function getStructure() {
		$rootCats        = sly_Util_Category::getRootCategories();
		$this->structure = array('0' => t('all'));

		if ($rootCats) {
			foreach ($rootCats as $rootCat) {
				$this->walkTree($rootCat, 0, $this->structure);
			}
		}

		return $this->structure;
	}

	protected function getMediaStructure() {
		$rootCats          = sly_Util_MediaCategory::getRootCategories();
		$this->mediaStruct = array('0' => t('all'));

		if ($rootCats) {
			foreach ($rootCats as $rootCat) {
				$this->walkTree($rootCat, 0, $this->mediaStruct);
			}
		}

		return $this->mediaStruct;
	}

	protected function walkTree($category, $depth, &$target) {
		if (empty($category)) return;

		$target[$category->getId()] = str_repeat(' ', $depth*2).$category->getName();

		$children = $category->getChildren();

		if (is_array($children)) {
			foreach ($children as $child) {
				$this->walkTree($child, $depth + 1, $target);
			}
		}
	}
}
