EMongoDataProvider.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. /**
  3. * EMongoDataProvider
  4. *
  5. * A data Provider helper for interacting with the EMongoCursor
  6. */
  7. class EMongoDataProvider extends CActiveDataProvider
  8. {
  9. /**
  10. * The primary ActiveRecord class name. The {@link getData()} method
  11. * will return a list of objects of this class.
  12. * @var string
  13. */
  14. public $modelClass;
  15. /**
  16. * The AR finder instance (eg <code>Post::model()</code>).
  17. * This property can be set by passing the finder instance as the first parameter
  18. * to the constructor. For example, <code>Post::model()->published()</code>.
  19. * @var EMongoModel
  20. */
  21. public $model;
  22. /**
  23. * The name of key attribute for {@link modelClass}. If not set,
  24. * it means the primary key of the corresponding database table will be used.
  25. * @var string
  26. */
  27. public $keyAttribute = '_id';
  28. /**
  29. * @var array The criteria array
  30. */
  31. private $_criteria;
  32. /**
  33. * The internal MongoDB cursor as a MongoCursor instance
  34. * @var EMongoCursor|MongoCursor
  35. */
  36. private $_cursor;
  37. /**
  38. * @var EMongoSort
  39. */
  40. private $_sort;
  41. /**
  42. * Creates the EMongoDataProvider instance
  43. * @param string|EMongoDocument $modelClass
  44. * @param array $config
  45. */
  46. public function __construct($modelClass, $config = array())
  47. {
  48. if(is_string($modelClass)){
  49. $this->modelClass = $modelClass;
  50. $this->model = EMongoDocument::model($this->modelClass);
  51. }elseif($modelClass instanceof EMongoDocument){
  52. $this->modelClass = get_class($modelClass);
  53. $this->model = $modelClass;
  54. }
  55. $this->setId($this->modelClass);
  56. foreach($config as $key => $value){
  57. $this->$key = $value;
  58. }
  59. }
  60. /**
  61. * @see CActiveDataProvider::getCriteria()
  62. * @return array
  63. */
  64. public function getCriteria()
  65. {
  66. return $this->_criteria;
  67. }
  68. /**
  69. * @see CActiveDataProvider::setCriteria()
  70. * @param array|EMongoCriteria $value
  71. */
  72. public function setCriteria($value)
  73. {
  74. if($value instanceof EMongoCriteria){
  75. $this->_criteria = $value->toArray();
  76. }
  77. if(is_array($value)){
  78. $this->_criteria = $value;
  79. }
  80. }
  81. /**
  82. * @see CActiveDataProvider::fetchData()
  83. * @return array
  84. */
  85. public function fetchData()
  86. {
  87. $criteria = $this->getCriteria();
  88. // I have not refactored this line considering that the condition may have changed from total item count to here, maybe.
  89. $this->_cursor = $this->model->find(
  90. isset($criteria['condition']) && is_array($criteria['condition']) ? $criteria['condition'] : array(),
  91. isset($criteria['project']) && !empty($criteria['project']) ? $criteria['project'] : array()
  92. );
  93. // If we have sort and limit and skip setup within the incoming criteria let's set it
  94. if(isset($criteria['sort']) && is_array($criteria['sort'])){
  95. $this->_cursor->sort($criteria['sort']);
  96. }
  97. if(isset($criteria['skip']) && is_int($criteria['skip'])){
  98. $this->_cursor->skip($criteria['skip']);
  99. }
  100. if(isset($criteria['limit']) && is_int($criteria['limit'])){
  101. $this->_cursor->limit($criteria['limit']);
  102. }
  103. if(isset($criteria['hint']) && (is_array($criteria['hint']) || is_string($criteria['hint']))){
  104. $this->_cursor->hint($criteria['hint']);
  105. }
  106. if(($pagination = $this->getPagination()) !== false){
  107. $pagination->setItemCount($this->getTotalItemCount());
  108. $this->_cursor->limit($pagination->getLimit());
  109. $this->_cursor->skip($pagination->getOffset());
  110. }
  111. if(($sort = $this->getSort()) !== false){
  112. $sort = $sort->getOrderBy();
  113. if(count($sort) > 0){
  114. $this->_cursor->sort($sort);
  115. }
  116. }
  117. return iterator_to_array($this->_cursor, false);
  118. }
  119. /**
  120. * @see CActiveDataProvider::fetchKeys()
  121. * @return array
  122. */
  123. public function fetchKeys()
  124. {
  125. $keys = array();
  126. foreach($this->getData() as $i => $data){
  127. $key = $this->keyAttribute === null ? $data->{$data->primaryKey()} : $data->{$this->keyAttribute};
  128. $keys[$i] = is_array($key) ? implode(',', $key) : $key;
  129. }
  130. return $keys;
  131. }
  132. /**
  133. * @see CActiveDataProvider::calculateTotalItemCount()
  134. * @return int
  135. */
  136. public function calculateTotalItemCount()
  137. {
  138. if(!$this->_cursor){
  139. $criteria = $this->getCriteria();
  140. $this->_cursor = $this->model->find(isset($criteria['condition']) && is_array($criteria['condition']) ? $criteria['condition'] : array());
  141. }
  142. return $this->_cursor->count();
  143. }
  144. public function setSort($value)
  145. {
  146. if(is_array($value))
  147. {
  148. if(isset($value['class']))
  149. {
  150. $sort=$this->getSort($value['class']);
  151. unset($value['class']);
  152. }
  153. else
  154. $sort=$this->getSort();
  155. foreach($value as $k=>$v)
  156. $sort->$k=$v;
  157. }
  158. else
  159. $this->_sort=$value;
  160. }
  161. /**
  162. * Returns the sort object. We don't use the newer getSort function because it does not have the same functionality
  163. * between 1.1.10 and 1.1.13, the functionality we need is actually in 1.1.13 only
  164. * @param string $className
  165. * @return CSort|EMongoSort|false - the sorting object. If this is false, it means the sorting is disabled.
  166. */
  167. public function getSort($className = 'EMongoSort')
  168. {
  169. if($this->_sort === null){
  170. $this->_sort = new $className;
  171. if(($id = $this->getId()) != ''){
  172. $this->_sort->sortVar = $id . '_sort';
  173. }
  174. $this->_sort->modelClass = $this->modelClass;
  175. }
  176. return $this->_sort;
  177. }
  178. }