1: <?php
2: /**
3: * ERememberFiltersBehavior class.
4: * The ERememberFiltersBehavior extension adds up some functionality to the default
5: * possibilites of CActiveRecord/Model implementation.
6: *
7: * It will detect the search scenario and it will save the filters from the GridView.
8: * This comes handy when you need to store them for later use. For heavy navigation and
9: * heavy filtering this function can be activated by just a couple of lines.
10: *
11: * To use this extension, just copy this file to your components/ directory,
12: * add 'import' => 'application.components.ERememberFiltersBehavior', [...] to your
13: * config/main.php and paste the following code to your behaviors() method of your model
14: *
15: * public function behaviors() {
16: * return array(
17: * 'ERememberFiltersBehavior' => array(
18: * 'class' => 'application.components.ERememberFiltersBehavior',
19: * 'defaults'=>array(),
20: * 'defaultStickOnClear'=>false
21: * ),
22: * );
23: * }
24: *
25: * 'defaults' is a key value pair array, that will hold the defaults for your filters.
26: * For example when you initially want to display `active products`, you set to array('status'=>'active').
27: * You can of course put multiple default values.
28: *
29: * 'defaultStickOnClear'=>true can be used, if you want the default values to be put back when the user clears the filters
30: * The default set is 'false' so if the user clears the filters, also the defaults are cleared out.
31: *
32: * You can use `scenarios` to remember the filters on multiple states of the same model. This is helpful when you use the same
33: * model on different views and you want to remember the state separated from each other.
34: * Known limitations: the views must be in different actions (not on the same view)
35: *
36: * To set a scenario add the set call after the instantiation
37: * Fragment from actionAdmin():
38: *
39: * $model=new Persons('search');
40: * $model->setRememberScenario('scene1');
41: *
42: *
43: * CHANGELOG
44: *
45: * 2011-06-02
46: * v1.2
47: * Added support for 'scenarios'.
48: * You can now tell your model to use custom scenario.
49: *
50: * 2011-03-06
51: * v1.1
52: * Added support for 'defaults' and 'defaultStickOnClear'.
53: * You can now tell your model to set default filters for your form using this extension.
54: *
55: * 2011-01-31
56: * v1.0
57: * Initial release
58: *
59: * This extension has also a pair Clear Filters Gridview
60: * http://www.yiiframework.com/extension/clear-filters-gridview
61: *
62: * Please VOTE this extension if helps you at:
63: * http://www.yiiframework.com/extension/remember-filters-gridview
64: *
65: * @author Marton Kodok http://www.yiiframework.com/forum/index.php?/user/8824-pentium10/
66: * @link http://www.yiiframework.com/
67: * @version 1.2
68: * @package application.components
69: */
70: /* x2modstart */
71: Yii::import ('application.components.X2Settings.X2Settings');
72: Yii::import ('application.components.X2Settings.GridViewDbSettingsBehavior');
73: Yii::import ('application.components.X2Settings.GridViewSessionSettingsBehavior');
74: /* x2modend */
75: class ERememberFiltersBehavior extends CActiveRecordBehavior {
76:
77: /* x2modstart */
78: /**
79: * Feature disabled for simplicity's sake. Property kept around to support legacy code.
80: * @var array
81: */
82: public $defaults = array();
83: /* x2modend */
84:
85: /**
86: * @var $disablePersistentGridSettings
87: */
88: private $_disablePersistentGridSettings;
89:
90: /**
91: * When this flag is true, the default values will be used also when the user clears the filters
92: *
93: * @var boolean
94: */
95: public $defaultStickOnClear = false;
96:
97: public function attach($owner) {
98: parent::attach ($owner);
99: $this->_disablePersistentGridSettings =
100: isset ($this->owner->disablePersistentGridSettings) ?
101: $this->owner->disablePersistentGridSettings : false;
102: $this->attachBehaviors (array (
103: 'settingsBehavior' => array ('class' =>
104: (!isset ($this->owner->dbPersistentGridSettings) ||
105: $this->owner->dbPersistentGridSettings ?
106: 'GridViewDbSettingsBehavior' :
107: 'GridViewSessionSettingsBehavior'),
108: 'uid' => property_exists ($this->owner, 'uid') ? $this->owner->uid : null,
109: 'modelClass' => get_class ($this->owner),
110: )
111: ));
112: }
113:
114: /**
115: * @return array filters set for this model
116: */
117: public function getGridFilters () {
118: if (!$this->_disablePersistentGridSettings) return $this->getSetting ('filters');
119: }
120:
121: /**
122: * Saves grid filters to session/db
123: * @param array $filters attr values indexed by attr name
124: */
125: public function setGridFilters ($filters) {
126: if (!$this->_disablePersistentGridSettings) $this->saveSetting ('filters', $filters);
127: }
128:
129: /**
130: * Set model attributes (if scenario is 'search') and clear filters
131: * (if clearFilters param is set).
132: */
133: public function afterConstruct($event) {
134: if(intval(Yii::app()->request->getParam('clearFilters')) == 1) {
135: $this->unsetAllFilters();
136: if(isset($_GET['id'])) {
137: Yii::app()->controller->redirect(
138: array(
139: Yii::app()->controller->action->ID,
140: 'id' => Yii::app()->request->getParam('id')));
141: } else {
142: Yii::app()->controller->redirect(array(Yii::app()->controller->action->ID));
143: }
144: }
145: $this->doReadSave();
146: }
147:
148: /**
149: * Method is called when we need to unset the filters
150: *
151: * @return owner
152: */
153: public function unsetAllFilters() {
154: $modelName = get_class($this->owner);
155: $attributes = $this->owner->getSafeAttributeNames();
156:
157: $filters = $this->getGridFilters ();
158: if (is_array ($filters)) {
159: foreach($attributes as $attribute) {
160: unset ($filters[$attribute]);
161: }
162: }
163: $this->setGridFilters ($filters);
164: return $this->owner;
165: }
166:
167: public function getId () {
168: if (isset ($this->owner->uid)) return $this->owner->uid;
169: return get_class ($this->owner);
170: }
171:
172: /**
173: * Save models attributes as filters
174: */
175: private function saveSearchValues() {
176: $modelName = get_class($this->owner);
177: $attributes = $this->owner->getSafeAttributeNames();
178: $filters = array ();
179: foreach($attributes as $attribute) {
180: if(isset($this->owner->$attribute)) {
181: $filters[$attribute] = $this->owner->$attribute;
182: }
183: }
184: $this->setGridFilters ($filters);
185: }
186:
187: /**
188: * Set owner attributes either with GET params or saved filters
189: */
190: private function doReadSave() {
191: if($this->owner->scenario === 'search') {
192: $this->owner->unsetAttributes();
193:
194: /* x2tempstart */
195: // violates abstraction by referring to internals of SmartDataProviderBehavior
196: // also doesn't belong here since it has to do with sorting, not filtering
197: //
198: // if sort order is explicitly set to empty string, remove it
199: $sortKey = $this->getId () . '_sort';
200: if (in_array ($sortKey, array_keys ($_GET)) && isset ($_GET[$sortKey]) &&
201: $_GET[$sortKey] === '') {
202:
203: unset ($_GET[$sortKey]);
204: if (!$this->owner->disablePersistentGridSettings) $this->saveSetting ('sort', '');
205: }
206: /* x2tempend */
207:
208: if(isset($_GET[get_class($this->owner)])) {
209: // grid refresh, set attributes with GET params
210:
211: $this->owner->attributes = $_GET[get_class($this->owner)];
212: $this->saveSearchValues();
213: } else { // initial page load, set attributes with saved filters
214: $this->readSearchValues();
215: }
216: }
217: }
218:
219: /**
220: * Set owner attributes with saved filters
221: */
222: private function readSearchValues() {
223: $modelName = get_class($this->owner);
224: $attributes = $this->owner->getSafeAttributeNames();
225:
226: $filters = $this->getGridFilters ();
227: if (is_array ($filters)) {
228: foreach($attributes as $attribute) {
229: if (isset ($filters[$attribute])) {
230: try {
231: $this->owner->$attribute = $filters[$attribute];
232: } catch (Exception $e) {
233: }
234: }
235: }
236: }
237: }
238: }
239: ?>
240: