CActiveDataProvider.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * CActiveDataProvider 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. * CActiveDataProvider implements a data provider based on ActiveRecord.
  12. *
  13. * CActiveDataProvider provides data in terms of ActiveRecord objects which are
  14. * of class {@link modelClass}. It uses the AR {@link CActiveRecord::findAll} method
  15. * to retrieve the data from database. The {@link criteria} property can be used to
  16. * specify various query options.
  17. *
  18. * CActiveDataProvider may be used in the following way:
  19. * <pre>
  20. * $dataProvider=new CActiveDataProvider('Post', array(
  21. * 'criteria'=>array(
  22. * 'condition'=>'status=1',
  23. * 'order'=>'create_time DESC',
  24. * 'with'=>array('author'),
  25. * ),
  26. * 'countCriteria'=>array(
  27. * 'condition'=>'status=1',
  28. * // 'order' and 'with' clauses have no meaning for the count query
  29. * ),
  30. * 'pagination'=>array(
  31. * 'pageSize'=>20,
  32. * ),
  33. * ));
  34. * // $dataProvider->getData() will return a list of Post objects
  35. * </pre>
  36. *
  37. * @property CDbCriteria $criteria The query criteria.
  38. * @property CDbCriteria $countCriteria The count query criteria. This property is available
  39. * since 1.1.14
  40. * @property CSort $sort The sorting object. If this is false, it means the sorting is disabled.
  41. *
  42. * @author Qiang Xue <qiang.xue@gmail.com>
  43. * @package system.web
  44. * @since 1.1
  45. */
  46. class CActiveDataProvider extends CDataProvider
  47. {
  48. /**
  49. * @var string the primary ActiveRecord class name. The {@link getData()} method
  50. * will return a list of objects of this class.
  51. */
  52. public $modelClass;
  53. /**
  54. * @var CActiveRecord the AR finder instance (eg <code>Post::model()</code>).
  55. * This property can be set by passing the finder instance as the first parameter
  56. * to the constructor. For example, <code>Post::model()->published()</code>.
  57. * @since 1.1.3
  58. */
  59. public $model;
  60. /**
  61. * @var string the name of key attribute for {@link modelClass}. If not set,
  62. * it means the primary key of the corresponding database table will be used.
  63. */
  64. public $keyAttribute;
  65. /**
  66. * @var CDbCriteria
  67. */
  68. private $_criteria;
  69. /**
  70. * @var CDbCriteria
  71. */
  72. private $_countCriteria;
  73. /**
  74. * Constructor.
  75. * @param mixed $modelClass the model class (e.g. 'Post') or the model finder instance
  76. * (e.g. <code>Post::model()</code>, <code>Post::model()->published()</code>).
  77. * @param array $config configuration (name=>value) to be applied as the initial property values of this class.
  78. */
  79. public function __construct($modelClass,$config=array())
  80. {
  81. if(is_string($modelClass))
  82. {
  83. $this->modelClass=$modelClass;
  84. $this->model=$this->getModel($this->modelClass);
  85. }
  86. elseif($modelClass instanceof CActiveRecord)
  87. {
  88. $this->modelClass=get_class($modelClass);
  89. $this->model=$modelClass;
  90. }
  91. $this->setId(CHtml::modelName($this->model));
  92. foreach($config as $key=>$value)
  93. $this->$key=$value;
  94. }
  95. /**
  96. * Returns the query criteria.
  97. * @return CDbCriteria the query criteria
  98. */
  99. public function getCriteria()
  100. {
  101. if($this->_criteria===null)
  102. $this->_criteria=new CDbCriteria;
  103. return $this->_criteria;
  104. }
  105. /**
  106. * Sets the query criteria.
  107. * @param CDbCriteria|array $value the query criteria. This can be either a CDbCriteria object or an array
  108. * representing the query criteria.
  109. */
  110. public function setCriteria($value)
  111. {
  112. $this->_criteria=$value instanceof CDbCriteria ? $value : new CDbCriteria($value);
  113. }
  114. /**
  115. * Returns the count query criteria.
  116. * @return CDbCriteria the count query criteria.
  117. * @since 1.1.14
  118. */
  119. public function getCountCriteria()
  120. {
  121. if($this->_countCriteria===null)
  122. return $this->getCriteria();
  123. return $this->_countCriteria;
  124. }
  125. /**
  126. * Sets the count query criteria.
  127. * @param CDbCriteria|array $value the count query criteria. This can be either a CDbCriteria object
  128. * or an array representing the query criteria.
  129. * @since 1.1.14
  130. */
  131. public function setCountCriteria($value)
  132. {
  133. $this->_countCriteria=$value instanceof CDbCriteria ? $value : new CDbCriteria($value);
  134. }
  135. /**
  136. * Returns the sorting object.
  137. * @param string $className the sorting object class name. Parameter is available since version 1.1.13.
  138. * @return CSort the sorting object. If this is false, it means the sorting is disabled.
  139. */
  140. public function getSort($className='CSort')
  141. {
  142. if(($sort=parent::getSort($className))!==false)
  143. $sort->modelClass=$this->modelClass;
  144. return $sort;
  145. }
  146. /**
  147. * Given active record class name returns new model instance.
  148. *
  149. * @param string $className active record class name.
  150. * @return CActiveRecord active record model instance.
  151. *
  152. * @since 1.1.14
  153. */
  154. protected function getModel($className)
  155. {
  156. return CActiveRecord::model($className);
  157. }
  158. /**
  159. * Fetches the data from the persistent data storage.
  160. * @return array list of data items
  161. */
  162. protected function fetchData()
  163. {
  164. $criteria=clone $this->getCriteria();
  165. if(($pagination=$this->getPagination())!==false)
  166. {
  167. $pagination->setItemCount($this->getTotalItemCount());
  168. $pagination->applyLimit($criteria);
  169. }
  170. $baseCriteria=$this->model->getDbCriteria(false);
  171. if(($sort=$this->getSort())!==false)
  172. {
  173. // set model criteria so that CSort can use its table alias setting
  174. if($baseCriteria!==null)
  175. {
  176. $c=clone $baseCriteria;
  177. $c->mergeWith($criteria);
  178. $this->model->setDbCriteria($c);
  179. }
  180. else
  181. $this->model->setDbCriteria($criteria);
  182. $sort->applyOrder($criteria);
  183. }
  184. $this->model->setDbCriteria($baseCriteria!==null ? clone $baseCriteria : null);
  185. $data=$this->model->findAll($criteria);
  186. $this->model->setDbCriteria($baseCriteria); // restore original criteria
  187. return $data;
  188. }
  189. /**
  190. * Fetches the data item keys from the persistent data storage.
  191. * @return array list of data item keys.
  192. */
  193. protected function fetchKeys()
  194. {
  195. $keys=array();
  196. foreach($this->getData() as $i=>$data)
  197. {
  198. $key=$this->keyAttribute===null ? $data->getPrimaryKey() : $data->{$this->keyAttribute};
  199. $keys[$i]=is_array($key) ? implode(',',$key) : $key;
  200. }
  201. return $keys;
  202. }
  203. /**
  204. * Calculates the total number of data items.
  205. * @return integer the total number of data items.
  206. */
  207. protected function calculateTotalItemCount()
  208. {
  209. $baseCriteria=$this->model->getDbCriteria(false);
  210. if($baseCriteria!==null)
  211. $baseCriteria=clone $baseCriteria;
  212. $count=$this->model->count($this->getCountCriteria());
  213. $this->model->setDbCriteria($baseCriteria);
  214. return $count;
  215. }
  216. }