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

BlockModalButton   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 242
ccs 0
cts 124
cp 0
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 8

6 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 5 1
A modalEnd() 0 4 1
A run() 0 6 1
F initOptions() 0 76 11
A modalBegin() 0 21 1
B renderBody() 0 26 4
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\widgets;
13
14
use hipanel\base\Model;
15
use hipanel\helpers\ArrayHelper;
16
use hipanel\helpers\FontIcon;
17
use Yii;
18
use yii\base\Event;
19
use yii\base\Widget;
20
use yii\bootstrap\Modal;
21
use yii\helpers\Html;
22
use yii\helpers\Url;
23
24
/**
25
 * Class BlockModalButton
26
 * Used for special render of object blocking modal window with activating button.
27
 */
28
class BlockModalButton extends Widget
29
{
30
    const ACTION_ENABLE = 'enable';
31
    const ACTION_DISABLE = 'disable';
32
33
    const SCENARIO_ENABLE = 'enable-block';
34
    const SCENARIO_DISABLE = 'disable-block';
35
36
    const EVENT_BEFORE_BODY = 'beforeBody';
37
    const EVENT_AFTER_BODY = 'afterBody';
38
39
    /**
40
     * @var integer ID of action
41
     *
42
     * @see ACTION_DISABLE
43
     * @SEE ACTION_ENABLE
44
     */
45
    public $action;
46
47
    /**
48
     * @var Model
49
     */
50
    public $model;
51
52
    /**
53
     * @var string
54
     */
55
    public $scenario;
56
57
    /**
58
     * @var array|Modal stores the overriding options for [[ModalButton]].
59
     * After Modal creating, stores the object.
60
     */
61
    public $modal = [];
62
63
    /**
64
     * @var string the validation URL, will be passed to [[ModalButton::form]]
65
     * Default: `validate-form?scenario={$this->scenario}`
66
     */
67
    public $validationUrl;
68
69
    /**
70
     * @var array block reasons. Should be a key-value array, will be passed to [[Html::dropDown]]
71
     * Default: `Yii::$app->controller->getBlockReasons()`
72
     */
73
    public $blockReasons;
74
75
    /**
76
     * @var array Options for trigger button. Will be passed to [[ModalButton::button]]
77
     */
78
    public $button = [];
79
80
    /**
81
     * @var array Options to render the header of modal.
82
     * Keys with special behaviour:
83
     *  - tag - html tag, used to wrap the header label (default: h4)
84
     *  - label - the value of tag
85
     *
86
     * All other options will be passed as third argument options to [[Html::tag]]
87
     */
88
    public $header = [];
89
90
    /**
91
     * @var array Options to render the warning message inside of the modal.
92
     * Keys with special behaviour:
93
     *  - tag - html tag, used to wrap the label (default: h4)
94
     *  - label - the value of tag
95
     *
96
     * All other options will be passed as third argument options to [[Html::tag]]
97
     */
98
    public $warning = [];
99
100
    /**
101
     * @var array
102
     */
103
    public $footer = [];
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function init()
109
    {
110
        parent::init();
111
        $this->initOptions();
112
    }
113
114
    /**
115
     * Configures options of widget.
116
     */
117
    public function initOptions()
118
    {
119
        $model = $this->model;
120
        if ($this->action === null) {
121
            $this->action = $model->state === $model::STATE_BLOCKED ? self::ACTION_DISABLE : self::ACTION_ENABLE;
0 ignored issues
show
Documentation introduced by
The property state does not exist on object<hipanel\base\Model>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation Bug introduced by
The property $action was declared of type integer, but $model->state === $model...E : self::ACTION_ENABLE is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
122
        }
123
124
        if ($this->scenario === null) {
125
            $this->scenario = $this->action === static::ACTION_ENABLE ? static::SCENARIO_ENABLE : static::SCENARIO_DISABLE;
126
        }
127
128
        if ($this->validationUrl === null) {
129
            $this->validationUrl = Url::toRoute(['validate-form', 'scenario' => $this->scenario]);
130
        }
131
132
        if ($this->blockReasons === null) {
133
            $this->blockReasons = Yii::$app->controller->getBlockReasons();
134
        }
135
136
        if (is_array($this->button)) {
137
            $this->button = ArrayHelper::merge([
138
                static::ACTION_ENABLE => [
139
                    'label' => FontIcon::i('fa-lock fa-2x fa-fw') . Yii::t('app', 'Enable block'),
140
                    'position' => ModalButton::BUTTON_OUTSIDE,
141
                ],
142
                static::ACTION_DISABLE => [
143
                    'label' => FontIcon::i('fa-unlock fa-2x fa-fw') . Yii::t('app', 'Disable block'),
144
                    'position' => ModalButton::BUTTON_OUTSIDE,
145
                ],
146
            ], $this->button);
147
            $this->button = $this->button[$this->action];
148
        }
149
150
        if (is_array($this->header)) {
151
            $this->header = ArrayHelper::merge([
152
                static::ACTION_ENABLE => [
153
                    'label' => Yii::t('app', 'Are you sure you want to block this object'),
154
                    'class' => 'label-danger',
155
                ],
156
                static::ACTION_DISABLE => [
157
                    'label' => Yii::t('app', 'Are you sure you want to unblock this object'),
158
                    'class' => 'label-info',
159
                ],
160
            ], $this->header);
161
162
            $this->header = $this->header[$this->action];
163
        }
164
165
        if (is_array($this->warning)) {
166
            $this->warning = ArrayHelper::merge([
167
                static::ACTION_ENABLE => false,
168
                static::ACTION_DISABLE => [
169
                    'label' => Yii::t('app', 'Check whether all of the violations were eliminated'),
170
                ],
171
            ], $this->warning);
172
173
            $this->warning = $this->warning[$this->action];
174
        }
175
176
        if (is_array($this->footer)) {
177
            $this->footer = ArrayHelper::merge([
178
                static::ACTION_ENABLE => [
179
                    'label' => Yii::t('app', 'Enable block'),
180
                    'data-loading-text' => Yii::t('app', 'Enabling block...'),
181
                    'class' => 'btn btn-danger',
182
                ],
183
                static::ACTION_DISABLE => [
184
                    'label' => Yii::t('app', 'Disable block'),
185
                    'data-loading-text' => Yii::t('app', 'Disabling block...'),
186
                    'class' => 'btn btn-info',
187
                ],
188
            ], $this->footer);
189
190
            $this->footer = $this->footer[$this->action];
191
        }
192
    }
193
194
    /**
195
     * Begins modal.
196
     * @throws \yii\base\InvalidConfigException
197
     */
198
    protected function modalBegin()
199
    {
200
        $config = ArrayHelper::merge([
201
            'class' => ModalButton::className(),
202
            'model' => $this->model,
203
            'scenario' => $this->scenario,
204
            'button' => $this->button,
205
            'form' => [
206
                'enableAjaxValidation' => true,
207
                'validationUrl' => $this->validationUrl,
208
            ],
209
            'modal' => [
210
                'header' => Html::tag(ArrayHelper::remove($this->header, 'tag', 'h4'),
211
                    ArrayHelper::remove($this->header, 'label')),
212
                'headerOptions' => $this->header,
213
                'footer' => $this->footer,
214
            ],
215
        ], $this->modal);
216
217
        $this->modal = call_user_func([ArrayHelper::remove($config, 'class'), 'begin'], $config);
218
    }
219
220
    /**
221
     * Ends modal.
222
     */
223
    protected function modalEnd()
224
    {
225
        $this->modal->end();
226
    }
227
228
    /**
229
     * Renders the body of the Modal.
230
     * Triggers [[EVENT_BEFORE_BODY]] and [[EVENT_AFTER_BODY]]
231
     * Set `$event->handled = true` to prevent default body render.
232
     */
233
    protected function renderBody()
234
    {
235
        $event = new Event();
236
        $this->trigger(static::EVENT_BEFORE_BODY, $event);
237
        if ($event->handled) {
238
            return;
239
        }
240
241
        if ($this->warning) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->warning of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
242
            echo Html::tag('div',
243
                Html::tag(
244
                    ArrayHelper::remove($this->warning, 'tag', 'h4'),
245
                    ArrayHelper::remove($this->warning, 'label'),
246
                    $this->warning
247
                ),
248
                ['class' => 'callout callout-warning']
249
            );
250
        }
251
252
        if ($this->blockReasons) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->blockReasons of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
253
            echo $this->modal->form->field($this->model, 'type')->dropDownList($this->blockReasons);
254
        }
255
        echo $this->modal->form->field($this->model, 'comment');
256
257
        $this->trigger(static::EVENT_AFTER_BODY);
258
    }
259
260
    /**
261
     * Renders widget.
262
     */
263
    public function run()
264
    {
265
        $this->modalBegin();
266
        $this->renderBody();
267
        $this->modalEnd();
268
    }
269
}
270