Passed
Push — master ( de4ed9...5f6eee )
by Petr
10:41
created

CookieAdapter::offsetSet()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 14
c 1
b 0
f 1
nc 4
nop 2
dl 0
loc 22
rs 9.4888
ccs 7
cts 7
cp 1
crap 5
1
<?php
2
3
namespace kalanis\kw_input\Simplified;
4
5
6
use ArrayIterator;
7
use kalanis\kw_input\InputException;
8
use kalanis\kw_input\Interfaces;
9
use kalanis\kw_input\Traits;
10
use Traversable;
11
12
13
/**
14
 * Class CookieAdapter
15
 * @package kalanis\kw_input\Extras
16
 * Accessing _COOKIES via ArrayAccess
17
 * Also set them into the headers
18
 * "Cannot modify header information - headers already sent"
19
 */
20
class CookieAdapter implements Interfaces\IFilteredInputs
21
{
22
    use Traits\TFill;
23
24
    protected static string $domain = '';
25
    protected static string $path = '';
26
    protected static ?int $expire = null;
27
    protected static bool $secure = false;
28
    protected static bool $httpOnly = false;
29
    protected static bool $sameSite = false;
30
    protected static bool $dieOnSent = false;
31
32 4
    public static function init(
33
        string $domain,
34
        string $path,
35
        ?int $expire = null,
36
        bool $secure = false,
37
        bool $httpOnly = false,
38
        bool $sameSite = false,
39
        bool $dieOnSent = false
40
    ): void
41
    {
42 4
        static::$domain = $domain;
43 4
        static::$path = $path;
44 4
        static::$expire = $expire;
45 4
        static::$secure = $secure;
46 4
        static::$httpOnly = $httpOnly;
47 4
        static::$sameSite = $sameSite;
48 4
        static::$dieOnSent = $dieOnSent;
49
    }
50
51
    /**
52
     * @param string|int $offset
53
     * @return mixed
54
     */
55 1
    public final function __get($offset)
56
    {
57 1
        return $this->offsetGet($offset);
58
    }
59
60
    /**
61
     * @param string|int $offset
62
     * @param mixed|null $value
63
     * @throws InputException
64
     */
65 3
    public final function __set($offset, $value): void
66
    {
67 3
        $this->offsetSet($offset, $value);
68
    }
69
70
    /**
71
     * @param string|int $offset
72
     * @return bool
73
     */
74 1
    public final function __isset($offset): bool
75
    {
76 1
        return $this->offsetExists($offset);
77
    }
78
79
    /**
80
     * @param string|int $offset
81
     * @throws InputException
82
     */
83 3
    public final function __unset($offset): void
84
    {
85 3
        $this->offsetUnset($offset);
86
    }
87
88 1
    public final function offsetExists($offset): bool
89
    {
90 1
        $offset = $this->removeNullBytes(strval($offset));
91 1
        return isset($_COOKIE[$offset]) && ('' != $_COOKIE[$offset]);
92
    }
93
94
    #[\ReturnTypeWillChange]
95 1
    public final function offsetGet($offset)
96
    {
97 1
        return $_COOKIE[$this->removeNullBytes(strval($offset))];
98
    }
99
100
    /**
101
     * @param string|int $offset
102
     * @param mixed|null $value
103
     * @throws InputException
104
     */
105 3
    public final function offsetSet($offset, $value): void
106
    {
107 3
        $offset = $this->removeNullBytes(strval($offset));
108
        // access immediately
109 3
        $_COOKIE[$offset] = $value;
110
111
        // now permanent ones
112 3
        if (headers_sent()) {
113 3
            if (static::$dieOnSent) {
114 1
                throw new InputException('Cannot modify header information - headers already sent');
115
            }
116 2
            return;
117
        }
118
        // @codeCoverageIgnoreStart
119
        $expire = is_null(static::$expire) ? null : time() + static::$expire;
120
        setcookie($offset, strval($value), [
121
            'expires'  => intval($expire),
122
            'path'     => strval(static::$path),
123
            'domain'   => strval(static::$domain),
124
            'secure'   => boolval(static::$secure),
125
            'httponly' => boolval(static::$httpOnly),
126
            'samesite' => static::$sameSite ? 'Strict' : 'Lax', // not in usual config
127
        ]);
128
        // @codeCoverageIgnoreEnd
129
    }
130
131
    /**
132
     * @param string|int $offset
133
     * @throws InputException
134
     */
135 3
    public function offsetUnset($offset): void
136
    {
137 3
        unset($_COOKIE[strval($this->removeNullBytes(strval($offset)))]); // remove immediately
138 3
        if (headers_sent()) {
139 3
            if (static::$dieOnSent) {
140 1
                throw new InputException('Cannot modify header information - headers already sent');
141
            }
142 2
            return;
143
        }
144
        // @codeCoverageIgnoreStart
145
        setcookie(strval($this->removeNullBytes(strval($offset))), '', (time() - 3600), static::$path, static::$domain);
146
    }
147
    // @codeCoverageIgnoreEnd
148
149 1
    public function getIterator(): Traversable
150
    {
151 1
        return new ArrayIterator(
152 1
            $this->fillFromEntries(Interfaces\IEntry::SOURCE_COOKIE, $_COOKIE),
153 1
            ArrayIterator::STD_PROP_LIST | ArrayIterator::ARRAY_AS_PROPS
154 1
        );
155
    }
156
}
157