SettingsAction   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 9
Bugs 2 Features 4
Metric Value
eloc 40
c 9
b 2
f 4
dl 0
loc 155
rs 10
wmc 15

5 Methods

Rating   Name   Duplication   Size   Complexity  
A saveSettings() 0 7 3
A run() 0 24 4
A prepareModel() 0 10 4
A getSection() 0 7 2
A init() 0 6 2
1
<?php
2
3
namespace yii2mod\settings\actions;
4
5
use Yii;
6
use yii\base\Action;
7
use yii\base\InvalidConfigException;
8
use yii\base\Model;
9
use yii\helpers\ArrayHelper;
10
use yii2mod\settings\events\FormEvent;
11
12
/**
13
 * Class SettingsAction
14
 *
15
 * @package yii2mod\settings\actions
16
 */
17
class SettingsAction extends Action
18
{
19
    /**
20
     * Event is triggered before the settings will be saved.
21
     * Triggered with \yii2mod\settings\events\FormEvent.
22
     */
23
    const EVENT_BEFORE_SAVE = 'beforeSave';
24
25
    /**
26
     * Event is triggered after the settings have been saved successfully.
27
     * Triggered with \yii2mod\settings\events\FormEvent.
28
     */
29
    const EVENT_AFTER_SAVE = 'afterSave';
30
31
    /**
32
     * @var string class name of the model which will be used to validate the attributes
33
     */
34
    public $modelClass;
35
36
    /**
37
     * @var callable a PHP callable that will be called for save the settings.
38
     * If not set, [[saveSettings()]] will be used instead.
39
     * The signature of the callable should be:
40
     *
41
     * ```php
42
     * function ($model) {
43
     *      // $model is the object which will be used to validate the attributes
44
     * }
45
     * ```
46
     */
47
    public $saveSettings;
48
49
    /**
50
     * @var callable a PHP callable that will be called to prepare a model.
51
     * If not set, [[prepareModel()]] will be used instead.
52
     * The signature of the callable should be:
53
     *
54
     * ```php
55
     * function ($model) {
56
     *      // $model is the object which will be used to validate the attributes
57
     * }
58
     * ```
59
     */
60
    public $prepareModel;
61
62
    /**
63
     * @var string
64
     */
65
    public $sectionName;
66
67
    /**
68
     * @var string message to be set on successful save a model
69
     */
70
    public $successMessage = 'Settings have been saved successfully.';
71
72
    /**
73
     * @var string the name of the settings view
74
     */
75
    public $view = 'settings';
76
77
    /**
78
     * @var array additional view params
79
     */
80
    public $viewParams = [];
81
82
    /**
83
     * @inheritdoc
84
     */
85
    public function init()
86
    {
87
        parent::init();
88
89
        if ($this->modelClass === null) {
90
            throw new InvalidConfigException('The "modelClass" property must be set.');
91
        }
92
    }
93
94
    /**
95
     * Renders the settings form.
96
     *
97
     * @return string
98
     */
99
    public function run()
100
    {
101
        /* @var $model Model */
102
        $model = Yii::createObject($this->modelClass);
103
        $event = Yii::createObject(['class' => FormEvent::class, 'form' => $model]);
104
105
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
106
            $this->trigger(self::EVENT_BEFORE_SAVE, $event);
107
108
            $this->saveSettings($model);
109
110
            $this->trigger(self::EVENT_AFTER_SAVE, $event);
111
112
            if ($this->successMessage !== null) {
113
                Yii::$app->session->setFlash('success', $this->successMessage);
0 ignored issues
show
Bug introduced by
The method setFlash() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

113
                Yii::$app->session->/** @scrutinizer ignore-call */ 
114
                                    setFlash('success', $this->successMessage);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114
            }
115
116
            return $this->controller->refresh();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->controller->refresh() also could return the type yii\web\Response which is incompatible with the documented return type string.
Loading history...
117
        }
118
119
        $this->prepareModel($model);
120
121
        return $this->controller->render($this->view, ArrayHelper::merge($this->viewParams, [
122
            'model' => $model,
123
        ]));
124
    }
125
126
    /**
127
     * Prepares the model which will be used to validate the attributes.
128
     *
129
     * @param Model $model
130
     */
131
    protected function prepareModel(Model $model)
132
    {
133
        if (is_callable($this->prepareModel)) {
134
            call_user_func($this->prepareModel, $model);
135
        } else {
136
            foreach ($model->attributes() as $attribute) {
137
                $value = Yii::$app->settings->get($this->getSection($model), $attribute);
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

137
                /** @scrutinizer ignore-call */ 
138
                $value = Yii::$app->settings->get($this->getSection($model), $attribute);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
138
139
                if (!is_null($value)) {
140
                    $model->{$attribute} = $value;
141
                }
142
            }
143
        }
144
    }
145
146
    /**
147
     * @param Model $model
148
     */
149
    protected function saveSettings(Model $model)
150
    {
151
        if (is_callable($this->saveSettings)) {
152
            call_user_func($this->saveSettings, $model);
153
        } else {
154
            foreach ($model->toArray() as $key => $value) {
155
                Yii::$app->settings->set($this->getSection($model), $key, $value);
156
            }
157
        }
158
    }
159
160
    /**
161
     * @param Model $model
162
     *
163
     * @return string
164
     */
165
    protected function getSection(Model $model): string
166
    {
167
        if ($this->sectionName !== null) {
168
            return $this->sectionName;
169
        }
170
171
        return $model->formName();
172
    }
173
}
174