Repository navigation
Expand file tree
/
Copy pathSortableGridBehavior.php
More file actions
98 lines (85 loc) · 2.84 KB
/
Copy pathSortableGridBehavior.php
File metadata and controls
98 lines (85 loc) · 2.84 KB
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
<?php
/**
* @link https://github.com/himiklab/yii2-sortable-grid-view-widget
* @copyright Copyright (c) 2014-2017 HimikLab
* @license http://opensource.org/licenses/MIT MIT
*/
namespace himiklab\sortablegrid;
use yii\base\Behavior;
use yii\base\InvalidConfigException;
use yii\db\ActiveRecord;
/**
* Behavior for sortable Yii2 GridView widget.
*
* For example:
*
* ```php
* public function behaviors()
* {
* return [
* 'sort' => [
* 'class' => SortableGridBehavior::className(),
* 'sortableAttribute' => 'sortOrder',
* 'scope' => function ($query) {
* $query->andWhere(['group_id' => $this->group_id]);
* },
* ],
* ];
* }
* ```
*
* @author HimikLab
* @package himiklab\sortablegrid
*/
class SortableGridBehavior extends Behavior
{
/** @var string database field name for row sorting */
public $sortableAttribute = 'sortOrder';
/** @var callable */
public $scope;
/** @var callable */
public $afterGridSort;
public function events()
{
return [ActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert'];
}
public function gridSort($items)
{
/** @var ActiveRecord $model */
$model = $this->owner;
if (!$model->hasAttribute($this->sortableAttribute)) {
throw new InvalidConfigException("Model does not have sortable attribute `{$this->sortableAttribute}`.");
}
$newOrder = [];
$models = [];
foreach ($items as $old => $new) {
$models[$new] = $model::findOne($new);
$newOrder[$old] = $models[$new]->{$this->sortableAttribute} ? $models[$new]->{$this->sortableAttribute} : $new;
}
$model::getDb()->transaction(function () use ($models, $newOrder) {
foreach ($newOrder as $modelId => $orderValue) {
/** @var ActiveRecord[] $models */
$models[$modelId]->updateAttributes([$this->sortableAttribute => $orderValue]);
}
});
if (is_callable($this->afterGridSort)) {
call_user_func($this->afterGridSort, $model);
}
}
public function beforeInsert()
{
/** @var ActiveRecord $model */
$model = $this->owner;
if (!$model->hasAttribute($this->sortableAttribute)) {
throw new InvalidConfigException("Invalid sortable attribute `{$this->sortableAttribute}`.");
}
$query = $model::find();
if (is_callable($this->scope)) {
call_user_func($this->scope, $query);
}
/* Override model alias if defined in the model's class */
$query->from([$model::tableName() => $model::tableName()]);
$maxOrder = $query->max('{{' . trim($model::tableName(), '{}') . '}}.[[' . $this->sortableAttribute . ']]');
$model->{$this->sortableAttribute} = $maxOrder + 1;
}
}