-
Notifications
You must be signed in to change notification settings - Fork 4
/
SaveGridFiltersBehavior.php
152 lines (135 loc) · 4.63 KB
/
SaveGridFiltersBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
namespace marqu3s\behaviors;
use Yii;
use yii\data\ActiveDataProvider;
use yii\db\BaseActiveRecord;
/**
* Saves the Grid's current filters in PHP Session on every request
* and use [[loadWithFilters()]] to get the current filters and assign it
* to the grid.
*
* Usage: On the model that will be used to generate the dataProvider
* that will populate the grid, attach this behavior.
*
* ```
* public function behaviors()
* {
* return [
* 'saveGridFilters' =>[
* 'class' => SaveGridFiltersBehavior::class,
* 'sessionVarName' => self::class . 'GridFilters'
* ]
* ];
* }
* ```
*
* Then, on your search() method, replace $this->load() by $dataProvider = $this->loadWithFilters($params, $dataProvider):
*
* ```
* $dataProvider = new ActiveDataProvider(
* [
* 'query' => $query,
* 'sort' => ...,
* ]
* );
*
* //$this->load($params); // <-- Replace or comment this
* $dataProvider = $this->loadWithFilters($params, $dataProvider); // From SaveGridFiltersBehavior
* ```
*
* You may combine this behavior with [[SaveGridPaginationBehavior]].
*
* That's all!
*
* @author Joao Marques <joao@jjmf.com>
*/
class SaveGridFiltersBehavior extends MarquesBehavior
{
/** @var string the model class name without namespace. Used to detect filter values in $_GET['ModelClassName']. */
public $modelShortClassName;
/** @var bool control to check if filter values changed */
private $filtersChanged = false;
/**
* Define the short class name of the model in use.
*/
public function defineModelShortClassName()
{
$reflect = new \ReflectionClass($this->owner);
$this->modelShortClassName = $reflect->getShortName(); // Class name without namespace
}
/**
* @inheritdoc
*/
public function events()
{
return [
BaseActiveRecord::EVENT_INIT => [$this, 'saveGridFilters'],
];
}
/**
* Saves the grid's current filters.
*/
public function saveGridFilters()
{
$this->defineModelShortClassName();
if (!isset(Yii::$app->session[$this->sessionVarName])) {
Yii::$app->session[$this->sessionVarName] = $this->owner->attributes;
return;
}
$params =
$this->requestMethod === 'GET'
? Yii::$app->request->queryParams
: Yii::$app->request->post();
if (isset($params[$this->modelShortClassName])) {
# Check if the filter values have changed.
$arr1 = $params[$this->modelShortClassName];
$arr2 = Yii::$app->session[$this->sessionVarName];
$this->filtersChanged = $arr1 != $arr2;
Yii::$app->session[$this->sessionVarName] = $params[$this->modelShortClassName];
}
}
/**
* Load filters from $params or from session if no filters set in query string ($_GET).
* If new filter values are detected in $params, the grid pagination is reset to page 1 (index 0).
* Thats why we need the $dataProvider here.
*
* @param array $params
* @param ActiveDataProvider $dataProvider
*
* @return ActiveDataProvider
*/
public function loadWithFilters($params, $dataProvider)
{
$this->defineModelShortClassName();
if (isset($params[$this->modelShortClassName])) {
$this->owner->load($params);
if ($this->filtersChanged) {
$dataProvider->pagination->page = 0; // reset pagination to first page when applying new filters
# Check if owner is using SaveGridPaginationBehavior.
# If it is, reset the current page stored in session by SaveGridPaginationBehavior,
$behaviors = $this->owner->getBehaviors();
foreach ($behaviors as $behavior) {
if (get_class($behavior) == 'marqu3s\behaviors\SaveGridPaginationBehavior') {
$_SESSION[$behavior->sessionVarName] = $dataProvider->pagination->page;
$_GET[$behavior->getVarName] = $dataProvider->pagination->page;
break;
}
}
}
} else {
$this->owner->load([
$this->modelShortClassName => Yii::$app->session[$this->sessionVarName],
]);
}
$dataProvider->refresh(); // refresh the data provider.
return $dataProvider;
}
/**
* Resets the filters stored in session.
*/
public function resetGridFilters()
{
Yii::$app->session[$this->sessionVarName] = null;
$this->filtersChanged = true;
}
}