Cookie   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 47
lcom 1
cbo 3
dl 0
loc 304
ccs 98
cts 98
cp 1
rs 8.439
c 0
b 0
f 0

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A hasName() 0 4 1
A getName() 0 4 1
A setName() 0 4 1
A hasValue() 0 4 1
A getValue() 0 4 1
A setValue() 0 4 1
A clearAttributes() 0 4 1
A hasAttributes() 0 4 1
A getAttributes() 0 4 1
A setAttributes() 0 5 1
A addAttributes() 0 6 2
A removeAttributes() 0 6 2
A hasAttribute() 0 4 1
A getAttribute() 0 4 2
A setAttribute() 0 4 1
A removeAttribute() 0 4 1
A getCreatedAt() 0 4 1
A setCreatedAt() 0 4 1
A getExpires() 0 12 3
A isExpired() 0 4 2
A compare() 0 6 3
A match() 0 6 3
A matchDomain() 0 14 3
A matchPath() 0 8 2
B matchScheme() 0 10 6
A toArray() 0 9 1
A __toString() 0 4 1
A fixAttribute() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Cookie often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Cookie, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the Ivory Http Adapter package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\HttpAdapter\Event\Cookie;
13
14
use Ivory\HttpAdapter\Message\InternalRequestInterface;
15
16
/**
17
 * @author GeLo <[email protected]>
18
 */
