Completed
Push — master ( 24802e...2ba5bb )
by Walter
02:16
created

Cookie   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 173
wmc 19
lcom 1
cbo 1
ccs 61
cts 61
cp 1
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B parseExistingCookie() 0 22 5
A saveCookie() 0 6 1
A has() 0 9 1
A get() 0 8 2
A set() 0 16 3
A all() 0 6 1
A remove() 0 20 3
A clear() 0 13 2
1
<?php
2
/**
3
 * This file is part of phpab/phpab. (https://github.com/phpab/phpab)
4
 *
5
 * @link https://github.com/phpab/phpab for the canonical source repository
6
 * @copyright Copyright (c) 2015-2016 phpab. (https://github.com/phpab/)
7
 * @license https://raw.githubusercontent.com/phpab/phpab/master/LICENSE.md MIT
8
 */
9
10
namespace PhpAb\Storage\Adapter;
11
12
use InvalidArgumentException;
13
use RuntimeException;
14
use Webmozart\Assert\Assert;
15
16
/**
17
 * Cookie Storage Adapter records the participation state of the user in a cookie.
18
 *
19
 * @package PhpAb
20
 */
21
class Cookie implements AdapterInterface
22
{
23
    /**
24
     * The name of cookie.
25
     *
26
     * @var string
27
     */
28
    protected $cookieName;
29
    /**
30
     * The cookie's time to live in seconds
31
     *
32
     * @var int
33
     */
34
    protected $ttl;
35
    /**
36
     * The array of which will be saved in cookie.
37
     *
38
     * @var null|array
39
     */
40
    protected $data;
41
42
    /**
43
     * Initializes a new instance of this class.
44
     *
45
     * @param string $cookieName   The name the cookie.
46
     * @param int   $ttl           How long should the cookie last in browser. Default 5 years
47
     *                             Setting a negative number will make cookie expire after current session
48
     * @throws InvalidArgumentException
49
     */
50 20
    public function __construct($cookieName, $ttl = 157766400)
51
    {
52
        // We cannot typehint for primitive types yet so therefore we check if the cookie name is a (valid) string.
53 20
        Assert::string($cookieName, 'The cookie name is invalid.');
54 19
        Assert::notEmpty($cookieName, 'The cookie name is invalid.');
55 18
        Assert::integer($ttl, 'The cookie ttl parameter should be a integer.');
56
57 17
        $this->cookieName = $cookieName;
58
59 17
        $this->ttl = $ttl;
60 17
    }
61
62
    /**
63
     * Parses any previous cookie and stores it internally
64
     */
65 12
    protected function parseExistingCookie()
66
    {
67 12
        if (is_array($this->data)) {
68 5
            return;
69
        }
70
71 12
        $cookiesContent = filter_input_array(INPUT_COOKIE);
72
73 12
        if (empty($cookiesContent) || !array_key_exists($this->cookieName, $cookiesContent)) {
74 1
            $this->data = [];
75 1
            return;
76
        }
77
78 11
        $deserializedCookie = json_decode($cookiesContent[$this->cookieName], true);
79
80 11
        if (is_null($deserializedCookie)) {
81 2
            $this->data = [];
82 2
            return;
83
        }
84
85 9
        $this->data = $deserializedCookie;
86 9
    }
87
88
    /**
89
     * {@inheritDoc}
90
     */
91 3
    protected function saveCookie()
92
    {
93 3
        $this->parseExistingCookie();
94
95 3
        return setcookie($this->cookieName, json_encode($this->data), time() + $this->ttl, '/');
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101 11
    public function has($identifier)
102
    {
103 11
        Assert::string($identifier, 'Test identifier is invalid.');
104 7
        Assert::notEmpty($identifier, 'Test identifier is invalid.');
105
106 7
        $this->parseExistingCookie();
107
108 7
        return array_key_exists($identifier, $this->data);
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114 4
    public function get($identifier)
115
    {
116 4
        if (!$this->has($identifier)) {
117 2
            return null;
118
        }
119
120 3
        return $this->data[$identifier];
121
    }
122
123
    /**
124
     * {@inheritDoc}
125
     */
126 4
    public function set($identifier, $participation)
127
    {
128 4
        $this->has($identifier);
129
130 3
        if ('' === $participation) {
131 1
            throw new InvalidArgumentException('Participation name is invalid.');
132
        }
133
134 2
        if (headers_sent()) {
135 1
            throw new RuntimeException('Headers have been sent. Cannot save cookie.');
136
        }
137
138 1
        $this->data[$identifier] = $participation;
139
140 1
        return $this->saveCookie();
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146 6
    public function all()
147
    {
148 6
        $this->parseExistingCookie();
149
150 6
        return $this->data;
151
    }
152
153
    /**
154
     * {@inheritDoc}
155
     */
156 3
    public function remove($identifier)
157
    {
158 3
        $this->has($identifier);
159
160 2
        if (headers_sent()) {
161 1
            throw new RuntimeException('Headers have been sent. Cannot save cookie.');
162
        }
163
164 1
        $value = $this->get($identifier);
165
166 1
        if (is_null($value)) {
167 1
            return null;
168
        }
169
170 1
        unset($this->data[$identifier]);
171
172 1
        $this->saveCookie();
173
174 1
        return $value;
175
    }
176
177
    /**
178
     * {@inheritDoc}
179
     */
180 2
    public function clear()
181
    {
182 2
        if (headers_sent()) {
183 1
            throw new RuntimeException('Headers have been sent. Cannot save cookie.');
184
        }
185
186 1
        $this->parseExistingCookie();
187 1
        $values = $this->data;
188 1
        $this->data = [];
189 1
        $this->saveCookie();
190
191 1
        return $values;
192
    }
193
}
194