Passed
Push — master ( 1437fc...4d325a )
by Alexey
02:33
created

FileStateForm::loadModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
namespace dominus77\maintenance\models;
4
5
use Yii;
6
use yii\base\InvalidConfigException;
7
use yii\di\NotInstantiableException;
8
use yii\helpers\ArrayHelper;
9
use dominus77\maintenance\interfaces\StateFormInterface;
10
use dominus77\maintenance\states\FileState;
11
use dominus77\maintenance\BackendMaintenance;
12
use dominus77\maintenance\Maintenance;
13
use Exception;
14
use DateTime;
15
use yii\web\Session;
16
17
/**
18
 * Class FileStateForm
19
 * @package dominus77\maintenance\models
20
 *
21
 * @property string $dateTime
22
 * @property mixed $modeName
23
 * @property int $statusCode
24
 * @property int $timestamp
25
 */
26
class FileStateForm extends BaseForm implements StateFormInterface
27
{
28
    const MAINTENANCE_NOTIFY_SENDER_KEY = 'notifySender';
29
    const MAINTENANCE_UPDATE_KEY = 'maintenanceUpdate';
30
31
    /**
32
     * Select mode
33
     * @var string
34
     */
35
    public $mode;
36
    /**
37
     * Datetime
38
     * @var string
39
     */
40
    public $date;
41
    /**
42
     * Title
43
     * @var string
44
     */
45
    public $title;
46
    /**
47
     * Text
48
     * @var string
49
     */
50
    public $text;
51
    /**
52
     * Subscribe
53
     * @var string
54
     */
55
    public $subscribe;
56
    /**
57
     * CountDownWidget
58
     * @var string
59
     */
60
    public $countDown;
61
62
    /**
63
     * @var FileState
64
     */
65
    protected $state;
66
67
    /**
68
     * @throws InvalidConfigException
69
     * @throws NotInstantiableException
70
     */
71
    public function init()
72
    {
73
        parent::init();
74
        $this->loadModel();
75
    }
76
77
    /**
78
     * @inheritDoc
79
     * @return array
80
     */
81
    public function rules()
82
    {
83
        return [
84
            ['date', 'trim'],
85
            ['mode', 'required'],
86
            ['date', 'string', 'max' => 19],
87
            ['date', 'validateDateAttribute'],
88
            [['title', 'text'], 'string'],
89
            [['subscribe', 'countDown'], 'boolean']
90
        ];
91
    }
92
93
    /**
94
     * Validate date attribute
95
     *
96
     * @param $attribute
97
     * @throws InvalidConfigException
98
     */
99
    public function validateDateAttribute($attribute)
100
    {
101
        if ($attribute && !$this->validDate($this->$attribute)) {
102
            $example = $this->getDateTime();
103
            $this->addError($attribute, BackendMaintenance::t('app', 'Invalid date format. Use example: {:example}', [':example' => $example]));
104
        }
105
    }
106
107
    /**
108
     * Validate datetime
109
     *
110
     * @param $date
111
     * @return bool
112
     */
113
    public function validDate($date)
114
    {
115
        $d = DateTime::createFromFormat($this->dateFormat, $date);
116
        return $d && $d->format($this->dateFormat) === $date;
117
    }
118
119
    /**
120
     * @inheritDoc
121
     * @return array
122
     */
123
    public function attributeLabels()
124
    {
125
        return [
126
            'mode' => BackendMaintenance::t('app', 'Mode'),
127
            'date' => BackendMaintenance::t('app', 'Date and Time'),
128
            'title' => BackendMaintenance::t('app', 'Title'),
129
            'text' => BackendMaintenance::t('app', 'Text'),
130
            'subscribe' => BackendMaintenance::t('app', 'Subscribe'),
131
            'countDown' => BackendMaintenance::t('app', 'Count Down'),
132
        ];
133
    }
134
135
    /**
136
     * Set data model
137
     */
138
    public function loadModel()
139
    {
140
        if ($stateArray = $this->prepareLoadModel($this->state->path)) {
141
            $this->setAttributes($stateArray);
142
        } else {
143
            $this->setAttributeDefaultData();
144
        }
145
    }
146
147
    /**
148
     * @throws InvalidConfigException
149
     */
150
    public function setAttributeDefaultData()
151
    {
152
        $this->mode = $this->mode ?: Maintenance::STATUS_CODE_OK;
153
        $this->date = $this->date ?: $this->getDateTime();
154
        $this->title = $this->title ?: BackendMaintenance::t('app', $this->state->defaultTitle);
155
        $this->text = $this->text ?: BackendMaintenance::t('app', $this->state->defaultContent);
156
        $this->subscribe = $this->subscribe ?: 'true';
157
        $this->countDown = $this->countDown ?: 'true';
158
    }
159
160
    /**
161
     * Current Datetime
162
     *
163
     * @return string
164
     * @throws InvalidConfigException
165
     */
166
    public function getDateTime()
167
    {
168
        return Yii::$app->formatter->asDatetime($this->getTimestamp(), 'php:' . $this->dateFormat);
169
    }
170
171
    /**
172
     * Mode name
173
     * @return mixed
174
     */
175
    public function getModeName()
176
    {
177
        return ArrayHelper::getValue(self::getModesArray(), (int)$this->mode);
178
    }
179
180
    /**
181
     * Modes
182
     * @return array
183
     */
184
    public static function getModesArray()
185
    {
186
        return [
187
            Maintenance::STATUS_CODE_OK => BackendMaintenance::t('app', 'Mode normal'),
188
            Maintenance::STATUS_CODE_MAINTENANCE => BackendMaintenance::t('app', 'Mode maintenance'),
189
        ];
190
    }
191
192
    /**
193
     * Save this in file
194
     */
195
    public function save()
196
    {
197
        $result = false;
198
        if ($this->mode === (string)Maintenance::STATUS_CODE_MAINTENANCE) {
199
            if (file_exists($this->state->path)) {
200
                unlink($this->state->path);
201
            }
202
            file_put_contents($this->state->path,
203
                $this->prepareData());
204
            $result = chmod($this->state->path, 0765);
205
        }
206
        if ($this->mode === (string)Maintenance::STATUS_CODE_OK) {
207
            $model = new SubscribeForm();
208
            $count = $model->send();
209
            $this->state->disable();
210
            /** @var Session $session */
211
            $session = Yii::$app->session;
212
            $session->setFlash(self::MAINTENANCE_NOTIFY_SENDER_KEY, BackendMaintenance::t('app',
213
                '{n, plural, =0{no followers} =1{one message sent} other{# messages sent}}',
214
                ['n' => $count])
215
            );
216
            $result = true;
217
        }
218
        return $result;
219
    }
220
221
    /**
222
     * @return string
223
     */
224
    public function prepareData()
225
    {
226
        $result = '';
227
        foreach ($this->attributes as $attribute => $value) {
228
            $result .= $attribute . ' = ' . $value . PHP_EOL;
229
        }
230
        return $result;
231
    }
232
233
    /**
234
     * Enable
235
     *
236
     * @return bool|mixed
237
     */
238
    public function enable()
239
    {
240
        return $this->state->enable();
241
    }
242
243
    /**
244
     * Disable
245
     *
246
     * @return bool|mixed
247
     */
248
    public function disable()
249
    {
250
        return $this->state->disable();
251
    }
252
253
    /**
254
     * @return int
255
     * @throws Exception
256
     */
257
    public function getTimestamp()
258
    {
259
        $date = new DateTime(date($this->dateFormat));
260
        if ($this->validDate($this->date)) {
261
            $date = new DateTime($this->date);
262
        }
263
        return $date->getTimestamp();
264
    }
265
266
    /**
267
     * @return bool
268
     */
269
    public function isTimer()
270
    {
271
        return (bool)$this->countDown;
272
    }
273
274
    /**
275
     * @return bool
276
     */
277
    public function isSubscribe()
278
    {
279
        return (bool)$this->subscribe;
280
    }
281
282
    /**
283
     * Return true is enable maintenance mode
284
     * @return bool
285
     */
286
    public function isEnabled()
287
    {
288
        return $this->state->isEnabled();
289
    }
290
291
    /**
292
     * StatusCode
293
     * @return int
294
     */
295
    public function getStatusCode()
296
    {
297
        if ($this->state->isEnabled()) {
298
            $mode = (int)$this->mode;
299
            return ($mode !== Maintenance::STATUS_CODE_OK) ? $mode : Maintenance::STATUS_CODE_MAINTENANCE;
300
        }
301
        return Maintenance::STATUS_CODE_OK;
302
    }
303
}
304