BaseDataProvider.php 7.55 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\data;

use Yii;
use yii\base\Component;
use yii\base\InvalidParamException;

/**
Qiang Xue committed
15
 * BaseDataProvider provides a base class that implements the [[DataProviderInterface]].
16
 *
17
 * @property integer $count The number of data models in the current page. This property is read-only.
Qiang Xue committed
18 19 20
 * @property array $keys The list of key values corresponding to [[models]]. Each data model in [[models]] is
 * uniquely identified by the corresponding key value in this array.
 * @property array $models The list of data models in the current page.
21 22 23
 * @property Pagination|boolean $pagination The pagination object. If this is false, it means the pagination
 * is disabled. Note that the type of this property differs in getter and setter. See [[getPagination()]] and
 * [[setPagination()]] for details.
24
 * @property Sort|boolean $sort The sorting object. If this is false, it means the sorting is disabled. Note
25
 * that the type of this property differs in getter and setter. See [[getSort()]] and [[setSort()]] for details.
Qiang Xue committed
26
 * @property integer $totalCount Total number of possible data models.
27
 *
28 29 30
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
Qiang Xue committed
31
abstract class BaseDataProvider extends Component implements DataProviderInterface
32
{
Qiang Xue committed
33 34 35 36 37 38 39
	/**
	 * @var string an ID that uniquely identifies the data provider among all data providers.
	 * You should set this property if the same page contains two or more different data providers.
	 * Otherwise, the [[pagination]] and [[sort]] mainly not work properly.
	 */
	public $id;

40 41
	private $_sort;
	private $_pagination;
Qiang Xue committed
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
	private $_keys;
	private $_models;
	private $_totalCount;


	/**
	 * Prepares the data models that will be made available in the current page.
	 * @return array the available data models
	 */
	abstract protected function prepareModels();

	/**
	 * Prepares the keys associated with the currently available data models.
	 * @param array $models the available data models
	 * @return array the keys
	 */
	abstract protected function prepareKeys($models);

	/**
	 * Returns a value indicating the total number of data models in this data provider.
	 * @return integer total number of data models in this data provider.
	 */
	abstract protected function prepareTotalCount();

	/**
	 * Prepares the data models and keys.
	 *
	 * This method will prepare the data models and keys that can be retrieved via
	 * [[getModels()]] and [[getKeys()]].
	 *
	 * This method will be implicitly called by [[getModels()]] and [[getKeys()]] if it has not been called before.
	 *
	 * @param boolean $forcePrepare whether to force data preparation even if it has been done before.
	 */
	public function prepare($forcePrepare = false)
	{
		if ($forcePrepare || $this->_models === null) {
			$this->_models = $this->prepareModels();
		}
		if ($forcePrepare || $this->_keys === null) {
			$this->_keys = $this->prepareKeys($this->_models);
		}
	}

	/**
	 * Returns the data models in the current page.
	 * @return array the list of data models in the current page.
	 */
	public function getModels()
	{
		$this->prepare();
		return $this->_models;
	}

	/**
	 * Sets the data models in the current page.
	 * @param array $models the models in the current page
	 */
	public function setModels($models)
	{
		$this->_models = $models;
	}

	/**
	 * Returns the key values associated with the data models.
	 * @return array the list of key values corresponding to [[models]]. Each data model in [[models]]
	 * is uniquely identified by the corresponding key value in this array.
	 */
	public function getKeys()
	{
		$this->prepare();
		return $this->_keys;
	}

	/**
	 * Sets the key values associated with the data models.
	 * @param array $keys the list of key values corresponding to [[models]].
	 */
	public function setKeys($keys)
	{
		$this->_keys = $keys;
	}

	/**
	 * Returns the number of data models in the current page.
	 * @return integer the number of data models in the current page.
	 */
	public function getCount()
	{
		return count($this->getModels());
	}

	/**
	 * Returns the total number of data models.
	 * When [[pagination]] is false, this returns the same value as [[count]].
	 * Otherwise, it will call [[prepareTotalCount()]] to get the count.
	 * @return integer total number of possible data models.
	 */
	public function getTotalCount()
	{
		if ($this->getPagination() === false) {
			return $this->getCount();
		} elseif ($this->_totalCount === null) {
			$this->_totalCount = $this->prepareTotalCount();
		}
		return $this->_totalCount;
	}

	/**
	 * Sets the total number of data models.
	 * @param integer $value the total number of data models.
	 */
	public function setTotalCount($value)
	{
		$this->_totalCount = $value;
	}
