Completed
Push — master ( 3c8880...e2c218 )
by Dmitry
06:42 queued 02:46
created

Action::getFlashText()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 10
ccs 0
cts 7
cp 0
crap 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * HiPanel core package
5
 *
6
 * @link      https://hipanel.com/
7
 * @package   hipanel-core
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2014-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hipanel\actions;
13
14
use Closure;
15
use hipanel\base\Controller;
16
use hiqdev\hiart\Collection;
17
use hiqdev\hiart\ErrorResponseException;
18
use Yii;
19
use yii\base\InvalidCallException;
20
use yii\helpers\ArrayHelper;
21
22
/**
23
 * HiPanel basic action.
24
 * Holds scenario and collection. Displays flash.
25
 *
26
 * @property Collection collection
27
 */
28
class Action extends \yii\base\Action
29
{
30
    const EVENT_BEFORE_SAVE = 'beforeSave';
31
    const EVENT_BEFORE_LOAD = 'beforeLoad';
32
    const EVENT_BEFORE_PERFORM = 'beforePerform';
33
    const EVENT_AFTER_PERFORM = 'afterPerform';
34
35
    /**
36
     * @var Controller the controller that owns this action
37
     */
38
    public $controller;
39
40
    /**
41
     * @var Action|SwitchAction parent called action
42
     */
43
    public $parent;
44
45
    /**
46
     * @var string scenario to be used when save
47
     */
48
    public $_scenario;
49
50
    /**
51
     * @var array|Closure additional data passed when rendering
52
     */
53
    public $data = [];
54
55
    /**
56
     * @param string $scenario
57
     */
58
    public function setScenario($scenario)
59
    {
60
        $this->_scenario = $scenario;
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    public function getScenario()
67
    {
68
        return $this->_scenario ?: ($this->parent ? $this->parent->getScenario() : $this->id);
69
    }
70
71
    /**
72
     * @var Collection|array the options that will be used to create the collection.
73
     * Stores collection after creating
74
     */
75
    protected $_collection;
76
77
    /**
78
     * Setter for the collection.
79
     *
80
     * @param array $collection config for the collection
81
     */
82
    public function setCollection($collection)
83
    {
84
        $this->_collection = $collection;
85
    }
86
87
    /**
88
     * Gets the instance of the collection.
89
     *
90
     * @return Collection
91
     */
92
    public function getCollection()
93
    {
94
        if ($this->parent) {
95
            return $this->parent->getCollection();
96
        }
97
98
        if (!is_object($this->_collection)) {
99
            $action = $this->controller->action;
100
            if ($action instanceof self) {
101
                $scenario = $action->getScenario();
102
            } else {
103
                $scenario = $action->id;
104
            }
105
106
            $this->_collection = Yii::createObject(ArrayHelper::merge([
107
                'class' => Collection::className(),
108
                'model' => $this->controller->newModel(),
109
                'scenario' => $scenario,
110
            ], (array) $this->_collection));
111
        }
112
113
        return $this->_collection;
114
    }
115
116
    /**
117
     * @var callable the custom callback to load data into the collection. Gets [[$this]] as the only argument
118
     * Should call `$this->collection->load()`
119
     */
120
    public $collectionLoader;
121
122
    public function beforeLoad()
123
    {
124
        if (isset($this->parent)) {
125
            $this->parent->trigger(static::EVENT_BEFORE_LOAD);
126
        }
127
128
        $this->trigger(static::EVENT_BEFORE_LOAD);
129
    }
130
131
    /**
132
     * Loads data to the [[collection]].
133
     *
134
     * @param array $data
135
     */
136
    public function loadCollection($data = null)
137
    {
138
        $this->beforeLoad();
139
140
        if ($this->collectionLoader instanceof Closure) {
141
            call_user_func($this->collectionLoader, $this, $data);
142
        } else {
143
            $this->collection->load($data);
144
        }
145
    }
146
147
    public function beforeSave()
148
    {
149
        if (isset($this->parent)) {
150
            $this->parent->trigger(static::EVENT_BEFORE_SAVE);
151
        }
152
153
        $this->trigger(static::EVENT_BEFORE_SAVE);
154
    }
155
156
    /**
157
     * Saves stored [[collection]].
158
     *
159
     * @return bool
160
     */
161
    public function saveCollection()
162
    {
163
        $this->beforeSave();
164
        return $this->collection->save();
165
    }
166
167
    public function beforePerform()
168
    {
169
        if (isset($this->parent)) {
170
            $this->parent->trigger(static::EVENT_BEFORE_PERFORM);
171
        }
172
173
        $this->trigger(static::EVENT_BEFORE_PERFORM);
174
    }
175
176
    public function afterPerform()
177
    {
178
        if (isset($this->parent)) {
179
            $this->parent->trigger(static::EVENT_AFTER_PERFORM);
180
        }
181
182
        $this->trigger(static::EVENT_AFTER_PERFORM);
183
    }
184
185
    /**
186
     * Performs action.
187
     *
188
     * @return boolean|string Whether save is success
189
     *  - boolean true or sting - an error
190
     *  - false - no errors
191
     */
192
    public function perform()
193
    {
194
        $this->beforePerform();
195
196
        $this->loadCollection();
197
198
        try {
199
            $error = !$this->saveCollection();
200
201
            if ($error === true && $this->collection->hasErrors()) {
202
                $error = $this->collection->getFirstError();
203
            }
204
        } catch (ErrorResponseException $e) {
205
            $error = $e->getMessage();
206
        } catch (InvalidCallException $e) {
207
            $error = $e->getMessage();
208
        }
209
210
        $this->afterPerform();
211
        return $error;
212
    }
213
214
    /**
215
     * @return \hiqdev\hiart\ActiveRecord
216
     */
217
    public function getModel()
218
    {
219
        return $this->parent ? $this->parent->getModel() : $this->getCollection()->first;
220
    }
221
222
    /**
223
     * Return the model class name
224
     *
225
     * @return string
226
     */
227
    public function getModelClass()
228
    {
229
        if (isset($this->parent)) {
230
            return $this->parent->getModelClass();
231
        }
232
233
        if (isset($this->getCollection()->first)) {
234
            return $this->getCollection()->first->className();
235
        }
236
237
        return $this->getCollection()->getModel()->className();
238
    }
239
240
    /**
241
     * @return \hiqdev\hiart\ActiveRecord[]
242
     */
243
    public function getModels()
244
    {
245
        return $this->parent ? $this->parent->getModels() : $this->getCollection()->models;
246
    }
247
248
    /**
249
     * Prepares additional data for render.
250
     *
251
     * @param $data array Additional data, prepared by other classes. Optional.
252
     * @return array
253
     */
254
    public function prepareData($data = [])
255
    {
256
        return (array) ($this->data instanceof Closure ? call_user_func($this->data, $this, $data) : $this->data);
257
    }
258
259
    /**
260
     * {@inheritdoc}
261
     */
262
    public function getUniqueId()
263
    {
264
        return $this->parent !== null ? $this->parent->getUniqueId() : $this->controller->getUniqueId() . '/' . $this->id;
265
    }
266
267
    /**
268
     * Returns text for flash messages, search in parent actions.
269
     * Used by [[addFlash()]].
270
     *
271
     * @param $type string
272
     * @return string
273
     */
274
    public function getFlashText($type)
275
    {
276
        if ($this->{$type}) {
277
            return $this->{$type};
278
        } elseif ($this->parent) {
279
            return $this->parent->getFlashText($type);
280
        }
281
282
        return $type;
283
    }
284
285
    /**
286
     * Adds flash message.
287
     *
288
     * @param string $type the type of flash
289
     * @param string $error the text of error
290
     */
291
    public function addFlash($type, $error = null)
292
    {
293
        if ($type === 'error' && is_string($error) && !empty($error)) {
294
            $text = Yii::t('app', $error);
295
        } else {
296
            $text = $this->getFlashText($type);
297
        }
298
299
        if ($type instanceof \Closure) {
300
            $text = call_user_func($text, $text, $this);
301
        }
302
303
        Yii::$app->session->addFlash($type, [
304
            'text' => $text,
305
        ]);
306
    }
307
}
308