Cookie   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 34
c 2
b 0
f 1
dl 0
loc 73
ccs 33
cts 33
cp 1
rs 10
wmc 13

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getCookiesHeaderLine() 0 13 3
B serializePHPCookies() 0 36 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Soluble Japha
7
 *
8
 * @link      https://github.com/belgattitude/soluble-japha
9
 * @copyright Copyright (c) 2013-2020 Vanvelthem Sébastien
10
 * @license   MIT License https://github.com/belgattitude/soluble-japha/blob/master/LICENSE.md
11
 */
12
13
namespace Soluble\Japha\Bridge\Http;
14
15
/**
16
 * Utility class to serialize a PHP cookie array into a valid HTTP cookie header.
17
 */
18
class Cookie
19
{
20
    /**
21
     * Value used for values that cannot be serialized.
22
     */
23
    public const UNSUPPORTED_TYPE_VALUE = '__UNSUPPORTED_TYPE__';
24
25
    /**
26
     * Serialize PHP's $_COOKIE values into a valid HTTP COOKIE string.
27
     *
28
     * @param array<string, string> $cookies if null
29
     *
30
     * @return string|null
31
     */
32 34
    public static function getCookiesHeaderLine(array $cookies = null): ?string
33
    {
34 34
        $cookies = $cookies ?? $_COOKIE;
35 34
        if (empty($cookies)) {
36 29
            return null;
37
        }
38
39 5
        $cookieParts = [];
40 5
        foreach ($cookies as $k => $v) {
41 5
            $cookieParts[] = self::serializePHPCookies($k, $v);
42
        }
43
44 5
        return 'Cookie: '.implode(';', $cookieParts);
45
    }
46
47
    /**
48
     * Escapes $cookieValue taking into account its type to serialize it as a valid cookie value.
49
     *
50
     * @param string $cookieName
51
     * @param mixed  $cookieValue
52
     *
53
     * @return string
54
     */
55 5
    private static function serializePHPCookies(string $cookieName, $cookieValue): string
56
    {
57 5
        $cookieParts = [];
58 5
        $urlEncodedCookieName = urlencode($cookieName);
59 5
        $valueType = gettype($cookieValue);
60 5
        switch ($valueType) {
61 5
            case 'integer':
62 5
            case 'double':
63 5
            case 'string':
64 3
                $urlEncodedCookieValue = urlencode((string) $cookieValue);
65 3
                $cookieParts[] = "$urlEncodedCookieName=$urlEncodedCookieValue";
66 3
                break;
67
68 3
            case 'array':
69 1
                foreach ($cookieValue as $cookieValueKey => $cookieValueValue) {
70 1
                    $cookieParts[] = self::serializePHPCookies($cookieName."[$cookieValueKey]", $cookieValueValue);
71
                }
72 1
                break;
73
74 3
            case 'NULL':
75 2
                $cookieParts[] = "$urlEncodedCookieName=";
76 2
                break;
77
78 3
            case 'boolean':
79 2
                $cookieParts[] = "$urlEncodedCookieName=".((bool) $cookieValue ? '1' : '0');
80 2
                break;
81
82
            // It's a security risk to serialize an object and send it as a cookie
83 1
            case 'object':
84
                // Intentional fallthrough
85
            default:
86 1
                $cookieParts[] = "$urlEncodedCookieName=".self::UNSUPPORTED_TYPE_VALUE;
87 1
                break;
88
        }
89
90 5
        return implode(';', $cookieParts);
91
    }
92
}
93