This repository has been archived by the owner on Nov 21, 2019. It is now read-only.
forked from tyohan/MongoRecord
-
Notifications
You must be signed in to change notification settings - Fork 58
/
EMongoDocumentDataProvider.php
188 lines (171 loc) · 4.88 KB
/
EMongoDocumentDataProvider.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
/**
* EMongoDocumentDataProvider.php
*
* PHP version 5.2+
*
* @author Dariusz Górecki <[email protected]>
* @author Invenzzia Group, open-source division of CleverIT company http://www.invenzzia.org
* @copyright 2011 CleverIT http://www.cleverit.com.pl
* @license http://www.yiiframework.com/license/ BSD license
* @version 1.3
* @category ext
* @package ext.YiiMongoDbSuite
* @since v1.0
*/
/**
* EMongoRecordDataProvider implements a data provider based on EMongoRecord.
*
* EMongoRecordDataProvider provides data in terms of MongoRecord objects which are
* of class {@link modelClass}. It uses the AR {@link CActiveRecord::findAll} method
* to retrieve the data from database. The {@link query} property can be used to
* specify various query options, such as conditions, sorting, pagination, etc.
*
* @author canni
* @since v1.0
*/
class EMongoDocumentDataProvider extends CDataProvider
{
/**
* @var string the name of key field. Defaults to '_id', as a mongo default document primary key.
* @since v1.0
*/
public $keyField;
/**
* @var string the primary ActiveRecord class name. The {@link getData()} method
* will return a list of objects of this class.
* @since v1.0
*/
public $modelClass;
/**
* @var EMongoRecord the AR finder instance (e.g. <code>Post::model()</code>).
* This property can be set by passing the finder instance as the first parameter
* to the constructor.
* @since v1.0
*/
public $model;
private $_criteria;
/**
* Constructor.
* @param mixed $modelClass the model class (e.g. 'Post') or the model finder instance
* (e.g. <code>Post::model()</code>, <code>Post::model()->published()</code>).
* @param array $config configuration (name=>value) to be applied as the initial property values of this class.
* @since v1.0
*/
public function __construct($modelClass, $config = array())
{
if(is_string($modelClass))
{
$this->modelClass = $modelClass;
$this->model = EMongoDocument::model($modelClass);
}
else if($modelClass instanceof EMongoDocument)
{
$this->modelClass = get_class($modelClass);
$this->model = $modelClass;
}
$this->_criteria = $this->model->getDbCriteria();
if(isset($config['criteria']))
{
$this->_criteria->mergeWith($config['criteria']);
unset($config['criteria']);
}
$this->setId($this->modelClass);
foreach($config as $key=>$value)
$this->$key=$value;
if($this->keyField!==null)
{
if(is_array($this->keyField))
throw new CException('This DataProvider cannot handle multi-field primary key!');
}
else
$this->keyField='_id';
}
/**
* Returns the criteria.
* @return array the query criteria
* @since v1.0
*/
public function getCriteria()
{
return $this->_criteria;
}
/**
* Sets the query criteria.
* @param array $value the query criteria. Array representing the MongoDB query criteria.
* @since v1.0
*/
public function setCriteria($criteria)
{
if(is_array($criteria))
$this->_criteria = new EMongoCriteria($criteria);
else if($criteria instanceof EMongoCriteria)
$this->_criteria = $criteria;
}
/**
* Fetches the data from the persistent data storage.
* @return array list of data items
* @since v1.0
*/
protected function fetchData()
{
if(($pagination=$this->getPagination())!==false)
{
$pagination->setItemCount($this->getTotalItemCount());
$this->_criteria->setLimit($pagination->getLimit());
$this->_criteria->setOffset($pagination->getOffset());
}
if(($sort=$this->getSort())!==false && ($order=$sort->getOrderBy())!='')
{
$sort=array();
foreach($this->getSortDirections($order) as $name=>$descending)
{
$sort[$name]=$descending ? EMongoCriteria::SORT_DESC : EMongoCriteria::SORT_ASC;
}
$this->_criteria->setSort($sort);
}
return $this->model->findAll($this->_criteria);
}
/**
* Fetches the data item keys from the persistent data storage.
* @return array list of data item keys.
* @since v1.0
*/
protected function fetchKeys()
{
$keys = array();
foreach($this->getData() as $i=>$data)
{
$keys[$i] = $data->{$this->keyField};
}
return $keys;
}
/**
* Calculates the total number of data items.
* @return integer the total number of data items.
* @since v1.0
*/
public function calculateTotalItemCount()
{
return $this->model->count($this->_criteria);
}
/**
* Converts the "ORDER BY" clause into an array representing the sorting directions.
* @param string $order the "ORDER BY" clause.
* @return array the sorting directions (field name => whether it is descending sort)
* @since v1.0
*/
protected function getSortDirections($order)
{
$segs=explode(',',$order);
$directions=array();
foreach($segs as $seg)
{
if(preg_match('/(.*?)(\s+(desc|asc))?$/i',trim($seg),$matches))
$directions[$matches[1]]=isset($matches[3]) && !strcasecmp($matches[3],'desc');
else
$directions[trim($seg)]=false;
}
return $directions;
}
}