158 159

	/**
160 161 162
	 * Returns the pagination object used by this data provider.
	 * Note that you should call [[prepare()]] or [[getModels()]] first to get correct values
	 * of [[Pagination::totalCount]] and [[Pagination::pageCount]].
163
	 * @return Pagination|boolean the pagination object. If this is false, it means the pagination is disabled.
164 165 166 167
	 */
	public function getPagination()
	{
		if ($this->_pagination === null) {
168
			$this->setPagination([]);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
		}
		return $this->_pagination;
	}

	/**
	 * Sets the pagination for this data provider.
	 * @param array|Pagination|boolean $value the pagination to be used by this data provider.
	 * This can be one of the following:
	 *
	 * - a configuration array for creating the pagination object. The "class" element defaults
	 *   to 'yii\data\Pagination'
	 * - an instance of [[Pagination]] or its subclass
	 * - false, if pagination needs to be disabled.
	 *
	 * @throws InvalidParamException
	 */
	public function setPagination($value)
	{
		if (is_array($value)) {
Alexander Makarov committed
188
			$config = ['class' => Pagination::className()];
Qiang Xue committed
189 190 191 192
			if ($this->id !== null) {
				$config['pageVar'] = $this->id . '-page';
			}
			$this->_pagination = Yii::createObject(array_merge($config, $value));
193 194 195 196 197 198 199 200
		} elseif ($value instanceof Pagination || $value === false) {
			$this->_pagination = $value;
		} else {
			throw new InvalidParamException('Only Pagination instance, configuration array or false is allowed.');
		}
	}

	/**
201
	 * @return Sort|boolean the sorting object. If this is false, it means the sorting is disabled.
202 203 204 205
	 */
	public function getSort()
	{
		if ($this->_sort === null) {
Alexander Makarov committed
206
			$this->setSort([]);
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
		}
		return $this->_sort;
	}

	/**
	 * Sets the sort definition for this data provider.
	 * @param array|Sort|boolean $value the sort definition to be used by this data provider.
	 * This can be one of the following:
	 *
	 * - a configuration array for creating the sort definition object. The "class" element defaults
	 *   to 'yii\data\Sort'
	 * - an instance of [[Sort]] or its subclass
	 * - false, if sorting needs to be disabled.
	 *
	 * @throws InvalidParamException
	 */
	public function setSort($value)
	{
		if (is_array($value)) {
Alexander Makarov committed
226
			$config = ['class' => Sort::className()];
Qiang Xue committed
227 228 229 230
			if ($this->id !== null) {
				$config['sortVar'] = $this->id . '-sort';
			}
			$this->_sort = Yii::createObject(array_merge($config, $value));
231 232 233 234 235 236 237 238
		} elseif ($value instanceof Sort || $value === false) {
			$this->_sort = $value;
		} else {
			throw new InvalidParamException('Only Sort instance, configuration array or false is allowed.');
		}
	}

	/**
Qiang Xue committed
239 240 241
	 * Refreshes the data provider.
	 * After calling this method, if [[getModels()]], [[getKeys()]] or [[getTotalCount()]] is called again,
	 * they will re-execute the query and return the latest data available.
242
	 */
Qiang Xue committed
243
	public function refresh()
244
	{
Qiang Xue committed
245 246 247
		$this->_totalCount = null;
		$this->_models = null;
		$this->_keys = null;
248 249
	}
}