Completed
Push — master ( 3c79d6...11a354 )
by Alexander
02:32
created

Flash::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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