CViewAction.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. /**
  3. * CViewAction class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CViewAction represents an action that displays a view according to a user-specified parameter.
  12. *
  13. * By default, the view being displayed is specified via the <code>view</code> GET parameter.
  14. * The name of the GET parameter can be customized via {@link viewParam}.
  15. * If the user doesn't provide the GET parameter, the default view specified by {@link defaultView}
  16. * will be displayed.
  17. *
  18. * Users specify a view in the format of <code>path.to.view</code>, which translates to the view name
  19. * <code>BasePath/path/to/view</code> where <code>BasePath</code> is given by {@link basePath}.
  20. *
  21. * Note, the user specified view can only contain word characters, dots and dashes and
  22. * the first letter must be a word letter.
  23. *
  24. * @property string $requestedView The name of the view requested by the user.
  25. * This is in the format of 'path.to.view'.
  26. *
  27. * @author Qiang Xue <qiang.xue@gmail.com>
  28. * @package system.web.actions
  29. * @since 1.0
  30. */
  31. class CViewAction extends CAction
  32. {
  33. /**
  34. * @var string the name of the GET parameter that contains the requested view name. Defaults to 'view'.
  35. */
  36. public $viewParam='view';
  37. /**
  38. * @var string the name of the default view when {@link viewParam} GET parameter is not provided by user. Defaults to 'index'.
  39. * This should be in the format of 'path.to.view', similar to that given in
  40. * the GET parameter.
  41. * @see basePath
  42. */
  43. public $defaultView='index';
  44. /**
  45. * @var string the name of the view to be rendered. This property will be set
  46. * once the user requested view is resolved.
  47. */
  48. public $view;
  49. /**
  50. * @var string the base path for the views. Defaults to 'pages'.
  51. * The base path will be prefixed to any user-specified page view.
  52. * For example, if a user requests for <code>tutorial.chap1</code>, the corresponding view name will
  53. * be <code>pages/tutorial/chap1</code>, assuming the base path is <code>pages</code>.
  54. * The actual view file is determined by {@link CController::getViewFile}.
  55. * @see CController::getViewFile
  56. */
  57. public $basePath='pages';
  58. /**
  59. * @var mixed the name of the layout to be applied to the views.
  60. * This will be assigned to {@link CController::layout} before the view is rendered.
  61. * Defaults to null, meaning the controller's layout will be used.
  62. * If false, no layout will be applied.
  63. */
  64. public $layout;
  65. /**
  66. * @var boolean whether the view should be rendered as PHP script or static text. Defaults to false.
  67. */
  68. public $renderAsText=false;
  69. private $_viewPath;
  70. /**
  71. * Returns the name of the view requested by the user.
  72. * If the user doesn't specify any view, the {@link defaultView} will be returned.
  73. * @return string the name of the view requested by the user.
  74. * This is in the format of 'path.to.view'.
  75. */
  76. public function getRequestedView()
  77. {
  78. if($this->_viewPath===null)
  79. {
  80. if(!empty($_GET[$this->viewParam]) && is_string($_GET[$this->viewParam]))
  81. $this->_viewPath=$_GET[$this->viewParam];
  82. else
  83. $this->_viewPath=$this->defaultView;
  84. }
  85. return $this->_viewPath;
  86. }
  87. /**
  88. * Resolves the user-specified view into a valid view name.
  89. * @param string $viewPath user-specified view in the format of 'path.to.view'.
  90. * @return string fully resolved view in the format of 'path/to/view'.
  91. * @throws CHttpException if the user-specified view is invalid
  92. */
  93. protected function resolveView($viewPath)
  94. {
  95. // start with a word char and have word chars, dots and dashes only
  96. if(preg_match('/^\w[\w\.\-]*$/',$viewPath))
  97. {
  98. $view=strtr($viewPath,'.','/');
  99. if(!empty($this->basePath))
  100. $view=$this->basePath.'/'.$view;
  101. if($this->getController()->getViewFile($view)!==false)
  102. {
  103. $this->view=$view;
  104. return;
  105. }
  106. }
  107. throw new CHttpException(404,Yii::t('yii','The requested view "{name}" was not found.',
  108. array('{name}'=>$viewPath)));
  109. }
  110. /**
  111. * Runs the action.
  112. * This method displays the view requested by the user.
  113. * @throws CHttpException if the view is invalid
  114. */
  115. public function run()
  116. {
  117. $this->resolveView($this->getRequestedView());
  118. $controller=$this->getController();
  119. if($this->layout!==null)
  120. {
  121. $layout=$controller->layout;
  122. $controller->layout=$this->layout;
  123. }
  124. $this->onBeforeRender($event=new CEvent($this));
  125. if(!$event->handled)
  126. {
  127. if($this->renderAsText)
  128. {
  129. $text=file_get_contents($controller->getViewFile($this->view));
  130. $controller->renderText($text);
  131. }
  132. else
  133. $controller->render($this->view);
  134. $this->onAfterRender(new CEvent($this));
  135. }
  136. if($this->layout!==null)
  137. $controller->layout=$layout;
  138. }
  139. /**
  140. * Raised right before the action invokes the render method.
  141. * Event handlers can set the {@link CEvent::handled} property
  142. * to be true to stop further view rendering.
  143. * @param CEvent $event event parameter
  144. */
  145. public function onBeforeRender($event)
  146. {
  147. $this->raiseEvent('onBeforeRender',$event);
  148. }
  149. /**
  150. * Raised right after the action invokes the render method.
  151. * @param CEvent $event event parameter
  152. */
  153. public function onAfterRender($event)
  154. {
  155. $this->raiseEvent('onAfterRender',$event);
  156. }
  157. }