167 lines
5.2 KiB
PHP
167 lines
5.2 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* CViewAction 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/
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* CViewAction represents an action that displays a view according to a user-specified parameter.
|
||
|
*
|
||
|
* By default, the view being displayed is specified via the <code>view</code> GET parameter.
|
||
|
* The name of the GET parameter can be customized via {@link viewParam}.
|
||
|
* If the user doesn't provide the GET parameter, the default view specified by {@link defaultView}
|
||
|
* will be displayed.
|
||
|
*
|
||
|
* Users specify a view in the format of <code>path.to.view</code>, which translates to the view name
|
||
|
* <code>BasePath/path/to/view</code> where <code>BasePath</code> is given by {@link basePath}.
|
||
|
*
|
||
|
* Note, the user specified view can only contain word characters, dots and dashes and
|
||
|
* the first letter must be a word letter.
|
||
|
*
|
||
|
* @property string $requestedView The name of the view requested by the user.
|
||
|
* This is in the format of 'path.to.view'.
|
||
|
*
|
||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||
|
* @package system.web.actions
|
||
|
* @since 1.0
|
||
|
*/
|
||
|
class CViewAction extends CAction
|
||
|
{
|
||
|
/**
|
||
|
* @var string the name of the GET parameter that contains the requested view name. Defaults to 'view'.
|
||
|
*/
|
||
|
public $viewParam='view';
|
||
|
/**
|
||
|
* @var string the name of the default view when {@link viewParam} GET parameter is not provided by user. Defaults to 'index'.
|
||
|
* This should be in the format of 'path.to.view', similar to that given in
|
||
|
* the GET parameter.
|
||
|
* @see basePath
|
||
|
*/
|
||
|
public $defaultView='index';
|
||
|
/**
|
||
|
* @var string the name of the view to be rendered. This property will be set
|
||
|
* once the user requested view is resolved.
|
||
|
*/
|
||
|
public $view;
|
||
|
/**
|
||
|
* @var string the base path for the views. Defaults to 'pages'.
|
||
|
* The base path will be prefixed to any user-specified page view.
|
||
|
* For example, if a user requests for <code>tutorial.chap1</code>, the corresponding view name will
|
||
|
* be <code>pages/tutorial/chap1</code>, assuming the base path is <code>pages</code>.
|
||
|
* The actual view file is determined by {@link CController::getViewFile}.
|
||
|
* @see CController::getViewFile
|
||
|
*/
|
||
|
public $basePath='pages';
|
||
|
/**
|
||
|
* @var mixed the name of the layout to be applied to the views.
|
||
|
* This will be assigned to {@link CController::layout} before the view is rendered.
|
||
|
* Defaults to null, meaning the controller's layout will be used.
|
||
|
* If false, no layout will be applied.
|
||
|
*/
|
||
|
public $layout;
|
||
|
/**
|
||
|
* @var boolean whether the view should be rendered as PHP script or static text. Defaults to false.
|
||
|
*/
|
||
|
public $renderAsText=false;
|
||
|
|
||
|
private $_viewPath;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Returns the name of the view requested by the user.
|
||
|
* If the user doesn't specify any view, the {@link defaultView} will be returned.
|
||
|
* @return string the name of the view requested by the user.
|
||
|
* This is in the format of 'path.to.view'.
|
||
|
*/
|
||
|
public function getRequestedView()
|
||
|
{
|
||
|
if($this->_viewPath===null)
|
||
|
{
|
||
|
if(!empty($_GET[$this->viewParam]) && is_string($_GET[$this->viewParam]))
|
||
|
$this->_viewPath=$_GET[$this->viewParam];
|
||
|
else
|
||
|
$this->_viewPath=$this->defaultView;
|
||
|
}
|
||
|
return $this->_viewPath;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Resolves the user-specified view into a valid view name.
|
||
|
* @param string $viewPath user-specified view in the format of 'path.to.view'.
|
||
|
* @return string fully resolved view in the format of 'path/to/view'.
|
||
|
* @throw CHttpException if the user-specified view is invalid
|
||
|
*/
|
||
|
protected function resolveView($viewPath)
|
||
|
{
|
||
|
// start with a word char and have word chars, dots and dashes only
|
||
|
if(preg_match('/^\w[\w\.\-]*$/',$viewPath))
|
||
|
{
|
||
|
$view=strtr($viewPath,'.','/');
|
||
|
if(!empty($this->basePath))
|
||
|
$view=$this->basePath.'/'.$view;
|
||
|
if($this->getController()->getViewFile($view)!==false)
|
||
|
{
|
||
|
$this->view=$view;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
throw new CHttpException(404,Yii::t('yii','The requested view "{name}" was not found.',
|
||
|
array('{name}'=>$viewPath)));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Runs the action.
|
||
|
* This method displays the view requested by the user.
|
||
|
* @throws CHttpException if the view is invalid
|
||
|
*/
|
||
|
public function run()
|
||
|
{
|
||
|
$this->resolveView($this->getRequestedView());
|
||
|
$controller=$this->getController();
|
||
|
if($this->layout!==null)
|
||
|
{
|
||
|
$layout=$controller->layout;
|
||
|
$controller->layout=$this->layout;
|
||
|
}
|
||
|
|
||
|
$this->onBeforeRender($event=new CEvent($this));
|
||
|
if(!$event->handled)
|
||
|
{
|
||
|
if($this->renderAsText)
|
||
|
{
|
||
|
$text=file_get_contents($controller->getViewFile($this->view));
|
||
|
$controller->renderText($text);
|
||
|
}
|
||
|
else
|
||
|
$controller->render($this->view);
|
||
|
$this->onAfterRender(new CEvent($this));
|
||
|
}
|
||
|
|
||
|
if($this->layout!==null)
|
||
|
$controller->layout=$layout;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Raised right before the action invokes the render method.
|
||
|
* Event handlers can set the {@link CEvent::handled} property
|
||
|
* to be true to stop further view rendering.
|
||
|
* @param CEvent $event event parameter
|
||
|
*/
|
||
|
public function onBeforeRender($event)
|
||
|
{
|
||
|
$this->raiseEvent('onBeforeRender',$event);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Raised right after the action invokes the render method.
|
||
|
* @param CEvent $event event parameter
|
||
|
*/
|
||
|
public function onAfterRender($event)
|
||
|
{
|
||
|
$this->raiseEvent('onAfterRender',$event);
|
||
|
}
|
||
|
}
|