Passed
Push — master ( b86ef6...5fed0d )
by Alexander
02:39
created

Flash::getAll()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.0119

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
eloc 10
c 1
b 1
f 0
nc 4
nop 0
dl 0
loc 20
ccs 10
cts 11
cp 0.9091
crap 4.0119
rs 9.9332
1
<?php
2
3
namespace Yiisoft\Yii\Web;
4
5
use Yiisoft\Yii\Web\Session\SessionInterface;
6
7
final class Flash implements FlashInterface
8
{
9
    private const COUNTERS = '__counters';
10
11
    private const FLASH_PARAM = '__flash';
12
13
    private ?string $sessionId = null;
14
15
    private SessionInterface $session;
16
17 7
    public function __construct(SessionInterface $session)
18
    {
19 7
        $this->session = $session;
20 7
    }
21
22 1
    public function get(string $key)
23
    {
24 1
        $flashes = $this->fetch();
25
26 1
        if (!isset($flashes[$key], $flashes[self::COUNTERS][$key])) {
27 1
            return null;
28
        }
29
30 1
        if ($flashes[self::COUNTERS][$key] < 0) {
31
            // mark for deletion in the next request
32
            $flashes[self::COUNTERS][$key] = 1;
33
            $this->save($flashes);
34
        }
35
36 1
        return $flashes[$key];
37
    }
38
39 1
    public function getAll(): array
40
    {
41 1
        $flashes = $this->fetch();
42
43 1
        $list = [];
44 1
        foreach ($flashes as $key => $value) {
45 1
            if ($key === self::COUNTERS) {
46 1
                continue;
47
            }
48
49 1
            $list[$key] = $value;
50 1
            if ($flashes[self::COUNTERS][$key] < 0) {
51
                // mark for deletion in the next request
52
                $flashes[self::COUNTERS][$key] = 1;
53
            }
54
        }
55
56 1
        $this->save($flashes);
57
58 1
        return $list;
59
    }
60
61 1
    public function set(string $key, $value = true, bool $removeAfterAccess = true): void
62
    {
63 1
        $flashes = $this->fetch();
64 1
        $flashes[self::COUNTERS][$key] = $removeAfterAccess ? -1 : 0;
65 1
        $flashes[$key] = $value;
66 1
        $this->save($flashes);
67 1
    }
68
69 1
    public function add(string $key, $value = true, bool $removeAfterAccess = true): void
70
    {
71 1
        $flashes = $this->fetch();
72 1
        $flashes[self::COUNTERS][$key] = $removeAfterAccess ? -1 : 0;
73
74 1
        if (empty($flashes[$key])) {
75
            $flashes[$key] = [$value];
76 1
        } elseif (is_array($flashes[$key])) {
77
            $flashes[$key][] = $value;
78
        } else {
79 1
            $flashes[$key] = [$flashes[$key], $value];
80
        }
81
82 1
        $this->save($flashes);
83 1
    }
84
85 1
    public function remove(string $key): void
86
    {
87 1
        $flashes = $this->fetch();
88 1
        unset($flashes[$key], $flashes[self::COUNTERS][$key]);
89 1
        $this->save($flashes);
90 1
    }
91
92 1
    public function removeAll(): void
93
    {
94 1
        $this->save([self::COUNTERS => []]);
95 1
    }
96
97 1
    public function has(string $key): bool
98
    {
99 1
        $flashes = $this->fetch();
100 1
        return isset($flashes[$key], $flashes[self::COUNTERS][$key]);
101
    }
102
103
104
    /**
105
     * Updates the counters for flash messages and removes outdated flash messages.
106
     * This method should be called once after session initialization.
107
     */
108 6
    private function updateCounters(): void
109
    {
110 6
        $flashes = $this->session->get(self::FLASH_PARAM, []);
111 6
        if (!is_array($flashes)) {
112
            $flashes = [self::COUNTERS => []];
113
        }
114
115 6
        $counters = $flashes[self::COUNTERS] ?? [];
116 6
        if (!is_array($counters)) {
117
            $counters = [];
118
        }
119
120
121 6
        foreach ($counters as $key => $count) {
122 6
            if ($count > 0) {
123
                unset($counters[$key], $flashes[$key]);
124 6
            } elseif ($count === 0) {
125 6
                $counters[$key]++;
126
            }
127
        }
128
129 6
        $flashes[self::COUNTERS] = $counters;
130 6
        $this->save($flashes);
131 6
    }
132
133 6
    private function fetch(): array
134
    {
135
        // ensure session is active (and has id)
136 6
        $this->session->open();
137 6
        if ($this->sessionId !== $this->session->getId()) {
138 6
            $this->sessionId = $this->session->getId();
139 6
            $this->updateCounters();
140
        }
141
142 6
        return $this->session->get(self::FLASH_PARAM, []);
143
    }
144
145 7
    private function save(array $flashes): void
146
    {
147 7
        $this->session->set(self::FLASH_PARAM, $flashes);
148 7
    }
149
}
150