PageRenderTime 43ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/zii/widgets/CBaseListView.php

https://bitbucket.org/NordLabs/yiidoctrine
PHP | 284 lines | 142 code | 20 blank | 122 comment | 17 complexity | 7855c8e3b1ba8b0c268080577b998f7f MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * CBaseListView 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. * CBaseListView is the base class for {@link CListView} and {@link CGridView}.
  12. *
  13. * CBaseListView implements the common features needed by a view wiget for rendering multiple models.
  14. *
  15. * @author Qiang Xue <qiang.xue@gmail.com>
  16. * @version $Id: CBaseListView.php 3101 2011-03-22 17:35:19Z qiang.xue $
  17. * @package zii.widgets
  18. * @since 1.1
  19. */
  20. abstract class CBaseListView extends CWidget
  21. {
  22. /**
  23. * @var IDataProvider the data provider for the view.
  24. */
  25. public $dataProvider;
  26. /**
  27. * @var string the tag name for the view container. Defaults to 'div'.
  28. */
  29. public $tagName='div';
  30. /**
  31. * @var array the HTML options for the view container tag.
  32. */
  33. public $htmlOptions=array();
  34. /**
  35. * @var boolean whether to enable sorting. Note that if the {@link IDataProvider::sort} property
  36. * of {@link dataProvider} is false, this will be treated as false as well. When sorting is enabled,
  37. * sortable columns will have their headers clickable to trigger sorting along that column.
  38. * Defaults to true.
  39. * @see sortableAttributes
  40. */
  41. public $enableSorting=true;
  42. /**
  43. * @var boolean whether to enable pagination. Note that if the {@link IDataProvider::pagination} property
  44. * of {@link dataProvider} is false, this will be treated as false as well. When pagination is enabled,
  45. * a pager will be displayed in the view so that it can trigger pagination of the data display.
  46. * Defaults to true.
  47. */
  48. public $enablePagination=true;
  49. /**
  50. * @var array the configuration for the pager. Defaults to <code>array('class'=>'CLinkPager')</code>.
  51. * @see enablePagination
  52. */
  53. public $pager=array('class'=>'CLinkPager');
  54. /**
  55. * @var string the template to be used to control the layout of various sections in the view.
  56. * These tokens are recognized: {summary}, {items} and {pager}. They will be replaced with the
  57. * summary text, the items, and the pager.
  58. */
  59. public $template="{summary}\n{items}\n{pager}";
  60. /**
  61. * @var string the summary text template for the view. These tokens are recognized and will be replaced
  62. * with the corresponding values:
  63. * <ul>
  64. * <li>{start}: the starting row number (1-based) currently being displayed</li>
  65. * <li>{end}: the ending row number (1-based) currently being displayed</li>
  66. * <li>{count}: the total number of rows</li>
  67. * <li>{page}: the page number (1-based) current being displayed, available since version 1.1.3</li>
  68. * <li>{pages}: the total number of pages, available since version 1.1.3</li>
  69. * </ul>
  70. */
  71. public $summaryText;
  72. /**
  73. * @var string the message to be displayed when {@link dataProvider} does not have any data.
  74. */
  75. public $emptyText;
  76. /**
  77. * @var string the CSS class name for the container of all data item display. Defaults to 'items'.
  78. */
  79. public $itemsCssClass='items';
  80. /**
  81. * @var string the CSS class name for the summary text container. Defaults to 'summary'.
  82. */
  83. public $summaryCssClass='summary';
  84. /**
  85. * @var string the CSS class name for the pager container. Defaults to 'pager'.
  86. */
  87. public $pagerCssClass='pager';
  88. /**
  89. * @var string the CSS class name that will be assigned to the widget container element
  90. * when the widget is updating its content via AJAX. Defaults to 'loading'.
  91. * @since 1.1.1
  92. */
  93. public $loadingCssClass='loading';
  94. /**
  95. * Initializes the view.
  96. * This method will initialize required property values and instantiate {@link columns} objects.
  97. */
  98. public function init()
  99. {
  100. if($this->dataProvider===null)
  101. throw new CException(Yii::t('zii','The "dataProvider" property cannot be empty.'));
  102. $this->dataProvider->getData();
  103. $this->htmlOptions['id']=$this->getId();
  104. if($this->enableSorting && $this->dataProvider->getSort()===false)
  105. $this->enableSorting=false;
  106. if($this->enablePagination && $this->dataProvider->getPagination()===false)
  107. $this->enablePagination=false;
  108. }
  109. /**
  110. * Renders the view.
  111. * This is the main entry of the whole view rendering.
  112. * Child classes should mainly override {@link renderContent} method.
  113. */
  114. public function run()
  115. {
  116. $this->registerClientScript();
  117. echo CHtml::openTag($this->tagName,$this->htmlOptions)."\n";
  118. $this->renderContent();
  119. $this->renderKeys();
  120. echo CHtml::closeTag($this->tagName);
  121. }
  122. /**
  123. * Renders the main content of the view.
  124. * The content is divided into sections, such as summary, items, pager.
  125. * Each section is rendered by a method named as "renderXyz", where "Xyz" is the section name.
  126. * The rendering results will replace the corresponding placeholders in {@link template}.
  127. */
  128. public function renderContent()
  129. {
  130. ob_start();
  131. echo preg_replace_callback("/{(\w+)}/",array($this,'renderSection'),$this->template);
  132. ob_end_flush();
  133. }
  134. /**
  135. * Renders a section.
  136. * This method is invoked by {@link renderContent} for every placeholder found in {@link template}.
  137. * It should return the rendering result that would replace the placeholder.
  138. * @param array $matches the matches, where $matches[0] represents the whole placeholder,
  139. * while $matches[1] contains the name of the matched placeholder.
  140. * @return string the rendering result of the section
  141. */
  142. protected function renderSection($matches)
  143. {
  144. $method='render'.$matches[1];
  145. if(method_exists($this,$method))
  146. {
  147. $this->$method();
  148. $html=ob_get_contents();
  149. ob_clean();
  150. return $html;
  151. }
  152. else
  153. return $matches[0];
  154. }
  155. /**
  156. * Renders the empty message when there is no data.
  157. */
  158. public function renderEmptyText()
  159. {
  160. $emptyText=$this->emptyText===null ? Yii::t('zii','No results found.') : $this->emptyText;
  161. echo CHtml::tag('span', array('class'=>'empty'), $emptyText);
  162. }
  163. /**
  164. * Renders the key values of the data in a hidden tag.
  165. */
  166. public function renderKeys()
  167. {
  168. echo CHtml::openTag('div',array(
  169. 'class'=>'keys',
  170. 'style'=>'display:none',
  171. 'title'=>Yii::app()->getRequest()->getUrl(),
  172. ));
  173. foreach($this->dataProvider->getKeys() as $key)
  174. echo "<span>".CHtml::encode($key)."</span>";
  175. echo "</div>\n";
  176. }
  177. /**
  178. * Renders the summary text.
  179. */
  180. public function renderSummary()
  181. {
  182. if(($count=$this->dataProvider->getItemCount())<=0)
  183. return;
  184. echo '<div class="'.$this->summaryCssClass.'">';
  185. if($this->enablePagination)
  186. {
  187. if(($summaryText=$this->summaryText)===null)
  188. $summaryText=Yii::t('zii','Displaying {start}-{end} of {count} result(s).');
  189. $pagination=$this->dataProvider->getPagination();
  190. $total=$this->dataProvider->getTotalItemCount();
  191. $start=$pagination->currentPage*$pagination->pageSize+1;
  192. $end=$start+$count-1;
  193. if($end>$total)
  194. {
  195. $end=$total;
  196. $start=$end-$count+1;
  197. }
  198. echo strtr($summaryText,array(
  199. '{start}'=>$start,
  200. '{end}'=>$end,
  201. '{count}'=>$total,
  202. '{page}'=>$pagination->currentPage+1,
  203. '{pages}'=>$pagination->pageCount,
  204. ));
  205. }
  206. else
  207. {
  208. if(($summaryText=$this->summaryText)===null)
  209. $summaryText=Yii::t('zii','Total {count} result(s).');
  210. echo strtr($summaryText,array(
  211. '{count}'=>$count,
  212. '{start}'=>1,
  213. '{end}'=>$count,
  214. '{page}'=>1,
  215. '{pages}'=>1,
  216. ));
  217. }
  218. echo '</div>';
  219. }
  220. /**
  221. * Renders the pager.
  222. */
  223. public function renderPager()
  224. {
  225. if(!$this->enablePagination)
  226. return;
  227. $pager=array();
  228. $class='CLinkPager';
  229. if(is_string($this->pager))
  230. $class=$this->pager;
  231. else if(is_array($this->pager))
  232. {
  233. $pager=$this->pager;
  234. if(isset($pager['class']))
  235. {
  236. $class=$pager['class'];
  237. unset($pager['class']);
  238. }
  239. }
  240. $pager['pages']=$this->dataProvider->getPagination();
  241. if($pager['pages']->getPageCount()>1)
  242. {
  243. echo '<div class="'.$this->pagerCssClass.'">';
  244. $this->widget($class,$pager);
  245. echo '</div>';
  246. }
  247. else
  248. $this->widget($class,$pager);
  249. }
  250. /**
  251. * Registers necessary client scripts.
  252. * This method is invoked by {@link run}.
  253. * Child classes may override this method to register customized client scripts.
  254. */
  255. public function registerClientScript()
  256. {
  257. }
  258. /**
  259. * Renders the data items for the view.
  260. * Each item is corresponding to a single data model instance.
  261. * Child classes should override this method to provide the actual item rendering logic.
  262. */
  263. abstract public function renderItems();
  264. }