123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- <?php
- /**
- * CWebApplication class file.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.yiiframework.com/
- * @copyright 2008-2013 Yii Software LLC
- * @license http://www.yiiframework.com/license/
- */
- /**
- * CWebApplication extends CApplication by providing functionalities specific to Web requests.
- *
- * CWebApplication manages the controllers in MVC pattern, and provides the following additional
- * core application components:
- * <ul>
- * <li>{@link urlManager}: provides URL parsing and constructing functionality;</li>
- * <li>{@link request}: encapsulates the Web request information;</li>
- * <li>{@link session}: provides the session-related functionalities;</li>
- * <li>{@link assetManager}: manages the publishing of private asset files.</li>
- * <li>{@link user}: represents the user session information.</li>
- * <li>{@link themeManager}: manages themes.</li>
- * <li>{@link authManager}: manages role-based access control (RBAC).</li>
- * <li>{@link clientScript}: manages client scripts (javascripts and CSS).</li>
- * <li>{@link widgetFactory}: creates widgets and supports widget skinning.</li>
- * </ul>
- *
- * User requests are resolved as controller-action pairs and additional parameters.
- * CWebApplication creates the requested controller instance and let it to handle
- * the actual user request. If the user does not specify controller ID, it will
- * assume {@link defaultController} is requested (which defaults to 'site').
- *
- * Controller class files must reside under the directory {@link getControllerPath controllerPath}
- * (defaults to 'protected/controllers'). The file name and the class name must be
- * the same as the controller ID with the first letter in upper case and appended with 'Controller'.
- * For example, the controller 'article' is defined by the class 'ArticleController'
- * which is in the file 'protected/controllers/ArticleController.php'.
- *
- * @property IAuthManager $authManager The authorization manager component.
- * @property CAssetManager $assetManager The asset manager component.
- * @property CHttpSession $session The session component.
- * @property CWebUser $user The user session information.
- * @property IViewRenderer $viewRenderer The view renderer.
- * @property CClientScript $clientScript The client script manager.
- * @property IWidgetFactory $widgetFactory The widget factory.
- * @property CThemeManager $themeManager The theme manager.
- * @property CTheme $theme The theme used currently. Null if no theme is being used.
- * @property CController $controller The currently active controller.
- * @property string $controllerPath The directory that contains the controller classes. Defaults to 'protected/controllers'.
- * @property string $viewPath The root directory of view files. Defaults to 'protected/views'.
- * @property string $systemViewPath The root directory of system view files. Defaults to 'protected/views/system'.
- * @property string $layoutPath The root directory of layout files. Defaults to 'protected/views/layouts'.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @package system.web
- * @since 1.0
- */
- class CWebApplication extends CApplication
- {
- /**
- * @return string the route of the default controller, action or module. Defaults to 'site'.
- */
- public $defaultController='site';
- /**
- * @var mixed the application-wide layout. Defaults to 'main' (relative to {@link getLayoutPath layoutPath}).
- * If this is false, then no layout will be used.
- */
- public $layout='main';
- /**
- * @var array mapping from controller ID to controller configurations.
- * Each name-value pair specifies the configuration for a single controller.
- * A controller configuration can be either a string or an array.
- * If the former, the string should be the class name or
- * {@link YiiBase::getPathOfAlias class path alias} of the controller.
- * If the latter, the array must contain a 'class' element which specifies
- * the controller's class name or {@link YiiBase::getPathOfAlias class path alias}.
- * The rest name-value pairs in the array are used to initialize
- * the corresponding controller properties. For example,
- * <pre>
- * array(
- * 'post'=>array(
- * 'class'=>'path.to.PostController',
- * 'pageTitle'=>'something new',
- * ),
- * 'user'=>'path.to.UserController',
- * )
- * </pre>
- *
- * Note, when processing an incoming request, the controller map will first be
- * checked to see if the request can be handled by one of the controllers in the map.
- * If not, a controller will be searched for under the {@link getControllerPath default controller path}.
- */
- public $controllerMap=array();
- /**
- * @var array the configuration specifying a controller which should handle
- * all user requests. This is mainly used when the application is in maintenance mode
- * and we should use a controller to handle all incoming requests.
- * The configuration specifies the controller route (the first element)
- * and GET parameters (the rest name-value pairs). For example,
- * <pre>
- * array(
- * 'offline/notice',
- * 'param1'=>'value1',
- * 'param2'=>'value2',
- * )
- * </pre>
- * Defaults to null, meaning catch-all is not effective.
- */
- public $catchAllRequest;
- /**
- * @var string Namespace that should be used when loading controllers.
- * Default is to use global namespace.
- * @since 1.1.11
- */
- public $controllerNamespace;
- private $_controllerPath;
- private $_viewPath;
- private $_systemViewPath;
- private $_layoutPath;
- private $_controller;
- private $_theme;
- /**
- * Processes the current request.
- * It first resolves the request into controller and action,
- * and then creates the controller to perform the action.
- */
- public function processRequest()
- {
- if(is_array($this->catchAllRequest) && isset($this->catchAllRequest[0]))
- {
- $route=$this->catchAllRequest[0];
- foreach(array_splice($this->catchAllRequest,1) as $name=>$value)
- $_GET[$name]=$value;
- }
- else
- $route=$this->getUrlManager()->parseUrl($this->getRequest());
- $this->runController($route);
- }
- /**
- * Registers the core application components.
- * This method overrides the parent implementation by registering additional core components.
- * @see setComponents
- */
- protected function registerCoreComponents()
- {
- parent::registerCoreComponents();
- $components=array(
- 'session'=>array(
- 'class'=>'CHttpSession',
- ),
- 'assetManager'=>array(
- 'class'=>'CAssetManager',
- ),
- 'user'=>array(
- 'class'=>'CWebUser',
- ),
- 'themeManager'=>array(
- 'class'=>'CThemeManager',
- ),
- 'authManager'=>array(
- 'class'=>'CPhpAuthManager',
- ),
- 'clientScript'=>array(
- 'class'=>'CClientScript',
- ),
- 'widgetFactory'=>array(
- 'class'=>'CWidgetFactory',
- ),
- );
- $this->setComponents($components);
- }
- /**
- * @return IAuthManager the authorization manager component
- */
- public function getAuthManager()
- {
- return $this->getComponent('authManager');
- }
- /**
- * @return CAssetManager the asset manager component
- */
- public function getAssetManager()
- {
- return $this->getComponent('assetManager');
- }
- /**
- * @return CHttpSession the session component
- */
- public function getSession()
- {
- return $this->getComponent('session');
- }
- /**
- * @return CWebUser the user session information
- */
- public function getUser()
- {
- return $this->getComponent('user');
- }
- /**
- * Returns the view renderer.
- * If this component is registered and enabled, the default
- * view rendering logic defined in {@link CBaseController} will
- * be replaced by this renderer.
- * @return IViewRenderer the view renderer.
- */
- public function getViewRenderer()
- {
- return $this->getComponent('viewRenderer');
- }
- /**
- * Returns the client script manager.
- * @return CClientScript the client script manager
- */
- public function getClientScript()
- {
- return $this->getComponent('clientScript');
- }
- /**
- * Returns the widget factory.
- * @return IWidgetFactory the widget factory
- * @since 1.1
- */
- public function getWidgetFactory()
- {
- return $this->getComponent('widgetFactory');
- }
- /**
- * @return CThemeManager the theme manager.
- */
- public function getThemeManager()
- {
- return $this->getComponent('themeManager');
- }
- /**
- * @return CTheme the theme used currently. Null if no theme is being used.
- */
- public function getTheme()
- {
- if(is_string($this->_theme))
- $this->_theme=$this->getThemeManager()->getTheme($this->_theme);
- return $this->_theme;
- }
- /**
- * @param string $value the theme name
- */
- public function setTheme($value)
- {
- $this->_theme=$value;
- }
- /**
- * Creates the controller and performs the specified action.
- * @param string $route the route of the current request. See {@link createController} for more details.
- * @throws CHttpException if the controller could not be created.
- */
- public function runController($route)
- {
- if(($ca=$this->createController($route))!==null)
- {
- list($controller,$actionID)=$ca;
- $oldController=$this->_controller;
- $this->_controller=$controller;
- $controller->init();
- $controller->run($actionID);
- $this->_controller=$oldController;
- }
- else
- throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
- array('{route}'=>$route===''?$this->defaultController:$route)));
- }
- /**
- * Creates a controller instance based on a route.
- * The route should contain the controller ID and the action ID.
- * It may also contain additional GET variables. All these must be concatenated together with slashes.
- *
- * This method will attempt to create a controller in the following order:
- * <ol>
- * <li>If the first segment is found in {@link controllerMap}, the corresponding
- * controller configuration will be used to create the controller;</li>
- * <li>If the first segment is found to be a module ID, the corresponding module
- * will be used to create the controller;</li>
- * <li>Otherwise, it will search under the {@link controllerPath} to create
- * the corresponding controller. For example, if the route is "admin/user/create",
- * then the controller will be created using the class file "protected/controllers/admin/UserController.php".</li>
- * </ol>
- * @param string $route the route of the request.
- * @param CWebModule $owner the module that the new controller will belong to. Defaults to null, meaning the application
- * instance is the owner.
- * @return array the controller instance and the action ID. Null if the controller class does not exist or the route is invalid.
- */
- public function createController($route,$owner=null)
- {
- if($owner===null)
- $owner=$this;
- if(($route=trim($route,'/'))==='')
- $route=$owner->defaultController;
- $caseSensitive=$this->getUrlManager()->caseSensitive;
- $route.='/';
- while(($pos=strpos($route,'/'))!==false)
- {
- $id=substr($route,0,$pos);
- if(!preg_match('/^\w+$/',$id))
- return null;
- if(!$caseSensitive)
- $id=strtolower($id);
- $route=(string)substr($route,$pos+1);
- if(!isset($basePath)) // first segment
- {
- if(isset($owner->controllerMap[$id]))
- {
- return array(
- Yii::createComponent($owner->controllerMap[$id],$id,$owner===$this?null:$owner),
- $this->parseActionParams($route),
- );
- }
- if(($module=$owner->getModule($id))!==null)
- return $this->createController($route,$module);
- $basePath=$owner->getControllerPath();
- $controllerID='';
- }
- else
- $controllerID.='/';
- $className=ucfirst($id).'Controller';
- $classFile=$basePath.DIRECTORY_SEPARATOR.$className.'.php';
- if($owner->controllerNamespace!==null)
- $className=$owner->controllerNamespace.'\\'.str_replace('/','\\',$controllerID).$className;
- if(is_file($classFile))
- {
- if(!class_exists($className,false))
- require($classFile);
- if(class_exists($className,false) && is_subclass_of($className,'CController'))
- {
- $id[0]=strtolower($id[0]);
- return array(
- new $className($controllerID.$id,$owner===$this?null:$owner),
- $this->parseActionParams($route),
- );
- }
- return null;
- }
- $controllerID.=$id;
- $basePath.=DIRECTORY_SEPARATOR.$id;
- }
- }
- /**
- * Parses a path info into an action ID and GET variables.
- * @param string $pathInfo path info
- * @return string action ID
- */
- protected function parseActionParams($pathInfo)
- {
- if(($pos=strpos($pathInfo,'/'))!==false)
- {
- $manager=$this->getUrlManager();
- $manager->parsePathInfo((string)substr($pathInfo,$pos+1));
- $actionID=substr($pathInfo,0,$pos);
- return $manager->caseSensitive ? $actionID : strtolower($actionID);
- }
- else
- return $pathInfo;
- }
- /**
- * @return CController the currently active controller
- */
- public function getController()
- {
- return $this->_controller;
- }
- /**
- * @param CController $value the currently active controller
- */
- public function setController($value)
- {
- $this->_controller=$value;
- }
- /**
- * @return string the directory that contains the controller classes. Defaults to 'protected/controllers'.
- */
- public function getControllerPath()
- {
- if($this->_controllerPath!==null)
- return $this->_controllerPath;
- else
- return $this->_controllerPath=$this->getBasePath().DIRECTORY_SEPARATOR.'controllers';
- }
- /**
- * @param string $value the directory that contains the controller classes.
- * @throws CException if the directory is invalid
- */
- public function setControllerPath($value)
- {
- if(($this->_controllerPath=realpath($value))===false || !is_dir($this->_controllerPath))
- throw new CException(Yii::t('yii','The controller path "{path}" is not a valid directory.',
- array('{path}'=>$value)));
- }
- /**
- * @return string the root directory of view files. Defaults to 'protected/views'.
- */
- public function getViewPath()
- {
- if($this->_viewPath!==null)
- return $this->_viewPath;
- else
- return $this->_viewPath=$this->getBasePath().DIRECTORY_SEPARATOR.'views';
- }
- /**
- * @param string $path the root directory of view files.
- * @throws CException if the directory does not exist.
- */
- public function setViewPath($path)
- {
- if(($this->_viewPath=realpath($path))===false || !is_dir($this->_viewPath))
- throw new CException(Yii::t('yii','The view path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- /**
- * @return string the root directory of system view files. Defaults to 'protected/views/system'.
- */
- public function getSystemViewPath()
- {
- if($this->_systemViewPath!==null)
- return $this->_systemViewPath;
- else
- return $this->_systemViewPath=$this->getViewPath().DIRECTORY_SEPARATOR.'system';
- }
- /**
- * @param string $path the root directory of system view files.
- * @throws CException if the directory does not exist.
- */
- public function setSystemViewPath($path)
- {
- if(($this->_systemViewPath=realpath($path))===false || !is_dir($this->_systemViewPath))
- throw new CException(Yii::t('yii','The system view path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- /**
- * @return string the root directory of layout files. Defaults to 'protected/views/layouts'.
- */
- public function getLayoutPath()
- {
- if($this->_layoutPath!==null)
- return $this->_layoutPath;
- else
- return $this->_layoutPath=$this->getViewPath().DIRECTORY_SEPARATOR.'layouts';
- }
- /**
- * @param string $path the root directory of layout files.
- * @throws CException if the directory does not exist.
- */
- public function setLayoutPath($path)
- {
- if(($this->_layoutPath=realpath($path))===false || !is_dir($this->_layoutPath))
- throw new CException(Yii::t('yii','The layout path "{path}" is not a valid directory.',
- array('{path}'=>$path)));
- }
- /**
- * The pre-filter for controller actions.
- * This method is invoked before the currently requested controller action and all its filters
- * are executed. You may override this method with logic that needs to be done
- * before all controller actions.
- * @param CController $controller the controller
- * @param CAction $action the action
- * @return boolean whether the action should be executed.
- */
- public function beforeControllerAction($controller,$action)
- {
- return true;
- }
- /**
- * The post-filter for controller actions.
- * This method is invoked after the currently requested controller action and all its filters
- * are executed. You may override this method with logic that needs to be done
- * after all controller actions.
- * @param CController $controller the controller
- * @param CAction $action the action
- */
- public function afterControllerAction($controller,$action)
- {
- }
- /**
- * Do not call this method. This method is used internally to search for a module by its ID.
- * @param string $id module ID
- * @return CWebModule the module that has the specified ID. Null if no module is found.
- */
- public function findModule($id)
- {
- if(($controller=$this->getController())!==null && ($module=$controller->getModule())!==null)
- {
- do
- {
- if(($m=$module->getModule($id))!==null)
- return $m;
- } while(($module=$module->getParentModule())!==null);
- }
- if(($m=$this->getModule($id))!==null)
- return $m;
- }
- /**
- * Initializes the application.
- * This method overrides the parent implementation by preloading the 'request' component.
- */
- protected function init()
- {
- parent::init();
- // preload 'request' so that it has chance to respond to onBeginRequest event.
- $this->getRequest();
- }
- }
|