forked from canni/YiiMongoDbSuite
-
Notifications
You must be signed in to change notification settings - Fork 1
/
EMongoDocumentDataProvider.php
178 lines (161 loc) · 4.69 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
<?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 2010 CleverIT http://www.cleverit.com.pl
* @license http://www.yiiframework.com/license/ BSD license
* @version 1.3
* @category ext
* @package ext.YiiMongoDbSuite
*
*/
/**
* 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
*
*/
class EMongoDocumentDataProvider extends CDataProvider
{
/**
* @var string the name of key field. Defaults to '_id', as a mongo default document primary key.
*/
public $keyField;
/**
* @var string the primary ActiveRecord class name. The {@link getData()} method
* will return a list of objects of this class.
*/
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.
*/
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.
*/
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
*/
public function getCriteria()
{
return $this->_criteria;
}
/**
* Sets the query criteria.
* @param array $value the query criteria. Array representing the MongoDB query criteria.
*/
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
*/
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.
*/
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.
*/
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)
*/
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;
}
}