FlashBag::withSession()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
nc 2
nop 1
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\Session\Flash;
6
7
/**
8
 * Flash messages are stored in the session and cleared after they're used.
9
 *
10
 * @implements \IteratorAggregate<int,Flash>
11
 */
12
class FlashBag implements \IteratorAggregate
13
{
14
    /** @var \ArrayAccess<string,mixed> */
15
    protected \ArrayAccess $session;
16
    protected string $key;
17
18
    /** @var Flash[] */
19
    protected array $entries = [];
20
21
    /**
22
     * Class constructor.
23
     */
24 6
    public function __construct(string $key = 'flash')
25
    {
26 6
        $this->key = $key;
27 6
    }
28
29
30
    /**
31
     * Get iterator for entries.
32
     *
33
     * @return \ArrayIterator<int,Flash>
34
     */
35 1
    public function getIterator(): \Traversable
36
    {
37 1
        return new \ArrayIterator($this->entries);
38
    }
39
40
    /**
41
     * Get all entries as array.
42
     *
43
     * @return Flash[]
44
     */
45 6
    public function getArrayCopy(): array
46
    {
47 6
        return $this->entries;
48
    }
49
50
51
    /**
52
     * Get copy with session object.
53
     *
54
     * @param \ArrayAccess<string,mixed> $session
55
     * @return static
56
     */
57 6
    public function withSession(\ArrayAccess $session): self
58
    {
59 6
        if (isset($this->session) && $this->session === $session) {
60 1
            return $this;
61
        }
62
63 6
        $copy = clone $this;
64 6
        $copy->session = $session;
65
66 6
        $copy->initFromSession();
67
68 6
        return $copy;
69
    }
70
71
    /**
72
     *  Initialize the entries from the session.
73
     */
74 6
    protected function initFromSession(): void
75
    {
76 6
        if (!isset($this->session[$this->key])) {
77 1
            return;
78
        }
79
80 5
        $entries = $this->session[$this->key];
81 5
        unset($this->session[$this->key]);
82
83 5
        if (!is_array($entries)) {
84 1
            trigger_error('Invalid flash session data', E_USER_WARNING);
85 1
            return;
86
        }
87
88 4
        $this->initEntries($entries);
89 4
    }
90
91
    /**
92
     * Initialize the entries.
93
     *
94
     * @param array<mixed> $entries
95
     */
96 4
    protected function initEntries(array $entries): void
97
    {
98 4
        $invalid = 0;
99
100 4
        foreach ($entries as $entry) {
101 4
            if (!is_array($entry) || !isset($entry['message'])) {
102 1
                $invalid++;
103 1
                continue;
104
            }
105
106 4
            $this->entries[] = new Flash(
107 4
                $entry['type'] ?? '',
108 4
                $entry['message'],
109 4
                $entry['contentType'] ?? 'text/plain'
110
            );
111
        }
112
113 4
        if ($invalid > 0) {
114 1
            trigger_error(
115 1
                $invalid === 1 ? "Ignored invalid flash message" : "Ignoring $invalid invalid flash messages",
116 1
                E_USER_NOTICE,
117
            );
118
        }
119 4
    }
120
121
122
    /**
123
     * Add a flash message.
124
     *
125
     * @param string $type         flash type, eg. 'error', 'notice' or 'success'
126
     * @param string $message      flash message
127
     * @param string $contentType  mime, eg 'text/plain' or 'text/html'
128
     * @return $this
129
     */
130 3
    public function add(string $type, string $message, string $contentType = 'text/plain'): self
131
    {
132 3
        $this->session[$this->key][] = ['type' => $type, 'message' => $message, 'contentType' => $contentType];
133
134 3
        return $this;
135
    }
136
137
    /**
138
     * Reissue the flash messages.
139
     * Get it now and it will remain in the session for next request.
140
     */
141 1
    public function reissue(): self
142
    {
143 1
        $this->session[$this->key] = array_merge(
144 1
            array_map(fn(Flash $flash) => $flash->toAssoc(), $this->entries),
145 1
            $this->session[$this->key] ?? [],
146
        );
147
148 1
        $this->entries = [];
149
150 1
        return $this;
151
    }
152
153
    /**
154
     * Clear all flash messages.
155
     */
156 1
    public function clear(): self
157
    {
158 1
        $this->entries = [];
159
160 1
        if (isset($this->session[$this->key])) {
161 1
            unset($this->session[$this->key]);
162
        }
163
164 1
        return $this;
165
    }
166
}
167