Completed
Push — master ( de6c4f...fec136 )
by Peter
20:28
created

DataProvider::getModel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL or Commercial license.
5
 *
6
 * @package maslosoft/mangan
7
 * @licence AGPL or Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]>
9
 * @copyright Copyright (c) Maslosoft
10
 * @copyright Copyright (c) Others as mentioned in code
11
 * @link http://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan;
15
16
use CPagination;
17
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
18
use Maslosoft\Mangan\Exceptions\ManganException;
19
use Maslosoft\Mangan\Interfaces\CriteriaInterface;
20
use Maslosoft\Mangan\Interfaces\DataProviderInterface;
21
use Maslosoft\Mangan\Interfaces\FinderInterface;
22
use Maslosoft\Mangan\Interfaces\SortInterface;
23
use Maslosoft\Mangan\Interfaces\WithCriteriaInterface;
24
use Maslosoft\Mangan\Meta\ManganMeta;
25
26
/**
27
 * Mongo document data provider
28
 *
29
 * Implements a data provider based on Document.
30
 *
31
 * DataProvider provides data in terms of Document objects which are
32
 * of class {@link modelClass}. It uses the AR {@link CActiveRecord::findAll} method
33
 * to retrieve the data from database. The {@link query} property can be used to
34
 * specify various query options, such as conditions, sorting, pagination, etc.
35
 *
36
 * @author Ianaré Sévi
37
 * @author Dariusz Górecki <[email protected]>
38
 * @author Invenzzia Group, open-source division of CleverIT company http://www.invenzzia.org
39
 * @copyright 2011 CleverIT http://www.cleverit.com.pl
40
 * @since v1.0
41
 */
