1: <?php
2: /**
3: * CDataProvider is a base class that implements the {@link IDataProvider} interface.
4: *
5: * Derived classes mainly need to implement three methods: {@link fetchData},
6: * {@link fetchKeys} and {@link calculateTotalItemCount}.
7: *
8: * @property string $id The unique ID that uniquely identifies the data provider among all data providers.
9: * @property CPagination $pagination The pagination object. If this is false, it means the pagination is disabled.
10: * @property CSort $sort The sorting object. If this is false, it means the sorting is disabled.
11: * @property array $data The list of data items currently available in this data provider.
12: * @property array $keys The list of key values corresponding to {@link data}. Each data item in {@link data}
13: * is uniquely identified by the corresponding key value in this array.
14: * @property integer $itemCount The number of data items in the current page.
15: * @property integer $totalItemCount Total number of possible data items.
16: *
17: * @author Qiang Xue <qiang.xue@gmail.com>
18: * @package system.web
19: * @since 1.1
20: */
21: abstract class CDataProvider extends CComponent implements IDataProvider
22: {
23: private $_id;
24: private $_data;
25: private $_keys;
26: private $_totalItemCount;
27: private $_sort;
28: private $_pagination;
29:
30: /**
31: * Fetches the data from the persistent data storage.
32: * @return array list of data items
33: */
34: abstract protected function fetchData();
35: /**
36: * Fetches the data item keys from the persistent data storage.
37: * @return array list of data item keys.
38: */
39: abstract protected function fetchKeys();
40: /**
41: * Calculates the total number of data items.
42: * @return integer the total number of data items.
43: */
44: abstract protected function calculateTotalItemCount();
45:
46: /**
47: * Returns the ID that uniquely identifies the data provider.
48: * @return string the unique ID that uniquely identifies the data provider among all data providers.
49: */
50: public function getId()
51: {
52: return $this->_id;
53: }
54:
55: /**
56: * Sets the provider ID.
57: * @param string $value the unique ID that uniquely identifies the data provider among all data providers.
58: */
59: public function setId($value)
60: {
61: $this->_id=$value;
62: }
63:
64: /**
65: * Returns the pagination object.
66: * @param string $className the pagination object class name. Parameter is available since version 1.1.13.
67: * @return CPagination|false the pagination object. If this is false, it means the pagination is disabled.
68: */
69: public function getPagination($className='CPagination')
70: {
71: if($this->_pagination===null)
72: {
73: $this->_pagination=new $className;
74: if(($id=$this->getId())!='')
75: $this->_pagination->pageVar=$id.'_page';
76: }
77: return $this->_pagination;
78: }
79:
80: /**
81: * Sets the pagination for this data provider.
82: * @param mixed $value the pagination to be used by this data provider. This could be a {@link CPagination} object
83: * or an array used to configure the pagination object. If this is false, it means the pagination should be disabled.
84: *
85: * You can configure this property same way as a component:
86: * <pre>
87: * array(
88: * 'class' => 'MyPagination',
89: * 'pageSize' => 20,
90: * ),
91: * </pre>
92: */
93: public function setPagination($value)
94: {
95: if(is_array($value))
96: {
97: if(isset($value['class']))
98: {
99: $pagination=$this->getPagination($value['class']);
100: unset($value['class']);
101: }
102: else
103: $pagination=$this->getPagination();
104:
105: foreach($value as $k=>$v)
106: $pagination->$k=$v;
107: }
108: else
109: $this->_pagination=$value;
110: }
111:
112: /**
113: * Returns the sort object.
114: * @param string $className the sorting object class name. Parameter is available since version 1.1.13.
115: * @return CSort|false the sorting object. If this is false, it means the sorting is disabled.
116: */
117: public function getSort($className='CSort')
118: {
119: if($this->_sort===null)
120: {
121: $this->_sort=new $className;
122: if(($id=$this->getId())!='')
123: $this->_sort->sortVar=$id.'_sort';
124: }
125: return $this->_sort;
126: }
127:
128: /**
129: * Sets the sorting for this data provider.
130: * @param mixed $value the sorting to be used by this data provider. This could be a {@link CSort} object
131: * or an array used to configure the sorting object. If this is false, it means the sorting should be disabled.
132: *
133: * You can configure this property same way as a component:
134: * <pre>
135: * array(
136: * 'class' => 'MySort',
137: * 'attributes' => array('name', 'weight'),
138: * ),
139: * </pre>
140: */
141: public function setSort($value)
142: {
143: if(is_array($value))
144: {
145: if(isset($value['class']))
146: {
147: $sort=$this->getSort($value['class']);
148: unset($value['class']);
149: }
150: else
151: $sort=$this->getSort();
152:
153: foreach($value as $k=>$v)
154: $sort->$k=$v;
155: }
156: else
157: $this->_sort=$value;
158: }
159:
160: /**
161: * Returns the data items currently available.
162: * @param boolean $refresh whether the data should be re-fetched from persistent storage.
163: * @return array the list of data items currently available in this data provider.
164: */
165: public function getData($refresh=false)
166: {
167: if($this->_data===null || $refresh)
168: $this->_data=$this->fetchData();
169: return $this->_data;
170: }
171:
172: /**
173: * Sets the data items for this provider.
174: * @param array $value put the data items into this provider.
175: */
176: public function setData($value)
177: {
178: $this->_data=$value;
179: }
180:
181: /**
182: * Returns the key values associated with the data items.
183: * @param boolean $refresh whether the keys should be re-calculated.
184: * @return array the list of key values corresponding to {@link data}. Each data item in {@link data}
185: * is uniquely identified by the corresponding key value in this array.
186: */
187: public function getKeys($refresh=false)
188: {
189: if($this->_keys===null || $refresh)
190: $this->_keys=$this->fetchKeys();
191: return $this->_keys;
192: }
193:
194: /**
195: * Sets the data item keys for this provider.
196: * @param array $value put the data item keys into this provider.
197: */
198: public function setKeys($value)
199: {
200: $this->_keys=$value;
201: }
202:
203: /**
204: * Returns the number of data items in the current page.
205: * This is equivalent to <code>count($provider->getData())</code>.
206: * When {@link pagination} is set false, this returns the same value as {@link totalItemCount}.
207: * @param boolean $refresh whether the number of data items should be re-calculated.
208: * @return integer the number of data items in the current page.
209: */
210: public function getItemCount($refresh=false)
211: {
212: return count($this->getData($refresh));
213: }
214:
215: /**
216: * Returns the total number of data items.
217: * When {@link pagination} is set false, this returns the same value as {@link itemCount}.
218: * @param boolean $refresh whether the total number of data items should be re-calculated.
219: * @return integer total number of possible data items.
220: */
221: public function getTotalItemCount($refresh=false)
222: {
223: if($this->_totalItemCount===null || $refresh)
224: $this->_totalItemCount=$this->calculateTotalItemCount();
225: return $this->_totalItemCount;
226: }
227:
228: /**
229: * Sets the total number of data items.
230: * This method is provided in case when the total number cannot be determined by {@link calculateTotalItemCount}.
231: * @param integer $value the total number of data items.
232: * @since 1.1.1
233: */
234: public function setTotalItemCount($value)
235: {
236: $this->_totalItemCount=$value;
237: }
238: }
239: