summaryrefslogtreecommitdiff
path: root/framework/web/CArrayDataProvider.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/web/CArrayDataProvider.php')
-rw-r--r--framework/web/CArrayDataProvider.php162
1 files changed, 162 insertions, 0 deletions
diff --git a/framework/web/CArrayDataProvider.php b/framework/web/CArrayDataProvider.php
new file mode 100644
index 0000000..7641f85
--- /dev/null
+++ b/framework/web/CArrayDataProvider.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * CArrayDataProvider class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CArrayDataProvider implements a data provider based on a raw data array.
+ *
+ * The {@link rawData} property contains all data that may be sorted and/or paginated.
+ * CArrayDataProvider will supply the data after sorting and/or pagination.
+ * You may configure the {@link sort} and {@link pagination} properties to
+ * customize sorting and pagination behaviors.
+ *
+ * Elements in the raw data array may be either objects (e.g. model objects)
+ * or associative arrays (e.g. query results of DAO).
+ *
+ * CArrayDataProvider may be used in the following way:
+ * <pre>
+ * $rawData=Yii::app()->db->createCommand('SELECT * FROM tbl_user')->queryAll();
+ * // or using: $rawData=User::model()->findAll();
+ * $dataProvider=new CArrayDataProvider($rawData, array(
+ * 'id'=>'user',
+ * 'sort'=>array(
+ * 'attributes'=>array(
+ * 'id', 'username', 'email',
+ * ),
+ * ),
+ * 'pagination'=>array(
+ * 'pageSize'=>10,
+ * ),
+ * ));
+ * // $dataProvider->getData() will return a list of arrays.
+ * </pre>
+ *
+ * Note: if you want to use the sorting feature, you must configure {@link sort} property
+ * so that the provider knows which columns can be sorted.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CArrayDataProvider.php 3353 2011-07-12 21:10:36Z alexander.makarow $
+ * @package system.web
+ * @since 1.1.4
+ */
+class CArrayDataProvider extends CDataProvider
+{
+ /**
+ * @var string the name of key field. Defaults to 'id'. If it's set to false,
+ * keys of $rawData array are used.
+ */
+ public $keyField='id';
+ /**
+ * @var array the data that is not paginated or sorted. When pagination is enabled,
+ * this property usually contains more elements than {@link data}.
+ * The array elements must use zero-based integer keys.
+ */
+ public $rawData=array();
+
+ /**
+ * Constructor.
+ * @param array $rawData the data that is not paginated or sorted. The array elements must use zero-based integer keys.
+ * @param array $config configuration (name=>value) to be applied as the initial property values of this class.
+ */
+ public function __construct($rawData,$config=array())
+ {
+ $this->rawData=$rawData;
+ foreach($config as $key=>$value)
+ $this->$key=$value;
+ }
+
+ /**
+ * Fetches the data from the persistent data storage.
+ * @return array list of data items
+ */
+ protected function fetchData()
+ {
+ if(($sort=$this->getSort())!==false && ($order=$sort->getOrderBy())!='')
+ $this->sortData($this->getSortDirections($order));
+
+ if(($pagination=$this->getPagination())!==false)
+ {
+ $pagination->setItemCount($this->getTotalItemCount());
+ return array_slice($this->rawData, $pagination->getOffset(), $pagination->getLimit());
+ }
+ else
+ return $this->rawData;
+ }
+
+ /**
+ * Fetches the data item keys from the persistent data storage.
+ * @return array list of data item keys.
+ */
+ protected function fetchKeys()
+ {
+ if($this->keyField===false)
+ return array_keys($this->rawData);
+ $keys=array();
+ foreach($this->getData() as $i=>$data)
+ $keys[$i]=is_object($data) ? $data->{$this->keyField} : $data[$this->keyField];
+ return $keys;
+ }
+
+ /**
+ * Calculates the total number of data items.
+ * This method simply returns the number of elements in {@link rawData}.
+ * @return integer the total number of data items.
+ */
+ protected function calculateTotalItemCount()
+ {
+ return count($this->rawData);
+ }
+
+ /**
+ * Sorts the raw data according to the specified sorting instructions.
+ * After calling this method, {@link rawData} will be modified.
+ * @param array $directions the sorting directions (field name => whether it is descending sort)
+ */
+ protected function sortData($directions)
+ {
+ if(empty($directions))
+ return;
+ $args=array();
+ $dummy=array();
+ foreach($directions as $name=>$descending)
+ {
+ $column=array();
+ foreach($this->rawData as $index=>$data)
+ $column[$index]=is_object($data) ? $data->$name : $data[$name];
+ $args[]=&$column;
+ $dummy[]=&$column;
+ unset($column);
+ $direction=$descending ? SORT_DESC : SORT_ASC;
+ $args[]=&$direction;
+ $dummy[]=&$direction;
+ unset($direction);
+ }
+ $args[]=&$this->rawData;
+ call_user_func_array('array_multisort', $args);
+ }
+
+ /**
+ * 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;
+ }
+}