Passed
Push — v7 ( c2ec86...629ebb )
by Georges
01:43
created

Driver::driverReadExpirationDate()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 4
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
declare(strict_types=1);
15
16
namespace Phpfastcache\Drivers\Cookie;
17
18
use Phpfastcache\Core\Pool\{DriverBaseTrait, ExtendedCacheItemPoolInterface};
19
use Phpfastcache\Entities\DriverStatistic;
20
use Phpfastcache\Exceptions\{
21
  PhpfastcacheInvalidArgumentException, PhpfastcacheDriverException
22
};
23
use Psr\Cache\CacheItemInterface;
24
25
/**
26
 * Class Driver
27
 * @package phpFastCache\Drivers
28
 * @property Config $config Config object
29
 * @method Config getConfig() Return the config object
30
 */
31
class Driver implements ExtendedCacheItemPoolInterface
32
{
33
    use DriverBaseTrait;
34
35
    const PREFIX = 'PFC_';
36
37
    /**
38
     * @return bool
39
     */
40
    public function driverCheck(): bool
41
    {
42
        return \function_exists('setcookie');
43
    }
44
45
    /**
46
     * @return bool
47
     */
48
    protected function driverConnect(): bool
49
    {
50
        return !(!\array_key_exists('phpFastCache', $_COOKIE) && !@setcookie('phpFastCache', 1, 10));
51
    }
52
53
    /**
54
     * @param \Psr\Cache\CacheItemInterface $item
55
     * @return null|array
56
     * @throws \Phpfastcache\Exceptions\PhpfastcacheDriverException
57
     */
58
    protected function driverRead(CacheItemInterface $item)
59
    {
60
        $this->driverConnect();
61
        $keyword = self::PREFIX . $item->getKey();
62
        $x = isset($_COOKIE[ $keyword ]) ? \json_decode($_COOKIE[ $keyword ], true) : false;
63
64
        if ($x == false) {
65
            return null;
66
        }
67
68
        if (!is_scalar($this->driverUnwrapData($x)) && !is_null($this->driverUnwrapData($x))) {
69
            throw new PhpfastcacheDriverException('Hacking attempt: The decoding returned a non-scalar value, Cookie driver does not allow this.');
70
        }
71
72
        return $x;
73
    }
74
75
    /**
76
     * @param \Psr\Cache\CacheItemInterface $item
77
     * @return bool
78
     * @throws PhpfastcacheInvalidArgumentException
79
     */
80
    protected function driverWrite(CacheItemInterface $item): bool
81
    {
82
        /**
83
         * Check for Cross-Driver type confusion
84
         */
85
        if ($item instanceof Item) {
86
            $this->driverConnect();
87
            $keyword = self::PREFIX . $item->getKey();
88
            $v = \json_encode($this->driverPreWrap($item));
89
90
            if ($this->getConfig()->getLimitedMemoryByObject() !== null && \strlen($v) > $this->getConfig()->getLimitedMemoryByObject()) {
91
                return false;
92
            }
93
94
            return setcookie($keyword, $v, $item->getExpirationDate()->getTimestamp(), '/');
95
        }
96
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
97
    }
98
99
    /**
100
     * @param string $key
101
     * @return int
102
     */
103
    protected function driverReadExpirationDate($key): int
104
    {
105
        $this->driverConnect();
106
        $keyword = self::PREFIX . $key;
107
        $x = isset($_COOKIE[ $keyword ]) ? $this->decode(\json_decode($_COOKIE[ $keyword ])->t) : 0;
108
109
        return $x ? $x - \time() : $x;
110
    }
111
112
    /**
113
     * @param \Psr\Cache\CacheItemInterface $item
114
     * @return bool
115
     * @throws PhpfastcacheInvalidArgumentException
116
     */
117
    protected function driverDelete(CacheItemInterface $item)
118
    {
119
        /**
120
         * Check for Cross-Driver type confusion
121
         */
122
        if ($item instanceof Item) {
123
            $this->driverConnect();
124
            $keyword = self::PREFIX . $item->getKey();
125
            $_COOKIE[ $keyword ] = null;
126
127
            return @setcookie($keyword, null, -10);
128
        }
129
130
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
131
    }
132
133
    /**
134
     * @return bool
135
     */
136
    protected function driverClear(): bool
137
    {
138
        $return = null;
139
        $this->driverConnect();
140
        foreach ($_COOKIE as $keyword => $value) {
141
            if (\strpos($keyword, self::PREFIX) !== false) {
142
                $_COOKIE[ $keyword ] = null;
143
                $result = @setcookie($keyword, null, -10);
144
                if ($return !== false) {
145
                    $return = $result;
146
                }
147
            }
148
        }
149
150
        return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
151
    }
152
153
    /**
154
     * @inheritdoc
155
     */
156
    public static function isUsableInAutoContext(): bool
157
    {
158
        return false;
159
    }
160
161
    /********************
162
     *
163
     * PSR-6 Extended Methods
164
     *
165
     *******************/
166
167
    /**
168
     * @return DriverStatistic
169
     */
170
    public function getStats(): DriverStatistic
171
    {
172
        $size = 0;
173
        $stat = new DriverStatistic();
174
        $stat->setData($_COOKIE);
175
176
        /**
177
         * Only count PFC Cookie
178
         */
179
        foreach ($_COOKIE as $key => $value) {
180
            if (\strpos($key, self::PREFIX) === 0) {
181
                $size += \strlen($value);
182
            }
183
        }
184
185
        $stat->setSize($size);
186
187
        return $stat;
188
    }
189
}