PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/yii/framework/web/CBaseController.php

https://github.com/joshuaswarren/weatherhub
PHP | 296 lines | 111 code | 16 blank | 169 comment | 8 complexity | 130448f0e801c0e6f3008311d3cddfbd MD5 | raw file
  1. <?php
  2. /**
  3. * CBaseController class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CBaseController is the base class for {@link CController} and {@link CWidget}.
  12. *
  13. * It provides the common functionalities shared by controllers who need to render views.
  14. *
  15. * CBaseController also implements the support for the following features:
  16. * <ul>
  17. * <li>{@link CClipWidget Clips} : a clip is a piece of captured output that can be inserted elsewhere.</li>
  18. * <li>{@link CWidget Widgets} : a widget is a self-contained sub-controller with its own view and model.</li>
  19. * <li>{@link COutputCache Fragment cache} : fragment cache selectively caches a portion of the output.</li>
  20. * </ul>
  21. *
  22. * To use a widget in a view, use the following in the view:
  23. * <pre>
  24. * $this->widget('path.to.widgetClass',array('property1'=>'value1',...));
  25. * </pre>
  26. * or
  27. * <pre>
  28. * $this->beginWidget('path.to.widgetClass',array('property1'=>'value1',...));
  29. * // ... display other contents here
  30. * $this->endWidget();
  31. * </pre>
  32. *
  33. * To create a clip, use the following:
  34. * <pre>
  35. * $this->beginClip('clipID');
  36. * // ... display the clip contents
  37. * $this->endClip();
  38. * </pre>
  39. * Then, in a different view or place, the captured clip can be inserted as:
  40. * <pre>
  41. * echo $this->clips['clipID'];
  42. * </pre>
  43. *
  44. * To use fragment cache, do as follows,
  45. * <pre>
  46. * if($this->beginCache('cacheID',array('property1'=>'value1',...))
  47. * {
  48. * // ... display the content to be cached here
  49. * $this->endCache();
  50. * }
  51. * </pre>
  52. *
  53. * @author Qiang Xue <qiang.xue@gmail.com>
  54. * @version $Id: CBaseController.php 2799 2011-01-01 19:31:13Z qiang.xue $
  55. * @package system.web
  56. * @since 1.0
  57. */
  58. abstract class CBaseController extends CComponent
  59. {
  60. private $_widgetStack=array();
  61. /**
  62. * Returns the view script file according to the specified view name.
  63. * This method must be implemented by child classes.
  64. * @param string $viewName view name
  65. * @return string the file path for the named view. False if the view cannot be found.
  66. */
  67. abstract public function getViewFile($viewName);
  68. /**
  69. * Renders a view file.
  70. *
  71. * @param string $viewFile view file path
  72. * @param array $data data to be extracted and made available to the view
  73. * @param boolean $return whether the rendering result should be returned instead of being echoed
  74. * @return string the rendering result. Null if the rendering result is not required.
  75. * @throws CException if the view file does not exist
  76. */
  77. public function renderFile($viewFile,$data=null,$return=false)
  78. {
  79. $widgetCount=count($this->_widgetStack);
  80. if(($renderer=Yii::app()->getViewRenderer())!==null && $renderer->fileExtension==='.'.CFileHelper::getExtension($viewFile))
  81. $content=$renderer->renderFile($this,$viewFile,$data,$return);
  82. else
  83. $content=$this->renderInternal($viewFile,$data,$return);
  84. if(count($this->_widgetStack)===$widgetCount)
  85. return $content;
  86. else
  87. {
  88. $widget=end($this->_widgetStack);
  89. throw new CException(Yii::t('yii','{controller} contains improperly nested widget tags in its view "{view}". A {widget} widget does not have an endWidget() call.',
  90. array('{controller}'=>get_class($this), '{view}'=>$viewFile, '{widget}'=>get_class($widget))));
  91. }
  92. }
  93. /**
  94. * Renders a view file.
  95. * This method includes the view file as a PHP script
  96. * and captures the display result if required.
  97. * @param string $_viewFile_ view file
  98. * @param array $_data_ data to be extracted and made available to the view file
  99. * @param boolean $_return_ whether the rendering result should be returned as a string
  100. * @return string the rendering result. Null if the rendering result is not required.
  101. */
  102. public function renderInternal($_viewFile_,$_data_=null,$_return_=false)
  103. {
  104. // we use special variable names here to avoid conflict when extracting data
  105. if(is_array($_data_))
  106. extract($_data_,EXTR_PREFIX_SAME,'data');
  107. else
  108. $data=$_data_;
  109. if($_return_)
  110. {
  111. ob_start();
  112. ob_implicit_flush(false);
  113. require($_viewFile_);
  114. return ob_get_clean();
  115. }
  116. else
  117. require($_viewFile_);
  118. }
  119. /**
  120. * Creates a widget and initializes it.
  121. * This method first creates the specified widget instance.
  122. * It then configures the widget's properties with the given initial values.
  123. * At the end it calls {@link CWidget::init} to initialize the widget.
  124. * Starting from version 1.1, if a {@link CWidgetFactory widget factory} is enabled,
  125. * this method will use the factory to create the widget, instead.
  126. * @param string $className class name (can be in path alias format)
  127. * @param array $properties initial property values
  128. * @return CWidget the fully initialized widget instance.
  129. */
  130. public function createWidget($className,$properties=array())
  131. {
  132. $widget=Yii::app()->getWidgetFactory()->createWidget($this,$className,$properties);
  133. $widget->init();
  134. return $widget;
  135. }
  136. /**
  137. * Creates a widget and executes it.
  138. * @param string $className the widget class name or class in dot syntax (e.g. application.widgets.MyWidget)
  139. * @param array $properties list of initial property values for the widget (Property Name => Property Value)
  140. * @param boolean $captureOutput whether to capture the output of the widget. If true, the method will capture
  141. * and return the output generated by the widget. If false, the output will be directly sent for display
  142. * and the widget object will be returned. This parameter is available since version 1.1.2.
  143. * @return mixed the widget instance when $captureOutput is false, or the widget output when $captureOutput is true.
  144. */
  145. public function widget($className,$properties=array(),$captureOutput=false)
  146. {
  147. if($captureOutput)
  148. {
  149. ob_start();
  150. ob_implicit_flush(false);
  151. $widget=$this->createWidget($className,$properties);
  152. $widget->run();
  153. return ob_get_clean();
  154. }
  155. else
  156. {
  157. $widget=$this->createWidget($className,$properties);
  158. $widget->run();
  159. return $widget;
  160. }
  161. }
  162. /**
  163. * Creates a widget and executes it.
  164. * This method is similar to {@link widget()} except that it is expecting
  165. * a {@link endWidget()} call to end the execution.
  166. * @param string $className the widget class name or class in dot syntax (e.g. application.widgets.MyWidget)
  167. * @param array $properties list of initial property values for the widget (Property Name => Property Value)
  168. * @return CWidget the widget created to run
  169. * @see endWidget
  170. */
  171. public function beginWidget($className,$properties=array())
  172. {
  173. $widget=$this->createWidget($className,$properties);
  174. $this->_widgetStack[]=$widget;
  175. return $widget;
  176. }
  177. /**
  178. * Ends the execution of the named widget.
  179. * This method is used together with {@link beginWidget()}.
  180. * @param string $id optional tag identifying the method call for debugging purpose.
  181. * @return CWidget the widget just ended running
  182. * @throws CException if an extra endWidget call is made
  183. * @see beginWidget
  184. */
  185. public function endWidget($id='')
  186. {
  187. if(($widget=array_pop($this->_widgetStack))!==null)
  188. {
  189. $widget->run();
  190. return $widget;
  191. }
  192. else
  193. throw new CException(Yii::t('yii','{controller} has an extra endWidget({id}) call in its view.',
  194. array('{controller}'=>get_class($this),'{id}'=>$id)));
  195. }
  196. /**
  197. * Begins recording a clip.
  198. * This method is a shortcut to beginning {@link CClipWidget}.
  199. * @param string $id the clip ID.
  200. * @param array $properties initial property values for {@link CClipWidget}.
  201. */
  202. public function beginClip($id,$properties=array())
  203. {
  204. $properties['id']=$id;
  205. $this->beginWidget('CClipWidget',$properties);
  206. }
  207. /**
  208. * Ends recording a clip.
  209. * This method is an alias to {@link endWidget}.
  210. */
  211. public function endClip()
  212. {
  213. $this->endWidget('CClipWidget');
  214. }
  215. /**
  216. * Begins fragment caching.
  217. * This method will display cached content if it is availabe.
  218. * If not, it will start caching and would expect a {@link endCache()}
  219. * call to end the cache and save the content into cache.
  220. * A typical usage of fragment caching is as follows,
  221. * <pre>
  222. * if($this->beginCache($id))
  223. * {
  224. * // ...generate content here
  225. * $this->endCache();
  226. * }
  227. * </pre>
  228. * @param string $id a unique ID identifying the fragment to be cached.
  229. * @param array $properties initial property values for {@link COutputCache}.
  230. * @return boolean whether we need to generate content for caching. False if cached version is available.
  231. * @see endCache
  232. */
  233. public function beginCache($id,$properties=array())
  234. {
  235. $properties['id']=$id;
  236. $cache=$this->beginWidget('COutputCache',$properties);
  237. if($cache->getIsContentCached())
  238. {
  239. $this->endCache();
  240. return false;
  241. }
  242. else
  243. return true;
  244. }
  245. /**
  246. * Ends fragment caching.
  247. * This is an alias to {@link endWidget}.
  248. * @see beginCache
  249. */
  250. public function endCache()
  251. {
  252. $this->endWidget('COutputCache');
  253. }
  254. /**
  255. * Begins the rendering of content that is to be decorated by the specified view.
  256. * @param mixed $view the name of the view that will be used to decorate the content. The actual view script
  257. * is resolved via {@link getViewFile}. If this parameter is null (default),
  258. * the default layout will be used as the decorative view.
  259. * Note that if the current controller does not belong to
  260. * any module, the default layout refers to the application's {@link CWebApplication::layout default layout};
  261. * If the controller belongs to a module, the default layout refers to the module's
  262. * {@link CWebModule::layout default layout}.
  263. * @param array $data the variables (name=>value) to be extracted and made available in the decorative view.
  264. * This parameter has been available since version 1.0.4
  265. * @see beginContent
  266. * @see CContentDecorator
  267. */
  268. public function beginContent($view=null,$data=array())
  269. {
  270. $this->beginWidget('CContentDecorator',array('view'=>$view, 'data'=>$data));
  271. }
  272. /**
  273. * Ends the rendering of content.
  274. * @see beginContent
  275. */
  276. public function endContent()
  277. {
  278. $this->endWidget('CContentDecorator');
  279. }
  280. }