19
class Cookie implements CookieInterface
20
{
21
    /**
22
     * @var string|null
23
     */
24
    private $name;
25
26
    /**
27
     * @var string|null
28
     */
29
    private $value;
30
31
    /**
32
     * @var array
33
     */
34
    private $attributes;
35
36
    /**
37
     * @var int
38
     */
39
    private $createdAt;
40
41
    /**
42
     * @param string|null $name
43
     * @param string|null $value
44
     * @param array       $attributes
45
     * @param int         $createdAt
46
     */
47 918
    public function __construct($name, $value, array $attributes, $createdAt)
48
    {
49 918
        $this->setName($name);
50 918
        $this->setValue($value);
51 918
        $this->setAttributes($attributes);
52 918
        $this->setCreatedAt($createdAt);
53 918
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 72
    public function hasName()
59
    {
60 72
        return $this->name !== null;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 396
    public function getName()
67
    {
68 396
        return $this->name;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 918
    public function setName($name)
75
    {
76 918
        $this->name = $name;
77 918
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 72
    public function hasValue()
83
    {
84 72
        return $this->value !== null;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 297
    public function getValue()
91
    {
92 297
        return $this->value;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 918
    public function setValue($value)
99
    {
100 918
        $this->value = $value;
101 918
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 918
    public function clearAttributes()
107
    {
108 918
        $this->attributes = [];
109 918
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 18
    public function hasAttributes()
115
    {
116 18
        return !empty($this->attributes);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 306
    public function getAttributes()
123
    {
124 306
        return $this->attributes;
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 918
    public function setAttributes(array $attributes)
131
    {
132 918
        $this->clearAttributes();
133 918
        $this->addAttributes($attributes);
134 918
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 918
    public function addAttributes(array $attributes)
140
    {
141 918
        foreach ($attributes as $name => $value) {
142 810
            $this->setAttribute($name, $value);
143 714
        }
144 918
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149 9
    public function removeAttributes(array $names)
150
    {
151 9
        foreach ($names as $name) {
152 9
            $this->removeAttribute($name);
153 7
        }
154 9
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159 549
    public function hasAttribute($name)
160
    {
161 549
        return isset($this->attributes[$this->fixAttribute($name)]);
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167 459
    public function getAttribute($name)
168
    {
169 459
        return $this->hasAttribute($name) ? $this->attributes[$this->fixAttribute($name)] : null;
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175 810
    public function setAttribute($name, $value)
176
    {
177 810
        $this->attributes[$this->fixAttribute($name)] = $value;
178 810
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183 18
    public function removeAttribute($name)
184
    {
185 18
        unset($this->attributes[$this->fixAttribute($name)]);
186 18
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191 288
    public function getCreatedAt()
192
    {
193 288
        return $this->createdAt;
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199 918
    public function setCreatedAt($createdAt)
200
    {
201 918
        $this->createdAt = $createdAt;
202 918
    }
203
204
    /**
205
     * {@inheritdoc}
206
     */
207 90
    public function getExpires()
208
    {
209 90
        if ($this->hasAttribute(self::ATTR_EXPIRES)) {
210 45
            return strtotime($this->getAttribute(self::ATTR_EXPIRES));
211
        }
212
213 45
        if ($this->hasAttribute(self::ATTR_MAX_AGE)) {
214 27
            return $this->createdAt + $this->getAttribute(self::ATTR_MAX_AGE);
0 ignored issues
show
Bug Compatibility introduced by Eric GELOEN
The expression $this->createdAt + $this...te(self::ATTR_MAX_AGE); of type integer|double adds the type double to the return on line 214 which is incompatible with the return type declared by the interface Ivory\HttpAdapter\Event\...ieInterface::getExpires of type integer|boolean.
Loading history...
215
        }
216
217 18
        return false;
218
    }
219
220
    /**
221
     * {@inheritdoc}
222
     */
223 63
    public function isExpired()
224
    {
225 63
        return ($expires = $this->getExpires()) !== false ? $expires < time() : false;
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231 144
    public function compare(CookieInterface $cookie)
232
    {
233 144
        return $this->name === $cookie->getName()
234 144
            && $this->getAttribute(self::ATTR_DOMAIN) === $cookie->getAttribute(self::ATTR_DOMAIN)
235 144
            && $this->getAttribute(self::ATTR_PATH) === $cookie->getAttribute(self::ATTR_PATH);
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     */
241 144
    public function match(InternalRequestInterface $request)
242
    {
243 144
        return $this->matchDomain($request->getUri()->getHost())
244 144
            && $this->matchPath($request->getUri()->getPath())
245 144
            && $this->matchScheme($request->getUri()->getScheme());
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251 198
    public function matchDomain($domain)
252
    {
253 198
        if (!$this->hasAttribute(self::ATTR_DOMAIN)) {
254 81
            return true;
255
        }
256
257 117
        $cookieDomain = $this->getAttribute(self::ATTR_DOMAIN);
258
259 117
        if (strpos($cookieDomain, '.') === 0) {
260 36
            return (bool) preg_match('/\b'.preg_quote(substr($cookieDomain, 1), '/').'$/i', $domain);
261
        }
262
263 81
        return strcasecmp($cookieDomain, $domain) === 0;
264
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269 180
    public function matchPath($path)
270
    {
271 180
        if (!$this->hasAttribute(self::ATTR_PATH)) {
272 72
            return true;
273
        }
274
275 108
        return strpos($path, $this->getAttribute(self::ATTR_PATH)) === 0;
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281 180
    public function matchScheme($scheme)
282
    {
283 180
        if (!$this->hasAttribute(self::ATTR_SECURE)) {
284 72
            return true;
285
        }
286
287 108
        $secure = $this->getAttribute(self::ATTR_SECURE);
288
289 108
        return ($secure && $scheme === 'https') || (!$secure && ($scheme === 'http' || $scheme === null));
290
    }
291
292
    /**
293
     * {@inheritdoc}
294
     */
295 9
    public function toArray()
296
    {
297
        return [
298 9
            'name'       => $this->name,
299 9
            'value'      => $this->value,
300 9
            'attributes' => $this->attributes,
301 9
            'created_at' => $this->createdAt,
302 7
        ];
303
    }
304
305
    /**
306
     * {@inheritdoc}
307
     */
308 9
    public function __toString()
309
    {
310 9
        return $this->name.'='.$this->value;
311
    }
312
313
    /**
314
     * @param string $attribute
315
     *
316
     * @return string
317
     */
318 810
    private function fixAttribute($attribute)
319
    {
320 810
        return strtolower(trim($attribute));
321
    }
322
}
323