<?php

/**
 * CActiveDataProvider 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/
 */

/**
 * CActiveDataProvider implements a data provider based on ActiveRecord.
 *
 * CActiveDataProvider provides data in terms of ActiveRecord objects which are
 * of class {@link modelClass}. It uses the AR {@link PhonalisaRecord::findAll} method
 * to retrieve the data from database. The {@link criteria} property can be used to
 * specify various query options.
 *
 * CActiveDataProvider may be used in the following way:
 * <pre>
 * $dataProvider=new CActiveDataProvider('Post', array(
 *     'criteria'=>array(
 *         'condition'=>'status=1',
 *         'order'=>'create_time DESC',
 *         'with'=>array('author'),
 *     ),
 *     'pagination'=>array(
 *         'pageSize'=>20,
 *     ),
 * ));
 * // $dataProvider->getData() will return a list of Post objects
 * </pre>
 *
 * @property CDbCriteria $criteria The query criteria.
 * @property CSort $sort The sorting object. If this is false, it means the sorting is disabled.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @version $Id: CActiveDataProvider.php 3426 2011-10-25 00:01:09Z alexander.makarow $
 * @package system.web
 * @since 1.1
 */
class CPhonalisaDataProvider extends CDataProvider
{

    /**
     * @var string the primary ActiveRecord class name. The {@link getData()} method
     * will return a list of objects of this class.
     */
    public $modelClass;

    /**
     * @var CPhonalisaRecord the AR finder instance (eg <code>Post::model()</code>).
     * This property can be set by passing the finder instance as the first parameter
     * to the constructor. For example, <code>Post::model()->published()</code>.
     * @since 1.1.3
     */
    public $model;

    /**
     * @var string the name of key attribute for {@link modelClass}. If not set,
     * it means the primary key of the corresponding database table will be used.
     */
    public $keyAttribute;
    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 = PhonalisaRecord::model($this->modelClass);
        } else if ($modelClass instanceof PhonalisaRecord) {
            $this->modelClass = get_class($modelClass);
            $this->model = $modelClass;
        }
        $this->setId($this->modelClass);

        foreach ($config as $key => $value) {
            $this->$key = $value;
        }
    }

    /**
     * Returns the query criteria.
     * @return CDbCriteria the query criteria
     */
    public function getCriteria()
    {
        if ($this->_criteria === null)
            $this->_criteria = new CDbCriteria;
        return $this->_criteria;
    }

    /**
     * Sets the query criteria.
     * @param mixed $value the query criteria. This can be either a CDbCriteria object or an array
     * representing the query criteria.
     */
    public function setCriteria($value)
    {
        $this->_criteria = $value instanceof CDbCriteria ? $value : new CDbCriteria($value);
    }

    /**
     * Returns the sorting object.
     * @return CSort the sorting object. If this is false, it means the sorting is disabled.
     */
    public function getSort()
    {
        $sort = new CPhonalisaSort($this->modelClass); //FIXME: Save this stuff to our _s var inhertied from CDataProvider?
        return $sort;
    }

    /**
     * Fetches the data from the persistent data storage.
     * @return array list of data items
     */
    protected function fetchData()
    {
        $criteria = clone $this->getCriteria();

        if (($pagination = $this->getPagination()) !== false) {
            $pagination->setItemCount($this->getTotalItemCount());
            $pagination->applyLimit($criteria);
        }

        $baseCriteria = $this->model->getDbCriteria(false);

        if (($sort = $this->getSort()) !== false) {
            // set model criteria so that CSort can use its table alias setting
            if ($baseCriteria !== null) {
                $c = clone $baseCriteria;
                $c->mergeWith($criteria);
                $this->model->setDbCriteria($c);
            } else {
                $this->model->setDbCriteria($criteria);
            }
            $sort->applyOrder($criteria);
        }
        $this->model->setDbCriteria($baseCriteria !== null ? clone $baseCriteria : null);

        $attributes = array();
        if (@$criteria->condition != "") {
            $conditions = explode(" AND ", $criteria->condition);
            foreach ($conditions as $condition) {
                 if (!empty($condition)) {
                    $keyAndValue = explode("=", $condition);
                    $attributes[trim($keyAndValue[0])] = trim($keyAndValue[1]);
                }
            }
        }

        if (count($attributes) == 0) {
            //TEST FIXME ! 
            if ($criteria->order != null || $criteria->order != '') {
                $data = $this->model->find($attributes, $criteria->order, $criteria->limit, $criteria->offset);
            } else {
                $data = $this->model->findAll(array(), array('limit' => $criteria->limit, 'offset' => $criteria->offset));
            }
            //TEST end !
            ///  add here : 
            ///     $data=$this->model->findAll(array(),array('limit'=>$criteria->limit,'offset'=>$criteria->offset));
            ///  to reset this function on the time before the test.
        } else {
            $data = $this->model->find($attributes, $criteria->order, $criteria->limit, $criteria->offset);
        }
        $this->model->setDbCriteria($baseCriteria);  // restore original criteria

        return $data;
    }

    /**
     * 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) {
            $key = $this->keyAttribute === null ? $data->getPrimaryKey() : $data->{$this->keyAttribute};
            $keys[$i] = is_array($key) ? implode(',', $key) : $key;
        }
        return $keys;
    }

    /**
     * Calculates the total number of data items.
     * @return integer the total number of data items.
     */
    protected function calculateTotalItemCount()
    {
        $baseCriteria = $this->model->getDbCriteria(false);
        if ($baseCriteria !== null)
            $baseCriteria = clone $baseCriteria;
        $count = $this->model->count($this->getCriteria());
        $this->model->setDbCriteria($baseCriteria);
        return $count;
    }
}
