/** * Get the object of the class itself * @return object */ public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; }
/** * @param array $systemRoutes * @return array */ public static function getAdminRoutes(array $systemRoutes) { $routes = array(); foreach ($systemRoutes as $route => $params) { list($httpMethod, $routePattern) = RouterHelper::extractHttpRoute($route); if (preg_match('/^\\/admin(\\/|$)/', $routePattern)) { if (preg_match('/^\\\\?PSFS/', $params["class"])) { $profile = "superadmin"; } else { $profile = "admin"; } if (!empty($params["default"]) && preg_match('/(GET|ALL)/i', $httpMethod)) { $_profile = $params["visible"] ? $profile : 'adminhidden'; if (!array_key_exists($_profile, $routes)) { $routes[$_profile] = array(); } $routes[$_profile][] = $params["slug"]; } } } if (array_key_exists("superadmin", $routes)) { asort($routes["superadmin"]); } if (array_key_exists("adminhidden", $routes)) { asort($routes["adminhidden"]); } if (array_key_exists('admin', $routes)) { asort($routes["admin"]); } return $routes; }
/** * Get browse rules that are defined in acl.xml. Browse rules define the accessible module-controller-actions * before user login under the authentication control. * * @return array all the browse rules. */ public function getBrowseRules() { $xmldom = $this->getDOMfromXML($this->_aclxml); $rdom = $xmldom->getElementsByTagName(AclXmlConstant::ACL_ACCESS_CONTROL_EXCLUSION)->item(0); $mdom = $rdom->getElementsByTagName(AclXmlConstant::MODULE); $rules = array(); for ($i = 0; $i < $mdom->length; $i++) { $node = $mdom->item($i); $module_name = $node->getAttribute(AclXmlConstant::NAME); $anode = $node->getElementsByTagName(AclXmlConstant::ACL_ALLOW); if ($anode->length == 0) { $rules[$module_name] = AclXmlConstant::ALL_CONTROLLERS; continue; } for ($j = 0; $j < $anode->length; $j++) { $adom = $anode->item($j); $controller_node = $adom->getElementsByTagName(AclXmlConstant::CONTROLLER)->item(0); if (!is_null($controller_node)) { if ($controller_node->nodeType == 1) { $controllerName = $controller_node->nodeValue; $controllerName = RouterHelper::hyphenToCamelCase($controllerName, TRUE); } } $act_node = $adom->getElementsByTagName(AclXmlConstant::ACTION); if ($act_node->length == 0) { $rules[$module_name][$controllerName] = AclXmlConstant::ALL_ACTIONS; continue; } $action_rules = array(); for ($k = 0; $k < $act_node->length; $k++) { $action = $act_node->item($k); if (!is_null($action)) { if ($action->nodeType == 1) { $actionName = $action->nodeValue; $actionName = RouterHelper::hyphenToCamelCase($actionName); $action_rules[$k] = $actionName; } } } $rules[$module_name][$controllerName] = $action_rules; } } return $rules; }
/** * Rendering a layout. It also renders the views that the layout contains. * @throws AiryException */ public function render() { //To get the layout file $layoutContent = file_get_contents($this->_layoutPath); $this->prepareContent($layoutContent); //Fetch each views $viewContents = array(); foreach ($this->_layout as $contentKey => $viewComponent) { //check if it is an array that contains module controller action if (is_array($viewComponent)) { $moduleName = MvcReg::getModuleName(); $moduleName = isset($viewComponent[self::MODULE]) ? $viewComponent[self::MODULE] : $moduleName; try { if (isset($viewComponent[self::CONTROLLER])) { $controllerName = $viewComponent[self::CONTROLLER]; } else { throw new AiryException('Layout is missing controller'); } if (isset($viewComponent[self::ACTION])) { $actionName = $viewComponent[self::ACTION]; } else { throw new AiryException('Layout is missing controller'); } $paramString = ""; if (isset($viewComponent[self::PARAMS])) { $paramString = $this->getParamString($viewComponent[self::PARAMS]); } $HttpServerHost = PathService::getAbsoluteHostURL(); $config = Config::getInstance(); $LeadingUrl = $HttpServerHost . "/" . $config->getLeadFileName(); $mvcKeywords = $config->getMVCKeyword(); $moduleKey = $mvcKeywords['module']; $controllerKey = $mvcKeywords['controller']; $actionKey = $mvcKeywords['action']; $moduleName = RouterHelper::hyphenToCamelCase($moduleName); $controllerName = RouterHelper::hyphenToCamelCase($controllerName, TRUE); $actionName = RouterHelper::hyphenToCamelCase($actionName); $actionPath = $moduleKey . "=" . $moduleName . "&" . $controllerKey . "=" . $controllerName . "&" . $actionKey . "=" . $actionName; $url = $LeadingUrl . "?" . $actionPath . $paramString; //check if it is already signed in //if yes, add current action into allow action query string if (Authentication::isLogin($moduleName)) { $filename = "mca_file" . microtime(true); $md5Filename = md5($filename); $content = $moduleName . ";" . $controllerName . ";" . $actionName; $content = md5($content); FileCache::saveFile($md5Filename, $content); $url = $url . '&' . self::ALLOW_THIS_ACTION . '=' . $md5Filename; } $viewContent = $this->getData($url); $viewContents[$contentKey] = $viewContent; } catch (Exception $e) { $errorMsg = sprintf("View Exception: %s", $e->getMessage()); throw new AiryException($errorMsg); } } else { if ($viewComponent instanceof AppView) { //Use $this->_view->render(); $viewComponent->setInLayout(true); $viewContent = $viewComponent->render(); $viewContents[$contentKey] = $viewContent; } else { $viewContent = file_get_contents($viewComponent); $viewContent = Language::getInstance()->replaceWordByKey($viewContent); $viewContents[$contentKey] = $viewContent; } } } /** * Deal with layout variables */ if (!is_null($this->_variables)) { foreach ($this->_variables as $name => $value) { if ($value instanceof UIComponent || $value instanceof JUIComponent) { $htmlValue = $value->render(); $newHtmlValue = Language::getInstance()->replaceWordByKey($htmlValue); ${$name} = $newHtmlValue; } else { ${$name} = $value; } } } //Loop through each contents //Replace view components with keywords $layoutContent = $this->composeContent($layoutContent, $viewContents); //Check if inserting doctype at the beginning of the view content if (!$this->_noDoctype) { if (is_null($this->_doctype)) { $this->setDoctype(); } } $layoutContent = $this->_doctype . $layoutContent; //Stream output $existed = in_array("airy.layout", stream_get_wrappers()); if ($existed) { stream_wrapper_unregister("airy.layout"); } stream_wrapper_register('airy.layout', 'StreamHelper'); $fp = fopen("airy.layout://layout_content", "r+"); fwrite($fp, $layoutContent); fclose($fp); include "airy.layout://layout_content"; }
/** * Get the action view file. * @param string $moduleName * @param string $controllerName * @param string $actionName * @return string */ private function getActionViewFile($moduleName, $controllerName, $actionName) { $viewArray = RouterHelper::getActionViewData($moduleName, $controllerName, $actionName); return $viewArray[1]; }
/** * The forward function is to call the action according to the module, controller and action. * The function needs to consider all the forward restrictions and rules. * * @param string $moduleName the forwarding module name * @param string $controllerName the forwarding controller name * @param string $actionName the forwarding action name * @param array $params the url params * @param object $router an instance of Router the default value = null * */ public static function forward($moduleName, $controllerName, $actionName, $params, $router = null) { $Router = is_null($router) ? new Router() : $router; $Router->setDefaultModelView($controllerName); $controller = $controllerName . self::CONTROLLER_POSTFIX; $action = $actionName . self::ACTION_POSTFIX; $controllerfile = RouterHelper::getControllerFile($moduleName, $controller); try { if (file_exists($controllerfile)) { require_once $controllerfile; //Check special Authentication controller /* * If status */ $Config = Config::getInstance(); $auth_array = $Config->getAuthenticationConfig(); if ($auth_array['use_authentication'] == "enable") { /** * if the controller and actions are those login related ones, * we exclude them, let them dispatch. */ if (Authentication::isLogin($moduleName)) { // need to acl rule after login // put them here // if (Authentication::getSuccessController($moduleName) == $controllerName && Authentication::getSuccessAction($moduleName) == $actionName) { Dispatcher::setRoute($moduleName, $controllerName, $actionName); } Dispatcher::toMVC($controller, $action, $params); return; } else { //all allowed actions that are defined in acl.xml $allows = Authentication::getAllAllows($moduleName); //Change the controllerName to ControllerName //because the router already transform the value $controllerName = ucfirst($controllerName); //Dispatch sequence - checking allowing actions before checking login related actions //(1) Check acl access exclusions //Case #1: allow all controllers in the module if ($allows == self::ALL_CONTROLLERS) { Dispatcher::toMVC($controller, $action, $params); return; } //Case #2: allow all actions in a specific controller if (isset($allows[$controllerName]) && $allows[$controllerName] == self::ALL_ACTIONS) { Dispatcher::toMVC($controller, $action, $params); return; } //Case #3: allow a specific action in a specific controller if (isset($allows[$controllerName])) { $allowActions = $allows[$controllerName]; foreach ($allowActions as $idx => $allowAction) { //echo "{$allowAction}=={$actionName}"; if ($allowAction == $actionName) { Dispatcher::toMVC($controller, $action, $params); return; } } } //Case #4: Special cases, passing the actions in layout (due to using http request to get view) if (isset(Authentication::$layoutAllows[$moduleName][$controllerName])) { $allowActions = Authentication::$layoutAllows[$moduleName][$controllerName]; foreach ($allowActions as $idx => $allowAction) { if ($allowAction == $actionName) { //unset the action Authentication::removeLayoutAllowAction($moduleName, $controllerName, $actionName); Dispatcher::toMVC($controller, $action, $params); return; } } } //(2) Check login related actions $loginActions = Authentication::getLoginExcludeActions($moduleName); if (isset($loginActions[$controllerName][$actionName])) { Dispatcher::toMVC($controller, $action, $params); return; } //(3) None of above satisfies, forward to login controller action $loginControllerName = Authentication::getLoginController($moduleName); $loginController = Authentication::getLoginController($moduleName) . self::CONTROLLER_POSTFIX; $loginActionName = Authentication::getLoginAction($moduleName); $loginAction = Authentication::getLoginAction($moduleName) . self::ACTION_POSTFIX; Dispatcher::setRoute($moduleName, $loginControllerName, $loginActionName); Dispatcher::toMVC($loginController, $loginAction, $params); } } else { Dispatcher::toMVC($controller, $action, $params); } } else { $errorMsg = "Controller {$controller} or controller file {$controllerfile} is missing"; throw new AiryException($errorMsg); } } catch (Exception $e) { $errorMsg = "<h3><b>Dispatching ERROR!</b></h3>" . $e->getMessage(); $ifDisplayError = $Config = Config::getInstance()->getDisplayError(); if ($ifDisplayError == "enable") { echo $errorMsg; } } }
/** * Set the default action view. * @param string $controllerName * @param string $actionName */ public function setDefaultActionView($controllerName, $actionName) { $actionViewArray = RouterHelper::getActionViewData($this->moduleName, $controllerName, $actionName); $actionViewClassName = $actionViewArray[0]; $actionViewFile = $actionViewArray[1]; MvcReg::setActionViewClassName($actionViewClassName); MvcReg::setActionViewFile($actionViewFile); }