SearchAction   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 7
dl 0
loc 150
ccs 0
cts 78
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 16 3
A getDefaultRules() 0 13 1
A setSearchModel() 0 4 1
A getSearchModel() 0 12 4
A getDataProvider() 0 17 4
A perform() 0 25 3
A getReturnOptions() 0 4 1
1
<?php
2
/**
3
 * HiPanel core package
4
 *
5
 * @link      https://hipanel.com/
6
 * @package   hipanel-core
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2014-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\actions;
12
13
use hipanel\base\Model;
14
use hipanel\base\SearchModelTrait;
15
use hiqdev\hiart\ActiveDataProvider;
16
use hiqdev\hiart\ResponseErrorException;
17
use Yii;
18
use yii\helpers\ArrayHelper;
19
20
/**
21
 * Class SearchAction.
22
 *
23
 * @var ActiveDataProvider
24
 */
25
class SearchAction extends SwitchAction
26
{
27
    /**
28
     * @var array Options that will be passed to SearchModel by default
29
     */
30
    public $findOptions = [];
31
32
    /**
33
     * @var array Options that will be passed to [[SearchModel::search()]] method as second argument
34
     * and will be stored in [[DataProvider]]
35
     */
36
    public $dataProviderOptions = [];
37
38
    /**
39
     * @var array Options that will be returned. Used only for ajax rendering rules
40
     */
41
    protected $returnOptions = [];
42
43
    /**
44
     * @var Model
45
     */
46
    private $_searchModel;
47
48
    /**
49
     * @var callback Function to collect the response for ajax request/
50
     * @param SwitchAction $action
51
     * @returns array
52
     */
53
    public $ajaxResponseFormatter;
54
55
    /**
56
     * @var ActiveDataProvider stores ActiveDataProvider after creating by [[getDataProvider]]
57
     * @see getDataProvider()
58
     */
59
    public $dataProvider;
60
61
    public function init()
62
    {
63
        if ($this->ajaxResponseFormatter === null) {
64
            $this->ajaxResponseFormatter = function ($action) {
65
                $results = [];
66
67
                foreach ($action->collection->models as $k => $v) {
68
                    $results[$k] = ArrayHelper::toArray($v, $this->returnOptions);
69
                }
70
71
                return $results;
72
            };
73
        }
74
75
        parent::init();
76
    }
77
78
    /** {@inheritdoc} */
79
    protected function getDefaultRules()
80
    {
81
        return [
82
            'ajax' => [
83
                'save' => true,
84
                'flash' => false,
85
                'success' => [
86
                    'class' => RenderJsonAction::class,
87
                    'return' => $this->ajaxResponseFormatter,
88
                ],
89
            ],
90
        ];
91
    }
92
93
    /**
94
     * @param $model
95
     */
96
    public function setSearchModel($model)
97
    {
98
        $this->_searchModel = $model;
99
    }
100
101
    /**
102
     * @return Model|SearchModelTrait
103
     */
104
    public function getSearchModel()
105
    {
106
        if (is_null($this->_searchModel)) {
107
            $this->_searchModel = $this->controller->searchModel();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->controller->searchModel() of type object<hiqdev\hiart\ActiveRecord> or object<hipanel\base\SearchModelTrait> is incompatible with the declared type object<hipanel\base\Model> of property $_searchModel.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
108
        } elseif (is_string($this->_searchModel)) {
109
            $this->_searchModel = Yii::createObject(['class' => $this->_searchModel]);
110
        } elseif (is_array($this->_searchModel)) {
111
            $this->_searchModel = Yii::createObject($this->_searchModel);
112
        }
113
114
        return $this->_searchModel;
115
    }
116
117
    /**
118
     * Creates `ActiveDataProvider` with given options list, stores it to [[dataProvider]].
119
     *
120
     * @return ActiveDataProvider
121
     */
122
    public function getDataProvider()
123
    {
124
        if ($this->dataProvider === null) {
125
            $formName = $this->getSearchModel()->formName();
0 ignored issues
show
Bug introduced by
It seems like formName() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
126
            $search = ArrayHelper::merge($this->findOptions, Yii::$app->request->get($formName) ?: Yii::$app->request->get() ?: Yii::$app->request->post());
127
128
            $modelClass = $this->getModelClass();
129
            $this->returnOptions[$modelClass] = ArrayHelper::merge(
130
                ArrayHelper::remove($search, 'return', []),
131
                ArrayHelper::remove($search, 'rename', [])
132
            );
133
134
            $this->dataProvider = $this->getSearchModel()->search([$formName => $search], $this->dataProviderOptions);
135
        }
136
137
        return $this->dataProvider;
138
    }
139
140
    /** {@inheritdoc} */
141
    public function perform()
142
    {
143
        $this->beforePerform();
144
145
        if (!$this->rule->save) {
146
            return false;
147
        }
148
149
        $models = [];
150
        $error = false;
151
152
        $dataProvider = $this->getDataProvider();
153
        try {
154
            $this->beforeSave();
155
            $models = $dataProvider->getModels();
156
        } catch (ResponseErrorException $e) {
157
            $error = $e->getMessage();
158
        }
159
160
        $this->collection->set($models);
161
162
        $this->afterPerform();
163
164
        return $error;
165
    }
166
167
    /**
168
     * @return array
169
     */
170
    public function getReturnOptions()
171
    {
172
        return $this->returnOptions;
173
    }
174
}
175