Issues (3)

src/Cookie/Cookie.php (3 issues)

Labels
1
<?php
2
3
namespace ElePHPant\Cookie\Cookie;
4
5
6
/**
7
 * Class Cookie
8
 *
9
 * Please report bugs on https://github.com/wilderamorim/cookie/issues
10
 *
11
 * @author Wilder Amorim <https://github.com/wilderamorim>
12
 * @link https://www.linkedin.com/in/wilderamorim/
13
 */
14
class Cookie
15
{
16
    use CookieTrait {
17
        CookieTrait::__construct as private __traitConstructor;
18
    }
19
20
    /**
21
     * @param array $options
22
     */
23
    public function __construct(array $options = [])
24
    {
25
        $this->__traitConstructor($options);
26
    }
27
28
    /**
29
     * Set a cookie.
30
     *
31
     * @param string        $name       The name of the cookie.
32
     * @param mixed         $value      The value of the cookie.
33
     * @param int           $expiration The expiration time of the cookie.
34
     * @return bool                     True if the cookie is set successfully, false otherwise.
35
     */
36
    public static function set(string $name, $value, int $expiration): bool
37
    {
38
        if (empty($value) || $expiration < 1) {
39
            return false;
40
        }
41
42
        if (is_array($value)) {
43
            $value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
44
        }
45
46
        if (self::$isEncrypted) {
47
            $value = self::$encryptionStrategy->encrypt($value);
0 ignored issues
show
The method encrypt() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

47
            /** @scrutinizer ignore-call */ 
48
            $value = self::$encryptionStrategy->encrypt($value);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
48
        }
49
50
        return self::$storage->set($name, $value, $expiration);
51
    }
52
53
    /**
54
     * Get the value of a cookie.
55
     *
56
     * @param string|null $name The name of the cookie. If null, returns all cookies.
57
     * @return mixed            The value of the cookie, or an array of all cookies if $name is null.
58
     */
59
    public static function get(?string $name = null)
60
    {
61
        if (!$name) {
62
            return self::all();
63
        }
64
65
        $cookie = self::$storage->get($name);
66
        if ($cookie) {
67
            $cookie = self::$isEncrypted ? self::$encryptionStrategy->decrypt($cookie) : $cookie;
68
            return json_decode($cookie, true) ?? $cookie;
0 ignored issues
show
It seems like $cookie can also be of type null; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
            return json_decode(/** @scrutinizer ignore-type */ $cookie, true) ?? $cookie;
Loading history...
69
        }
70
71
        return null;
72
    }
73
74
    /**
75
     * Delete a cookie.
76
     *
77
     * @param string|null $name The name of the cookie. If null, deletes all cookies.
78
     * @return bool             True if the cookie is deleted successfully, false otherwise.
79
     */
80
    public static function destroy(?string $name = null): bool
81
    {
82
        return self::$storage->delete($name);
83
    }
84
85
    /**
86
     * Check if a cookie exists and optionally check its value.
87
     *
88
     * @param string    $name   The name of the cookie.
89
     * @param mixed     $value  The expected value of the cookie. If null, only checks for existence.
90
     * @return bool             True if the cookie exists and its value matches the expected value (or only existence is checked), false otherwise.
91
     */
92
    public static function has(string $name, $value = null): bool
93
    {
94
        $getCookie = self::get($name);
95
96
        if (!$value) {
97
            return $getCookie !== null;
98
        }
99
100
        return $getCookie === $value;
101
    }
102
103
    /**
104
     * Set a cookie if it doesn't already exist, with an option to remove the existing cookie.
105
     *
106
     * @param string      $name         The name of the cookie.
107
     * @param mixed       $value        The value of the cookie.
108
     * @param int         $expiration   The expiration time of the cookie.
109
     * @param bool        $removeHas    Whether to remove the existing cookie if it exists.
110
     * @return bool|null                True if the cookie is set successfully, null if the cookie already exists and $removeHas is false.
111
     */
112
    public static function setDoesntHave(string $name, $value, int $expiration, bool $removeHas = false): ?bool
113
    {
114
        if (!self::has($name)) {
115
            return self::set($name, $value, $expiration);
116
        }
117
118
        if ($removeHas) {
119
            return self::destroy($name);
120
        }
121
122
        return null;
123
    }
124
125
    /**
126
     * Get all cookies.
127
     *
128
     * @return array An associative array of all cookies, where the keys are the cookie names and the values are the cookie values.
129
     */
130
    private static function all(): array
131
    {
132
        $cookies = self::$storage->get() ?? [];
133
        $isBase64Encoded = fn(string $string): bool => $string === base64_encode(base64_decode($string));
134
        $isJson = fn(string $string): bool => json_decode($string) && json_last_error() === JSON_ERROR_NONE;
135
136
        return array_reduce(
137
            array_keys($cookies),
138
            fn($result, $key) => $result += [
139
                $key => self::$isEncrypted && $isBase64Encoded($cookies[$key])
140
                    ? (
141
                    $isJson(self::$encryptionStrategy->decrypt($cookies[$key]))
142
                        ? json_decode(self::$encryptionStrategy->decrypt($cookies[$key]), true)
0 ignored issues
show
It seems like self::encryptionStrategy->decrypt($cookies[$key]) can also be of type null; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
                        ? json_decode(/** @scrutinizer ignore-type */ self::$encryptionStrategy->decrypt($cookies[$key]), true)
Loading history...
143
                        : self::$encryptionStrategy->decrypt($cookies[$key])
144
                    )
145
                    : (
146
                    $isJson($cookies[$key])
147
                        ? json_decode($cookies[$key], true)
148
                        : $cookies[$key]
149
                    )
150
            ], []
151
        );
152
    }
153
}
154