Passed
Push — v7 ( 8c8f4f...b7a561 )
by Georges
01:55
created

Driver   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 149
rs 10
c 0
b 0
f 0
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A driverCheck() 0 3 1
A driverRead() 0 8 2
A driverClear() 0 3 1
A driverDelete() 0 10 2
A driverWrite() 0 20 3
C driverConnect() 0 44 11
A getStats() 0 12 1
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\Redis;
17
18
use Phpfastcache\Config\ConfigurationOption;
19
use Phpfastcache\Core\Pool\{
20
  DriverBaseTrait, ExtendedCacheItemPoolInterface
21
};
22
use Phpfastcache\Entities\DriverStatistic;
23
use Phpfastcache\Exceptions\{
24
  PhpfastcacheInvalidArgumentException, PhpfastcacheLogicException
25
};
26
use Phpfastcache\Util\ArrayObject;
27
use Psr\Cache\CacheItemInterface;
28
use Redis as RedisClient;
29
30
/**
31
 * Class Driver
32
 * @package phpFastCache\Drivers
33
 * @property Config $config Config object
34
 * @method Config getConfig() Return the config object
35
 */
36
class Driver implements ExtendedCacheItemPoolInterface
37
{
38
    use DriverBaseTrait;
39
40
    /**
41
     * @return bool
42
     */
43
    public function driverCheck(): bool
44
    {
45
        return \extension_loaded('Redis');
46
    }
47
48
    /**
49
     * @return bool
50
     * @throws PhpfastcacheLogicException
51
     */
52
    protected function driverConnect(): bool
53
    {
54
        if ($this->instance instanceof RedisClient) {
55
            throw new PhpfastcacheLogicException('Already connected to Redis server');
56
        }
57
58
        /**
59
         * In case of an user-provided
60
         * Redis client just return here
61
         */
62
        if($this->getConfig()->getRedisClient() instanceof RedisClient){
0 ignored issues
show
introduced by
$this->getConfig()->getRedisClient() is always a sub-type of Redis.
Loading history...
63
            /**
64
             * Unlike Predis, we can't test if we're are connected
65
             * or not, so let's just assume that we are
66
             */
67
            $this->instance = $this->getConfig()->getRedisClient();
68
            return true;
69
        }
70
71
        $this->instance = $this->instance ?: new RedisClient();
72
73
        /**
74
         * If path is provided we consider it as an UNIX Socket
75
         */
76
        if ($this->getConfig()->getPath()) {
77
            $isConnected = $this->instance->connect($this->getConfig()->getPath());
78
        } else {
79
            $isConnected = $this->instance->connect($this->getConfig()->getHost(), $this->getConfig()->getPort(), $this->getConfig()->getTimeout());
80
        }
81
82
        if (!$isConnected && $this->getConfig()->getPath()) {
83
            return false;
84
        }
85
86
        if (!$this->getConfig()->getPath()) {
87
            if ($this->getConfig()->getPassword() && !$this->instance->auth($this->getConfig()->getPassword())) {
88
                return false;
89
            }
90
        }
91
92
        if ($this->getConfig()->getDatabase() !== null) {
93
            $this->instance->select($this->getConfig()->getDatabase());
94
        }
95
        return true;
96
    }
97
98
    /**
99
     * @param \Psr\Cache\CacheItemInterface $item
100
     * @return null|array
101
     */
102
    protected function driverRead(CacheItemInterface $item)
103
    {
104
        $val = $this->instance->get($item->getKey());
105
        if ($val == false) {
106
            return null;
107
        }
108
109
        return $this->decode($val);
110
    }
111
112
    /**
113
     * @param \Psr\Cache\CacheItemInterface $item
114
     * @return mixed
115
     * @throws PhpfastcacheInvalidArgumentException
116
     */
117
    protected function driverWrite(CacheItemInterface $item): bool
118
    {
119
        /**
120
         * Check for Cross-Driver type confusion
121
         */
122
        if ($item instanceof Item) {
123
            $ttl = $item->getExpirationDate()->getTimestamp() - \time();
124
125
            /**
126
             * @see https://redis.io/commands/setex
127
             * @see https://redis.io/commands/expire
128
             */
129
            if ($ttl <= 0) {
130
                return $this->instance->expire($item->getKey(), 0);
131
            }
132
133
            return $this->instance->setex($item->getKey(), $ttl, $this->encode($this->driverPreWrap($item)));
134
        }
135
136
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
137
    }
138
139
    /**
140
     * @param \Psr\Cache\CacheItemInterface $item
141
     * @return bool
142
     * @throws PhpfastcacheInvalidArgumentException
143
     */
144
    protected function driverDelete(CacheItemInterface $item): bool
145
    {
146
        /**
147
         * Check for Cross-Driver type confusion
148
         */
149
        if ($item instanceof Item) {
150
            return (bool)$this->instance->del($item->getKey());
151
        }
152
153
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
154
    }
155
156
    /**
157
     * @return bool
158
     */
159
    protected function driverClear(): bool
160
    {
161
        return $this->instance->flushDB();
162
    }
163
164
    /********************
165
     *
166
     * PSR-6 Extended Methods
167
     *
168
     *******************/
169
170
    /**
171
     * @return DriverStatistic
172
     */
173
    public function getStats(): DriverStatistic
174
    {
175
        // used_memory
176
        $info = $this->instance->info();
177
        $date = (new \DateTime())->setTimestamp(\time() - $info[ 'uptime_in_seconds' ]);
178
179
        return (new DriverStatistic())
180
          ->setData(\implode(', ', \array_keys($this->itemInstances)))
181
          ->setRawData($info)
182
          ->setSize((int)$info[ 'used_memory' ])
183
          ->setInfo(\sprintf("The Redis daemon v%s is up since %s.\n For more information see RawData. \n Driver size includes the memory allocation size.",
184
            $info[ 'redis_version' ], $date->format(DATE_RFC2822)));
185
    }
186
}