<?php

class Eppe_Acl extends Zend_Acl {

	const SUPER_ADMIN = 'superadmin';
	const ANONYMOUS = 'anonymous';
	
	static $_roles = [];

	static function checkAllowed($params,$storage='Frontend') {
		/* @var $user RedBean_OODBBean */
		$authClass = 'Eppe_Auth_'.$storage;
		$auth = new $authClass();
		$user = $auth->getIdentity();
		
		// dzięki temu $params przyjmuje postać tablicy z kluczami 'module','controller','action'
		static::_getParams($params);

		$moduleInstance = Eppe_Module_ModuleAbstract::getModuleInstance($params['module']);

		$resource = $moduleInstance->acl->createRes($params['module'], $params['controller'], $params['action']);
		//Kiedy sprawdzac przypadek z wildcardem na akcje? [module.controller.*]
		if (!$moduleInstance->acl->has($resource)) {
			//Wtedy, gdy nie ma pierwotnie sprawdzanego zasobu...
			$resource = $moduleInstance->acl->createRes($params['module'], $params['controller'], '*');
		}
		
		if (!$moduleInstance->acl->has($resource)) {
			// Nie ma zasobu
			throw new Rtn_Exception_Acl("ACL Resource does not exist '$resource'");
		}
		
		return static::isUserOrAnonymousAllowed($user, $resource, $moduleInstance);
	}
	
	protected static function isUserOrAnonymousAllowed($user,$resource,$moduleInstance){
		if ($user) {
			$roles = $user->sharedRole;
			foreach ($roles as $role) {
				if ($moduleInstance->acl->isAllowed(new Zend_Acl_Role($role->name), $resource)) {
					return true;
				}
			}
		}
		else {
			return $moduleInstance->acl->isAllowed(new Zend_Acl_Role(static::ANONYMOUS), $resource);
		}		
	}

	public function init() {
		$this->_setRoles();
		$this->allow(static::SUPER_ADMIN);
	}

	/**
	 * Dodaje role, które mają być dostępne
	 */
	protected function _setRoles() {
		$roles = R::findAll('role');
		foreach ($roles as $role) {
			static::$_roles[$role->name] = $role->id;
			$this->addRole(new Zend_Acl_Role($role->name));
		}
	}

	// SUPER_ADMIN'a nie trzeba bedzie podawac za kazdym razem. Na koncu damy mu uprawnienia do wszystkiego po prostu....
	// Listujemy tylko inne niz super_admin uprawnienia

	/**
	 * Tworzy uprawnienie w postaci zasobu i uprawnionych ról
	 *
	 * @param type $module
	 * @param type $controller
	 * @param type $action
	 * @param array $rolesAllowed
	 * @return Eppe_Acl
	 */
	protected function _addPriv($module, $controller, $action, array $rolesAllowed) {
		$resource = $this->createRes($module, $controller, $action);
		if (!$this->has($resource)) {
			$this->addResource($resource);
		}

		foreach ($rolesAllowed as $role) {
			$this->allow($role, $resource);
		}

		return $this;
	}

	/**
	 * Tworzy zasób
	 * @param type $module
	 * @param type $controller
	 * @param type $action
	 * @return \Zend_Acl_Resource
	 */
	public function createRes($module, $controller, $action) {
		return new Zend_Acl_Resource($module . '.' . $controller . '.' . $action);
	}

	protected static function _getParams(&$params) {
		if (is_object($params)) {
			if (get_class($params) == 'Zend_Controller_Request_Http') {
				$params = array('module' => $params->getModuleName(),
					'controller' => $params->getControllerName(),
					'action' => $params->getActionName());
			}
		}
	}

}
