Completed
Pull Request — master (#106)
by Marco
02:15 queued 24s
created

DefaultSessionData::isEmpty()   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 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
declare(strict_types=1);
20
21
namespace PSR7Sessions\Storageless\Session;
22
23
use InvalidArgumentException;
24
use JsonSerializable;
25
use stdClass;
26
use function array_key_exists;
27
use function assert;
28
use function count;
29
use function is_array;
30
use function is_string;
31
use function json_decode;
32
use function json_encode;
33
use function json_last_error;
34
use function json_last_error_msg;
35
use function sprintf;
36
use function var_export;
37
use const JSON_PRESERVE_ZERO_FRACTION;
38
39
final class DefaultSessionData implements SessionInterface
40
{
41
    /** @var array<string, int|bool|string|float|mixed[]|null> */
42
    private array $data;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ARRAY, expecting T_FUNCTION or T_CONST
Loading history...
43
44
    /** @var array<string, int|bool|string|float|mixed[]|null> */
45
    private array $originalData;
46
47
    /**
48
     * Instantiation via __construct is not allowed, use
49
     * - {@see DefaultSessionData::fromDecodedTokenData}
50
     * - {@see DefaultSessionData::fromTokenData}
51
     * - {@see DefaultSessionData::newEmptySession}
52
     * instead
53
     */
54 193
    private function __construct()
55
    {
56 193
    }
57
58 33
    public static function fromDecodedTokenData(stdClass $data) : self
59
    {
60 33
        $instance = new self();
61
62 33
        $arrayShapedData = self::convertValueToScalar($data);
63 33
        assert(is_array($arrayShapedData));
64
65 33
        $instance->originalData = $instance->data = $arrayShapedData;
66
67 33
        return $instance;
68
    }
69
70
    /** @param mixed[] $data */
71 75
    public static function fromTokenData(array $data) : self
72
    {
73 75
        $instance = new self();
74
75 75
        $instance->data = [];
76
77 75
        foreach ($data as $key => $value) {
78 73
            $instance->set((string) $key, $value);
79
        }
80
81 74
        $instance->originalData = $instance->data;
82
83 74
        return $instance;
84
    }
85
86 107
    public static function newEmptySession() : self
87
    {
88 107
        $instance = new self();
89
90 107
        $instance->originalData = $instance->data = [];
91
92 107
        return $instance;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98 135
    public function set(string $key, $value) : void
99
    {
100 135
        $this->data[$key] = self::convertValueToScalar($value);
101 134
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106 95
    public function get(string $key, $default = null)
107
    {
108 95
        if (! $this->has($key)) {
109 26
            return self::convertValueToScalar($default);
110
        }
111
112 69
        return $this->data[$key];
113
    }
114
115 1
    public function remove(string $key) : void
116
    {
117 1
        unset($this->data[$key]);
118 1
    }
119
120 4
    public function clear() : void
121
    {
122 4
        $this->data = [];
123 4
    }
124
125 96
    public function has(string $key) : bool
126
    {
127 96
        return array_key_exists($key, $this->data);
128
    }
129
130 89
    public function hasChanged() : bool
131
    {
132 89
        return $this->data !== $this->originalData;
133
    }
134
135 49
    public function isEmpty() : bool
136
    {
137 49
        return ! count($this->data);
138
    }
139
140 40
    public function jsonSerialize() : object
141
    {
142 40
        return (object) $this->data;
143
    }
144
145
    /**
146
     * @param int|bool|string|float|mixed[]|object|JsonSerializable|null $value
147
     *
148
     * @return int|bool|string|float|mixed[]
149
     */
150 182
    private static function convertValueToScalar($value)
151
    {
152 182
        $jsonScalar = json_encode($value, JSON_PRESERVE_ZERO_FRACTION);
153
154 182
        if (! is_string($jsonScalar)) {
155
            // @TODO use PHP 7.3 and JSON_THROW_ON_ERROR instead? https://wiki.php.net/rfc/json_throw_on_error
156 1
            throw new InvalidArgumentException(sprintf(
157 1
                'Could not serialise given value %s due to %s (%s)',
158 1
                var_export($value, true),
159 1
                json_last_error_msg(),
160 1
                json_last_error()
161
            ));
162
        }
163
164 181
        return json_decode($jsonScalar, true);
165
    }
166
}
167