Completed
Pull Request — master (#361)
by
unknown
03:25
created

SessionHistoryDecorator::addFlash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 2
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User\Service\SessionHistory;
13
14
use Da\User\Model\SessionHistory;
15
use Da\User\Query\SessionHistoryCondition;
16
use Da\User\Query\SessionHistoryQuery;
17
use Da\User\Traits\ModuleAwareTrait;
18
use Yii;
19
use yii\db\Exception;
20
use yii\web\Session;
21
use yii\base\InvalidArgumentException as BaseInvalidArgumentException;
22
23
/**
24
 * Decorator for the {@see Session} class for storing the 'session history'
25
 *
26
 * Not decorated methods:
27
 * {@see Session::open()}
28
 * {@see Session::close()}
29
 * {@see Session::destroy()}
30
 * {@see Session::get()}
31
 * {@see Session::set()}
32
 */
33
class SessionHistoryDecorator extends Session
34
{
35
    use ModuleAwareTrait;
36
37
    public $sessionHistoryTable = '{{%session_history}}';
38
39
    /**
40
     * @var Session
41
     */
42
    public $session;
43
44
    public $condition;
45
46
    public function __construct(
47
        Session $session,
48
        SessionHistoryCondition $historyCondition,
49
        $config = []
50
    ) {
51
        $this->session = $session;
52
        $this->condition = $historyCondition;
53
54
        parent::__construct($config);
55
    }
56
57
    /** @inheritdoc */
58
    public function getUseCustomStorage()
59
    {
60
        return $this->session->getUseCustomStorage();
61
    }
62
63
    /** @inheritdoc */
64
    public function getIsActive()
65
    {
66
        return $this->session->getIsActive();
67
    }
68
69
    /** @inheritdoc */
70
    public function getHasSessionId()
71
    {
72
        return $this->session->getHasSessionId();
73
    }
74
75
    /** @inheritdoc */
76
    public function setHasSessionId($value)
77
    {
78
        return $this->session->setHasSessionId($value);
79
    }
80
81
    /** @inheritdoc */
82
    public function getId()
83
    {
84
        return $this->session->getId();
85
    }
86
87
    /** @inheritdoc */
88
    public function setId($value)
89
    {
90
        return $this->session->setId($value);
91
    }
92
93
    /** @inheritdoc */
94
    public function regenerateID($deleteOldSession = false)
95
    {
96
        return $this->getDb()->transaction(function () use ($deleteOldSession) {
97
            $oldSid = session_id();
98
            if (false === $this->session->regenerateID($deleteOldSession)) {
99
                return false;
100
            }
101
102
            if (false === $this->getModule()->enableSessionHistory) {
103
                return true;
104
            }
105
106
            $user = Yii::$app->user;
107
            if ($user->getIsGuest()) {
108
                $this->unbindSessionHistory($oldSid);
109
            } else {
110
                $this->getDB()->createCommand()
111
                    ->delete(
112
                        $this->sessionHistoryTable,
113
                        $this->condition->byUserSession($user->getId(), $oldSid)
114
                    )->execute();
115
            }
116
117
            return true;
118
        });
119
    }
120
121
    /** @inheritdoc */
122
    public function getName()
123
    {
124
        return $this->session->getName();
125
    }
126
127
    /** @inheritdoc */
128
    public function setName($value)
129
    {
130
        return $this->session->setName($value);
131
    }
132
133
    /** @inheritdoc */
134
    public function getSavePath()
135
    {
136
        return $this->session->getSavePath();
137
    }
138
139
    /** @inheritdoc */
140
    public function setSavePath($value)
141
    {
142
        return $this->session->setSavePath($value);
143
    }
144
145
    /** @inheritdoc */
146
    public function getCookieParams()
147
    {
148
        return $this->session->getCookieParams();
149
    }
150
151
    /** @inheritdoc */
152
    public function setCookieParams(array $value)
153
    {
154
        return $this->session->setCookieParams($value);
155
    }
156
157
    /** @inheritdoc */
158
    public function getUseCookies()
159
    {
160
        return $this->session->getUseCookies();
161
    }
162
163
    /** @inheritdoc */
164
    public function setUseCookies($value)
165
    {
166
        return $this->session->setUseCookies($value);
167
    }
168
169
    /** @inheritdoc */
170
    public function getGCProbability()
171
    {
172
        return $this->session->getGCProbability();
173
    }
174
175
    /** @inheritdoc */
176
    public function setGCProbability($value)
177
    {
178
        return $this->session->setGCProbability($value);
179
    }
180
181
    /** @inheritdoc */
182
    public function getUseTransparentSessionID()
183
    {
184
        return $this->session->getUseTransparentSessionID();
185
    }
186
187
    /** @inheritdoc */
188
    public function setUseTransparentSessionID($value)
189
    {
190
        return $this->session->setUseTransparentSessionID($value);
191
    }
192
193
    /** @inheritdoc */
194
    public function getTimeout()
195
    {
196
        return $this->session->getTimeout();
197
    }
198
199
    /** @inheritdoc */
200
    public function setTimeout($value)
201
    {
202
        return $this->session->setTimeout($value);
203
    }
204
205
    /** @inheritdoc */
206
    public function openSession($savePath, $sessionName)
207
    {
208
        return $this->session->openSession($savePath, $sessionName);
209
    }
210
211
    /** @inheritdoc */
212
    public function closeSession()
213
    {
214
        return $this->session->closeSession();
215
    }
216
217
    /** @inheritdoc */
218
    public function readSession($id)
219
    {
220
        return $this->session->readSession($id);
221
    }
222
223
    /** @inheritdoc */
224
    public function writeSession($id, $data)
225
    {
226
        return $this->session->writeSession($id, $data) &&
227
            (
228
                false === $this->getModule()->enableSessionHistory ||
229
                $this->getDb()->transaction(function () use ($id, $data) {
230
                    if (Yii::$app->user->getIsGuest()) {
231
                        return true;
232
                    }
233
234
                    $updatedAt = ['updated_at' => time()];
235
236
                    $model = $this->getHistoryQuery()
237
                        ->whereCurrentUser()
238
                        ->one();
239
                    if (isset($model)) {
240
                        $model->updateAttributes($updatedAt);
241
                        $result = true;
242
                    } else {
243
                        $model = Yii::createObject([
244
                                'class' => SessionHistory::class,
245
                            ] + $this->condition->currentUserData() + $updatedAt);
246
                        if (!$result = $model->save()) {
247
                            throw new BaseInvalidArgumentException(
248
                                print_r($model->errors, 1)
249
                            );
250
                        }
251
252
                        $this->displacementHistory($model->user_id);
253
                    }
254
255
                    return $result;
256
                })
257
            );
258
259
    }
260
261
    /** @inheritdoc */
262
    public function destroySession($id)
263
    {
264
        return $this->session->destroySession($id) &&
265
            (
266
                false === $this->getModule()->enableSessionHistory ||
267
                $this->getDb()->transaction(function () use ($id) {
268
                    $this->unbindSessionHistory($id);
269
270
                    return true;
271
                })
272
            );
273
    }
274
275
    /** @inheritdoc */
276
    public function gcSession($maxLifetime)
277
    {
278
        return $this->session->gcSession($maxLifetime) &&
279
            (
280
                false === $this->getModule()->enableSessionHistory ||
281
                $this->getDb()->transaction(function () use ($maxLifetime) {
282
                    $this->getDb()->createCommand()->update(
283
                        $this->sessionHistoryTable,
284
                        $this->condition->inactiveData(),
285
                        $this->condition->expired()
286
                    )->execute();
287
                    return true;
288
                })
289
            );
290
    }
291
292
    /** @inheritdoc */
293
    public function getIterator()
294
    {
295
        return $this->session->getIterator();
296
    }
297
298
    /** @inheritdoc */
299
    public function getCount()
300
    {
301
        return $this->session->getCount();
302
    }
303
304
    /** @inheritdoc */
305
    public function count()
306
    {
307
        return $this->session->count();
308
    }
309
310
    /** @inheritdoc */
311
    public function remove($key)
312
    {
313
        return $this->session->remove($key);
314
    }
315
316
    /** @inheritdoc */
317
    public function removeAll()
318
    {
319
        return $this->session->removeAll();
320
    }
321
322
    /** @inheritdoc */
323
    public function has($key)
324
    {
325
        return $this->session->has($key);
326
    }
327
328
    /** @inheritdoc */
329
    public function getFlash($key, $defaultValue = null, $delete = false)
330
    {
331
        return $this->session->getFlash($key, $defaultValue, $delete);
332
    }
333
334
    /** @inheritdoc */
335
    public function getAllFlashes($delete = false)
336
    {
337
        return $this->session->getAllFlashes($delete);
338
    }
339
340
    /** @inheritdoc */
341
    public function setFlash($key, $value = true, $removeAfterAccess = true)
342
    {
343
        return $this->session->setFlash($key, $value, $removeAfterAccess);
344
    }
345
346
    /** @inheritdoc */
347
    public function addFlash($key, $value = true, $removeAfterAccess = true)
348
    {
349
        return $this->session->addFlash($key, $value, $removeAfterAccess);
350
    }
351
352
    /** @inheritdoc */
353
    public function removeFlash($key)
354
    {
355
        return $this->session->removeFlash($key);
356
    }
357
358
    /** @inheritdoc */
359
    public function removeAllFlashes()
360
    {
361
        return $this->session->removeAllFlashes();
362
    }
363
364
    /** @inheritdoc */
365
    public function hasFlash($key)
366
    {
367
        return $this->session->hasFlash($key);
368
    }
369
370
    /** @inheritdoc */
371
    public function offsetExists($offset)
372
    {
373
        return $this->session->offsetExists($offset);
374
    }
375
376
    /** @inheritdoc */
377
    public function offsetGet($offset)
378
    {
379
        return $this->session->offsetGet($offset);
380
    }
381
382
    /** @inheritdoc */
383
    public function offsetSet($offset, $item)
384
    {
385
        return $this->session->offsetSet($offset, $item);
386
    }
387
388
    /** @inheritdoc */
389
    public function offsetUnset($offset)
390
    {
391
        return $this->session->offsetUnset($offset);
392
    }
393
394
    /** @inheritdoc */
395
    public function setCacheLimiter($cacheLimiter)
396
    {
397
        return $this->session->setCacheLimiter($cacheLimiter);
398
    }
399
400
    /** @inheritdoc */
401
    public function getCacheLimiter()
402
    {
403
        return $this->session->getCacheLimiter();
404
    }
405
406
    /**
407
     * @param string $id
408
     * @return bool
409
     * @throws Exception
410
     */
411
    protected function unbindSessionHistory($id)
412
    {
413
        return (bool)$this->getDb()->createCommand()->update(
414
            $this->sessionHistoryTable,
415
            $this->condition->unbindSession(),
416
            $this->condition->bySession($id)
417
        )->execute();
418
    }
419
420
    /**
421
     *
422
     * @param int $userId
423
     * @return bool
424
     * @throws Exception
425
     */
426
    protected function displacementHistory($userId)
427
    {
428
        $module = $this->getModule();
429
430
        if (false === $module->hasNumberSessionHistory()) {
431
            return true;
432
        }
433
434
        $updatedAt = $this->getHistoryQuery()
435
            ->oldestUpdatedTimeActiveSession($userId);
436
437
        if (!$updatedAt) {
438
            return true;
439
        }
440
441
        $this->getDB()->createCommand()->delete(
442
            $this->sessionHistoryTable,
443
            $this->condition->shouldDeleteBefore(intval($updatedAt), $userId)
444
        )->execute();
445
446
        return true;
447
    }
448
449
    /**
450
     * @return SessionHistoryQuery
451
     */
452
    protected function getHistoryQuery()
453
    {
454
        return Yii::$container->get(SessionHistoryQuery::class);
455
    }
456
457
    protected function getDb()
458
    {
459
        return Yii::$app->getDb();
460
    }
461
}
462