<?php

/**
 * ERememberFiltersBehavior class.
 * The ERememberFiltersBehavior extension adds up some functionality to the default
 * possibilites of CActiveRecord/Model implementation.
 *
 * It will detect the search scenario and it will save the filters from the GridView.
 * This comes handy when you need to store them for later use. For heavy navigation and
 * heavy filtering this function can be activated by just a couple of lines.
 *
 * To use this extension, just copy this file to your components/ directory,
 * add 'import' => 'application.components.ERememberFiltersBehavior', [...] to your
 * config/main.php and paste the following code to your behaviors() method of your model
 *
 * public function behaviors() {
 *        return array(
 *            'ERememberFiltersBehavior' => array(
 *                'class' => 'application.components.ERememberFiltersBehavior',
 *                'defaults'=>array(),
 *                'defaultStickOnClear'=>false 
 *            ),
 *        );
 * }
 * 
 * 'defaults' is a key value pair array, that will hold the defaults for your filters. 
 * For example when you initially want to display `active products`, you set to array('status'=>'active'). 
 * You can of course put multiple default values.
 *
 * 'defaultStickOnClear'=>true can be used, if you want the default values to be put back when the user clears the filters
 * The default set is 'false' so if the user clears the filters, also the defaults are cleared out.
 *
 * You can use `scenarios` to remember the filters on multiple states of the same model. This is helpful when you use the same 
 * model on different views and you want to remember the state separated from each other.
 * Known limitations: the views must be in different actions (not on the same view)
 *
 * To set a scenario add the set call after the instantiation
 * Fragment from actionAdmin():
 *
 * $model=new Persons('search');
 * $model->setRememberScenario('scene1');
 *
 *
 * CHANGELOG
 *
 * 2011-06-02
 * v1.2 
 * Added support for 'scenarios'. 
 * You can now tell your model to use custom scenario. 
 *
 * 2011-03-06
 * v1.1 
 * Added support for 'defaults' and 'defaultStickOnClear'. 
 * You can now tell your model to set default filters for your form using this extension.
 *
 * 2011-01-31
 * v1.0 
 * Initial release
 *
 * This extension has also a pair Clear Filters Gridview
 * http://www.yiiframework.com/extension/clear-filters-gridview
 *
 * Please VOTE this extension if helps you at:
 * http://www.yiiframework.com/extension/remember-filters-gridview
 * 
 * @author Marton Kodok http://www.yiiframework.com/forum/index.php?/user/8824-pentium10/
 * @link http://www.yiiframework.com/
 * @version 1.2
 * @package application.components
 */
class ERememberFiltersBehavior extends CActiveRecordBehavior {

	/**
	 * Array that holds any default filter value like array('active'=>'1')
	 *
	 * @var array
	 */
	public $defaults = array();

	/**
	 * When this flag is true, the default values will be used also when the user clears the filters
	 *
	 * @var boolean
	 */
	public $defaultStickOnClear = false;

	/**
	 * Holds a custom stateId key 
	 *
	 * @var string
	 */
	private $_rememberScenario = null;

	private function getStatePrefix() {
		$modelName = get_class($this->owner);
		if($this->_rememberScenario != null) {
			return $modelName . $this->_rememberScenario;
		} else {
			return $modelName;
		}
	}

	public function setRememberScenario($value) {
		$this->_rememberScenario = $value;
		$this->doReadSave();
		//if block added by John M, do this instead of calling EBUttonColumnWithClearFilters::clearFilters
		if(intval(Yii::app()->request->getParam('clearFilters')) == 1) {
			$this->unsetFilters();
			if(isset($_GET['id']))
				Yii::app()->controller->redirect(array(Yii::app()->controller->action->ID, 'id' => Yii::app()->request->getParam('id')));
			else
				Yii::app()->controller->redirect(array(Yii::app()->controller->action->ID));
		}
		return $this->owner;
	}

	public function getRememberScenario() {
		return $this->_rememberScenario;
	}

	private function readSearchValues() {
		$modelName = get_class($this->owner);
		$attributes = $this->owner->getSafeAttributeNames();

		// set any default value
		if(is_array($this->defaults) && (null == Yii::app()->user->getState($modelName . __CLASS__ . 'defaultsSet', null))) {
			foreach($this->defaults as $attribute => $value) {
				if(null == (Yii::app()->user->getState($this->getStatePrefix() . $attribute, null))) {
					Yii::app()->user->setState($this->getStatePrefix() . $attribute, $value);
				}
			}
			Yii::app()->user->setState($modelName . __CLASS__ . 'defaultsSet', 1);
		}

		// set values from session
		foreach($attributes as $attribute) {
			if(null != ($value = Yii::app()->user->getState($this->getStatePrefix() . $attribute, null))) {
				try {
					$this->owner->$attribute = $value;
				} catch (Exception $e) {
					
				}
			}
		}
	}

	private function saveSearchValues() {
		$modelName = get_class($this->owner);
		$attributes = $this->owner->getSafeAttributeNames();
		foreach($attributes as $attribute) {
			if(isset($this->owner->$attribute)) {
			//echo var_export($attributes,true);
			//exit;
			Yii::app()->user->setState($this->getStatePrefix() . $attribute, $this->owner->$attribute);
			}
		}
	}

	private function doReadSave() {
		if($this->owner->scenario == 'search') {
			$this->owner->unsetAttributes();
			if(isset($_GET[get_class($this->owner)])) {
				$this->owner->attributes = $_GET[get_class($this->owner)];
				$this->saveSearchValues();
			} else {
				$this->readSearchValues();
			}
		}
	}

	public function afterConstruct($event) {
		//always start with a unique remember scenario
		//based on the controller/action names, and id if specified
		if (!Yii::app()->params->noSession)
			$this->setRememberScenario(Yii::app()->controller->uniqueid . '/' . Yii::app()->controller->action->id . (isset($_GET['id']) ? '/' . $_GET['id'] : ''));

		//$this->doReadSave(); //original functionality, overidden by John M
	}

	/**
	 * Method is called when we need to unset the filters
	 *
	 * @return owner
	 */
	public function unsetFilters() {
		$modelName = get_class($this->owner);
		$attributes = $this->owner->getSafeAttributeNames();

		foreach ($attributes as $attribute) {
			if (null != ($value = Yii::app()->user->getState($this->getStatePrefix() . $attribute, null))) {
				Yii::app()->user->setState($this->getStatePrefix() . $attribute, 1, 1);
			}
		}
		if ($this->defaultStickOnClear) {
			Yii::app()->user->setState($modelName . __CLASS__ . 'defaultsSet', 1, 1);
		}
		return $this->owner;
	}

}

?>