42
class DataProvider implements DataProviderInterface
43
{
44
45
	/**
46
	 * @deprecated since version number
47
	 * @var string
48
	 */
49
	public static $CLS = __CLASS__;
50
51
	/**
52
	 * @var string the name of key field. Defaults to '_id', as a mongo default document primary key.
53
	 * @since v1.0
54
	 */
55
	public $keyField;
56
57
	/**
58
	 * @var string the primary ActiveRecord class name. The {@link getData()} method
59
	 * will return a list of objects of this class.
60
	 * @since v1.0
61
	 */
62
	public $modelClass;
63
64
	/**
65
	 * @var Document the AR finder instance (e.g. <code>Post::model()</code>).
66
	 * This property can be set by passing the finder instance as the first parameter
67
	 * to the constructor.
68
	 * @since v1.0
69
	 */
70
	public $model;
71
72
	/**
73
	 * Finder instance
74
	 * @var FinderInterface
75
	 */
76
	private $_finder = null;
77
78
	/**
79
	 * @var CriteriaInterface
80
	 */
81
	private $_criteria;
82
83
	/**
84
	 * @var SortInterface
85
	 */
86
	private $_sort;
87
	private $_data = null;
88
	private $_totalItemCount = null;
89
90
	/**
91
	 * Constructor.
92
	 * @param mixed $modelClass the model class (e.g. 'Post') or the model finder instance
93
	 * (e.g. <code>Post::model()</code>, <code>Post::model()->published()</code>).
94
	 * @param array $config configuration (name=>value) to be applied as the initial property values of this class.
95
	 * @since v1.0
96
	 */
97
	public function __construct($modelClass, $config = [])
98
	{
99
		if (is_string($modelClass))
100
		{
101
			$this->modelClass = $modelClass;
102
			$this->model = new $modelClass;
103
		}
104
		elseif (is_object($modelClass))
105
		{
106
			$this->modelClass = get_class($modelClass);
107
			$this->model = $modelClass;
108
		}
109
		else
110
		{
111
			throw new ManganException('Invalid model type for ' . __CLASS__);
112
		}
113
114
		$this->_finder = Finder::create($this->model);
115
		if ($this->model instanceof WithCriteriaInterface)
116
		{
117
			$this->_criteria = $this->model->getDbCriteria();
118
		}
119
		else
120
		{
121
			$this->_criteria = new Criteria();
122
		}
123
		if (isset($config['criteria']))
124
		{
125
			$this->_criteria->mergeWith($config['criteria']);
126
			unset($config['criteria']);
127
		}
128
129
		if (!$this->_criteria->getSelect())
130
		{
131
			$fields = array_keys(ManganMeta::create($this->model)->fields());
132
			$fields = array_fill_keys($fields, true);
133
			$this->_criteria->setSelect($fields);
134
		}
135
136
		foreach ($config as $key => $value)
137
		{
138
			$this->$key = $value;
139
		}
140
141
		if ($this->keyField !== null)
142
		{
143
			if (is_array($this->keyField))
144
			{
145
				throw new ManganException('This DataProvider cannot handle multi-field primary key.');
146
			}
147
		}
148
		else
149
		{
150
			$this->keyField = '_id';
151
		}
152
	}
153
154
	/**
155
	 * Get model used by this dataprovider
156
	 * @return AnnotatedInterface
157
	 */
158
	public function getModel()
159
	{
160
		return $this->model;
161
	}
162
163
	/**
164
	 * Returns the criteria.
165
	 * @return array the query criteria
166
	 * @since v1.0
167
	 */
168
	public function getCriteria()
169
	{
170
		return $this->_criteria;
171
	}
172
173
	/**
174
	 * Sets the query criteria.
175
	 * @param CriteriaInterface|array $criteria the query criteria. Array representing the MongoDB query criteria.
176
	 * @since v1.0
177
	 */
178
	public function setCriteria($criteria)
179
	{
180
		if (is_array($criteria))
181
		{
182
			$this->_criteria = new Criteria($criteria);
183
		}
184
		elseif ($criteria instanceof CriteriaInterface)
185
		{
186
			$this->_criteria = $criteria;
187
		}
188
	}
189
190
	/**
191
	 * Returns the sort object.
192
	 * @return Sort the sorting object. If this is false, it means the sorting is disabled.
193
	 */
194
	public function getSort()
195
	{
196
		if ($this->_sort === null)
197
		{
198
			$this->_sort = new Sort;
199
			$this->_sort->setModel($this->model);
200
		}
201
		return $this->_sort;
202
	}
203
204
	/**
205
	 * Set sort
206
	 * @param SortInterface $sort
207
	 * @return DataProvider
208
	 */
209
	public function setSort(SortInterface $sort)
210
	{
211
		$this->_sort = $sort;
212
		$this->_sort->setModel($this->model);
213
		return $this;
214
	}
215
216
	/**
217
	 * Returns the pagination object.
218
	 * @param string $className the pagination object class name. Parameter is available since version 1.1.13.
219
	 * @return CPagination|false the pagination object. If this is false, it means the pagination is disabled.
220
	 */
221
	public function getPagination($className = 'CPagination')
222
	{
223
		return false;
224
//		if($this->_pagination===null)
225
//		{
226
//			$this->_pagination=new $className;
227
//			if(($id=$this->getId())!='')
228
//				$this->_pagination->pageVar=$id.'_page';
229
//		}
230
//		return $this->_pagination;
231
	}
232
233
	/**
234
	 * Returns the number of data items in the current page.
235
	 * This is equivalent to <code>count($provider->getData())</code>.
236
	 * When {@link pagination} is set false, this returns the same value as {@link totalItemCount}.
237
	 * @param boolean $refresh whether the number of data items should be re-calculated.
238
	 * @return integer the number of data items in the current page.
239
	 */
240
	public function getItemCount($refresh = false)
241
	{
242
		return count($this->getData($refresh));
243
	}
244
245
	/**
246
	 * Returns the total number of data items.
247
	 * When {@link pagination} is set false, this returns the same value as {@link itemCount}.
248
	 * @return integer total number of possible data items.
249
	 */
250
	public function getTotalItemCount()
251
	{
252
		if ($this->_totalItemCount === null)
253
		{
254
			$this->_totalItemCount = $this->_finder->count($this->_criteria);
255
		}
256
		return $this->_totalItemCount;
257
	}
258
259
	/**
260
	 * Fetches the data from the persistent data storage.
261
	 * @return Document[]|Cursor list of data items
262
	 * @since v1.0
263
	 */
264
	protected function fetchData()
265
	{
266
		if (($pagination = $this->getPagination()) !== false)
267
		{
268
			$pagination->setItemCount($this->getTotalItemCount());
269
270
			$this->_criteria->setLimit($pagination->getLimit());
271
			$this->_criteria->setOffset($pagination->getOffset());
272
		}
273
274
		$sort = $this->getSort();
275
		if ($sort->isSorted())
276
		{
277
			$this->_criteria->setSort($sort);
278
		}
279
280
		return $this->_finder->findAll($this->_criteria);
281
	}
282
283
	/**
284
	 * Returns the data items currently available, ensures that result is at leas empty array
285
	 * @param boolean $refresh whether the data should be re-fetched from persistent storage.
286
	 * @return array the list of data items currently available in this data provider.
287
	 */
288
	public function getData($refresh = false)
289
	{
290
		if ($this->_data === null || $refresh)
291
		{
292
			$this->_data = $this->fetchData();
293
		}
294
		if ($this->_data === null)
295
		{
296
			return [];
297
		}
298
		return $this->_data;
299
	}
300
301
}
302