Passed
Push — master ( 974680...fc5316 )
by Kirill
03:59
created

Cookie::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 11
rs 10
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Cookies;
13
14
/**
15
 * Represent singular cookie header value with packing abilities.
16
 */
17
final class Cookie
18
{
19
    /**
20
     * The name of the cookie.
21
     *
22
     * @var string
23
     */
24
    private $name;
25
26
    /**
27
     * The value of the cookie. This value is stored on the clients computer; do not store sensitive information.
28
     *
29
     * @var string|null
30
     */
31
    private $value;
32
33
    /**
34
     * Cookie lifetime. This value specified in seconds and declares period of time in which cookie will expire
35
     * relatively to current time() value.
36
     *
37
     * @var int|null
38
     */
39
    private $lifetime;
40
41
    /**
42
     * The path on the server in which the cookie will be available on.
43
     * If set to '/', the cookie will be available within the entire domain. If set to '/foo/', the cookie will only be
44
     * available within the /foo/ directory and all sub-directories such as /foo/bar/ of domain. The default value is
45
     * the current directory that the cookie is being set in.
46
     *
47
     * @var string|null
48
     */
49
    private $path;
50
51
    /**
52
     * The domain that the cookie is available. To make the cookie available on all subdomains ofexample.com then you'd
53
     * set it to '.example.com'. The . is not required but makes itcompatible with more browsers. Setting it to
54
     * www.example.com will make the cookie onlyavailable in the www subdomain. Refer to tail matching in the spec for
55
     * details.
56
     *
57
     * @var string|null
58
     */
59
    private $domain;
60
61
    /**
62
     * Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client. When set to
63
     * true, the cookie will only be set if a secure connection exists. On the server-side, it's on the programmer to
64
     * send this kind of cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).
65
     *
66
     * @var bool
67
     */
68
    private $secure;
69
70
    /**
71
     * When true the cookie will be made accessible only through the HTTP protocol. This means that the cookie won't be
72
     * accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity
73
     * theft through XSS attacks (although it is not supported by all browsers).
74
     *
75
     * @var bool
76
     */
77
    private $httpOnly;
78
79
    /**
80
     * The value of the samesite element should be either None, Lax or Strict. If any of the allowed options are not
81
     * given, their default values are the same as the default values of the explicit parameters. If the samesite
82
     * element is omitted, no SameSite cookie attribute is set. When Same-Site attribute is set to "None" it is
83
     * required to have "Secure" attribute enable. Otherwise it will be converted to "Lax".
84
     *
85
     * @var Cookie\SameSite
86
     */
87
    private $sameSite;
88
89
    /**
90
     * New Cookie instance, cookies used to schedule cookie set while dispatching Response.
91
     *
92
     * @link http://php.net/manual/en/function.setcookie.php
93
     *
94
     * @param string      $name     The name of the cookie.
95
     * @param string|null $value    The value of the cookie. This value is stored on the clients computer; do not store
96
     *                              sensitive information.
97
     * @param int|null    $lifetime Cookie lifetime. This value specified in seconds and declares period of time in
98
     *                              which cookie will expire relatively to current time() value.
99
     * @param string|null $path     The path on the server in which the cookie will be available on. If set to '/', the
100
     *                              cookie will be available within the entire domain. If set to '/foo/', the cookie
101
     *                              will only be available within the /foo/ directory and all sub-directories such as
102
     *                              /foo/bar/ of domain. The default value is the current directory that the cookie is
103
     *                              being set in.
104
     * @param string|null $domain   The domain that the cookie is available. To make the cookie available on all
105
     *                              subdomains of example.com then you'd set it to '.example.com'. The . is not
106
     *                              required but makes it compatible with more browsers. Setting it to www.example.com
107
     *                              will make the cookie only available in the www subdomain. Refer to tail matching in
108
     *                              the spec for details.
109
     * @param bool        $secure   Indicates that the cookie should only be transmitted over a secure HTTPS connection
110
     *                              from the client. When set to true, the cookie will only be set if a secure
111
     *                              connection exists. On the server-side, it's on the programmer to send this kind of
112
     *                              cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).
113
     * @param bool        $httpOnly When true the cookie will be made accessible only through the HTTP protocol. This
114
     *                              means that the cookie won't be accessible by scripting languages, such as
115
     *                              JavaScript. This setting can effectively help to reduce identity theft through XSS
116
     *                              attacks (although it is not supported by all browsers).
117
     * @param string|null $sameSite The value of the samesite element should be either None, Lax or Strict. If any of
118
     *                              the allowed options are not given, their default values are the same as the default
119
     *                              values of the explicit parameters. If the samesite element is omitted, no SameSite
120
     *                              cookie attribute is set. When Same-Site attribute is set to "None" it is required
121
     *                              to have "Secure" attribute enable. Otherwise it will be converted to "Lax".
122
     */
123
    public function __construct(
124
        string $name,
125
        ?string $value = null,
126
        ?int $lifetime = null,
127
        ?string $path = null,
128
        ?string $domain = null,
129
        bool $secure = false,
130
        bool $httpOnly = true,
131
        ?string $sameSite = null
132
    ) {
133
        $this->name = $name;
134
        $this->value = $value;
135
        $this->lifetime = $lifetime;
136
        $this->path = $path;
137
        $this->domain = $domain;
138
        $this->secure = $secure;
139
        $this->httpOnly = $httpOnly;
140
        $this->sameSite = new Cookie\SameSite($sameSite, $secure);
141
    }
142
143
    /**
144
     * @return string
145
     */
146
    public function __toString(): string
147
    {
148
        return $this->createHeader();
149
    }
150
151
    /**
152
     * The name of the cookie.
153
     *
154
     * @return string
155
     */
156
    public function getName(): string
157
    {
158
        return $this->name;
159
    }
160
161
    /**
162
     * The value of the cookie. This value is stored on the clients computer; do not store sensitive information.
163
     *
164
     * @return string|null
165
     */
166
    public function getValue(): ?string
167
    {
168
        return $this->value;
169
    }
170
171
    /**
172
     * The path on the server in which the cookie will be available on. If set to '/', the cookie will be available
173
     * within the entire domain. If set to '/foo/', the cookie will only be available within the /foo/ directory and
174
     * all sub-directories such as /foo/bar/ of domain. The default value is the current directory that the cookie is
175
     * being set in.
176
     *
177
     * @return string|null
178
     */
179
    public function getPath(): ?string
180
    {
181
        return $this->path;
182
    }
183
184
    /**
185
     * The domain that the cookie is available. To make the cookie available on all subdomains of example.com then
186
     * you'd set it to '.example.com'. The . is not required but makes it compatible with more browsers. Setting it to
187
     * www.example.com will make the cookie only available in the www subdomain. Refer to tail matching in the spec for
188
     * details.
189
     *
190
     * @return string|null
191
     */
192
    public function getDomain(): ?string
193
    {
194
        return $this->domain;
195
    }
196
197
    /**
198
     * Indicates that the cookie should only be transmitted over a secure HTTPS connection from the client. When set to
199
     * true, the cookie will only be set if a secure connection exists. On the server-side, it's on the programmer to
200
     * send this kind of cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).
201
     *
202
     * @return bool
203
     */
204
    public function isSecure(): bool
205
    {
206
        return $this->secure;
207
    }
208
209
    /**
210
     * When true the cookie will be made accessible only through the HTTP protocol. This means that the cookie won't be
211
     * accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity
212
     * theft through XSS attacks (although it is not supported by all browsers).
213
     *
214
     * @return bool
215
     */
216
    public function isHttpOnly(): bool
217
    {
218
        return $this->httpOnly;
219
    }
220
221
    /**
222
     * The value of the samesite element should be either None, Lax or Strict. If any of the allowed options are not
223
     * given, their default values are the same as the default values of the explicit parameters. If the samesite
224
     * element is omitted, no SameSite cookie attribute is set. When Same-Site attribute is set to "None" it is
225
     * required to have "Secure" attribute enable. Otherwise it will be converted to "Lax".
226
     *
227
     * @return string
228
     */
229
    public function getSameSite(): ?string
230
    {
231
        return $this->sameSite->get();
232
    }
233
234
    /**
235
     * Get new cookie with altered value. Original cookie object should not be changed.
236
     *
237
     * @param string $value
238
     * @return Cookie
239
     */
240
    public function withValue(string $value): self
241
    {
242
        $cookie = clone $this;
243
        $cookie->value = $value;
244
245
        return $cookie;
246
    }
247
248
    /**
249
     * Convert cookie instance to string.
250
     *
251
     * @link http://www.w3.org/Protocols/rfc2109/rfc2109
252
     * @return string
253
     */
254
    public function createHeader(): string
255
    {
256
        $header = [rawurlencode($this->name) . '=' . rawurlencode((string)$this->value)];
257
258
        if ($this->lifetime !== null) {
259
            $header[] = 'Expires=' . gmdate(\DateTime::COOKIE, $this->getExpires());
260
            $header[] = "Max-Age={$this->lifetime}";
261
        }
262
263
        if (!empty($this->path)) {
264
            $header[] = "Path={$this->path}";
265
        }
266
267
        if (!empty($this->domain)) {
268
            $header[] = "Domain={$this->domain}";
269
        }
270
271
        if ($this->secure) {
272
            $header[] = 'Secure';
273
        }
274
275
        if ($this->httpOnly) {
276
            $header[] = 'HttpOnly';
277
        }
278
279
        if ($this->sameSite->get() !== null) {
280
            $header[] = "SameSite={$this->sameSite->get()}";
281
        }
282
283
        return implode('; ', $header);
284
    }
285
286
    /**
287
     * The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch. In other
288
     * words, you'll most likely set this with the time function plus the number of seconds before you want it to
289
     * expire. Or you might use mktime. Will return null if lifetime is not specified.
290
     *
291
     * @return int|null
292
     */
293
    public function getExpires(): ?int
294
    {
295
        if ($this->lifetime === null) {
296
            return null;
297
        }
298
299
        return time() + $this->lifetime;
300
    }
301
302
    /**
303
     * New Cookie instance, cookies used to schedule cookie set while dispatching Response. Static constructor.
304
     *
305
     * @link http://php.net/manual/en/function.setcookie.php
306
     *
307
     * @param string      $name     The name of the cookie.
308
     * @param string|null $value    The value of the cookie. This value is stored on the clients computer; do not store
309
     *                              sensitive information.
310
     * @param int|null    $lifetime Cookie lifetime. This value specified in seconds and declares period of time in
311
     *                              which cookie will expire relatively to current time() value.
312
     * @param string|null $path     The path on the server in which the cookie will be available on. If set to '/', the
313
     *                              cookie will be available within the entire domain. If set to '/foo/', the cookie
314
     *                              will only be available within the /foo/ directory and all sub-directories such as
315
     *                              /foo/bar/ of domain. The default value is the current directory that the cookie is
316
     *                              being set in.
317
     * @param string|null $domain   The domain that the cookie is available. To make the cookie available on all
318
     *                              subdomains of example.com then you'd set it to '.example.com'. The . is not
319
     *                              required but makes it compatible with more browsers. Setting it to www.example.com
320
     *                              will make the cookie only available in the www subdomain. Refer to tail matching in
321
     *                              the spec for details.
322
     * @param bool        $secure   Indicates that the cookie should only be transmitted over a secure HTTPS connection
323
     *                              from the client. When set to true, the cookie will only be set if a secure
324
     *                              connection exists. On the server-side, it's on the programmer to send this kind of
325
     *                              cookie only on secure connection (e.g. with respect to $_SERVER["HTTPS"]).
326
     * @param bool        $httpOnly When true the cookie will be made accessible only through the HTTP protocol. This
327
     *                              means that the cookie won't be accessible by scripting languages, such as
328
     *                              JavaScript. This setting can effectively help to reduce identity theft through XSS
329
     *                              attacks (although it is not supported by all browsers).
330
     * @param string|null $sameSite The value of the samesite element should be either None, Lax or Strict. If any of
331
     *                              the allowed options are not given, their default values are the same as the default
332
     *                              values of the explicit parameters. If the samesite element is omitted, no SameSite
333
     *                              cookie attribute is set. When Same-Site attribute is set to "None" it is required
334
     *                              to have "Secure" attribute enable. Otherwise it will be converted to "Lax".
335
     * @return Cookie
336
     */
337
    public static function create(
338
        string $name,
339
        ?string $value = null,
340
        ?int $lifetime = null,
341
        ?string $path = null,
342
        ?string $domain = null,
343
        bool $secure = false,
344
        bool $httpOnly = true,
345
        ?string $sameSite = null
346
    ): self {
347
        return new self($name, $value, $lifetime, $path, $domain, $secure, $httpOnly, $sameSite);
348
    }
349
}
350