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

Driver::driverCheck()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 *
5
 * This file is part of phpFastCache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt file.
10
 *
11
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
12
 * @author Georges.L (Geolim4)  <[email protected]>
13
 *
14
 */
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Drivers\Predis;
18
19
use Phpfastcache\Core\Pool\{DriverBaseTrait, ExtendedCacheItemPoolInterface};
20
use Phpfastcache\Entities\DriverStatistic;
21
use Phpfastcache\Exceptions\{
22
  PhpfastcacheInvalidArgumentException, PhpfastcacheDriverException, PhpfastcacheLogicException
23
};
24
use Phpfastcache\Util\ArrayObject;
25
use Predis\Client as PredisClient;
0 ignored issues
show
Bug introduced by
The type Predis\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use Predis\Connection\ConnectionException as PredisConnectionException;
0 ignored issues
show
Bug introduced by
The type Predis\Connection\ConnectionException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Psr\Cache\CacheItemInterface;
28
29
/**
30
 * Class Driver
31
 * @package phpFastCache\Drivers
32
 * @property PredisClient $instance Instance of driver service
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
        if (extension_loaded('Redis')) {
46
            \trigger_error('The native Redis extension is installed, you should use Redis instead of Predis to increase performances', E_USER_NOTICE);
47
        }
48
49
        return \class_exists('Predis\Client');
50
    }
51
52
    /**
53
     * @return bool
54
     * @throws PhpfastcacheDriverException
55
     * @throws PhpfastcacheLogicException
56
     */
57
    protected function driverConnect(): bool
58
    {
59
        if ($this->instance instanceof PredisClient) {
60
            throw new PhpfastcacheLogicException('Already connected to Predis server');
61
        }
62
63
        /**
64
         * In case of an user-provided
65
         * Predis client just return here
66
         */
67
        if($this->getConfig()->getPredisClient() instanceof PredisClient){
68
            $this->instance = $this->getConfig()->getPredisClient();
69
            if(!$this->instance->isConnected()){
70
                $this->instance->connect();
71
            }
72
            return true;
73
        }
74
75
        if(!empty($this->getConfig()->getPath())){
76
            $this->instance = new PredisClient([
77
              'scheme' => 'unix',
78
              'path' =>  $this->getConfig()->getPath()
79
            ]);
80
        }else{
81
            $this->instance = new PredisClient($this->getConfig()->getPredisConfigArray());
82
        }
83
84
        try {
85
            $this->instance->connect();
86
        } catch (PredisConnectionException $e) {
87
            echo $e->getMessage();
88
            throw new PhpfastcacheDriverException('Failed to connect to predis server. Check the Predis documentation: https://github.com/nrk/predis/tree/v1.1#how-to-install-and-use-predis', 0, $e);
89
        }
90
91
        return true;
92
    }
93
94
    /**
95
     * @param \Psr\Cache\CacheItemInterface $item
96
     * @return null|array
97
     */
98
    protected function driverRead(CacheItemInterface $item)
99
    {
100
        $val = $this->instance->get($item->getKey());
101
        if ($val == false) {
102
            return null;
103
        }
104
105
        return $this->decode($val);
106
    }
107
108
    /**
109
     * @param \Psr\Cache\CacheItemInterface $item
110
     * @return mixed
111
     * @throws PhpfastcacheInvalidArgumentException
112
     */
113
    protected function driverWrite(CacheItemInterface $item): bool
114
    {
115
        /**
116
         * Check for Cross-Driver type confusion
117
         */
118
        if ($item instanceof Item) {
119
            $ttl = $item->getExpirationDate()->getTimestamp() - \time();
120
121
            /**
122
             * @see https://redis.io/commands/setex
123
             * @see https://redis.io/commands/expire
124
             */
125
            if ($ttl <= 0) {
126
                return (bool)$this->instance->expire($item->getKey(), 0);
127
            }
128
129
            return $this->instance->setex($item->getKey(), $ttl, $this->encode($this->driverPreWrap($item)))->getPayload() === 'OK';
130
        }
131
132
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
133
    }
134
135
    /**
136
     * @param \Psr\Cache\CacheItemInterface $item
137
     * @return bool
138
     * @throws PhpfastcacheInvalidArgumentException
139
     */
140
    protected function driverDelete(CacheItemInterface $item): bool
141
    {
142
        /**
143
         * Check for Cross-Driver type confusion
144
         */
145
        if ($item instanceof Item) {
146
            return (bool) $this->instance->del([$item->getKey()]);
147
        }
148
149
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
150
    }
151
152
    /**
153
     * @return bool
154
     */
155
    protected function driverClear(): bool
156
    {
157
        return $this->instance->flushdb()->getPayload() === 'OK';
158
    }
159
160
    /********************
161
     *
162
     * PSR-6 Extended Methods
163
     *
164
     *******************/
165
166
167
    /**
168
     * @return string
169
     */
170
    public function getHelp(): string
171
    {
172
        return <<<HELP
173
<p>
174
To install the Predis library via Composer:
175
<code>composer require "predis/predis" "~1.1.0"</code>
176
</p>
177
HELP;
178
    }
179
180
    /**
181
     * @return DriverStatistic
182
     */
183
    public function getStats(): DriverStatistic
184
    {
185
        $info = $this->instance->info();
186
        $size = (isset($info[ 'Memory' ][ 'used_memory' ]) ? $info[ 'Memory' ][ 'used_memory' ] : 0);
187
        $version = (isset($info[ 'Server' ][ 'redis_version' ]) ? $info[ 'Server' ][ 'redis_version' ] : 0);
188
        $date = (isset($info[ 'Server' ][ 'uptime_in_seconds' ]) ? (new \DateTime())->setTimestamp(\time() - $info[ 'Server' ][ 'uptime_in_seconds' ]) : 'unknown date');
189
190
        return (new DriverStatistic())
191
          ->setData(\implode(', ', \array_keys($this->itemInstances)))
192
          ->setRawData($info)
193
          ->setSize((int) $size)
194
          ->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.",
195
            $version, $date->format(DATE_RFC2822)));
196
    }
197
}