Passed
Push — master ( 4006b8...c871f9 )
by Georges
02:32 queued 21s
created

Driver::getConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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 and LICENCE files.
10
 *
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 * @author Contributors  https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
13
 */
14
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Drivers\Predis;
18
19
use DateTime;
20
use Phpfastcache\Cluster\AggregatablePoolInterface;
21
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
22
use Phpfastcache\Core\Pool\TaggableCacheItemPoolTrait;
23
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
24
use Phpfastcache\Entities\DriverStatistic;
25
use Phpfastcache\Exceptions\PhpfastcacheDriverException;
26
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
27
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
28
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...
29
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...
30
31
/**
32
 * @property PredisClient $instance Instance of driver service
33
 * @method Config getConfig()
34
 */
35
class Driver implements ExtendedCacheItemPoolInterface, AggregatablePoolInterface
36
{
37
    use TaggableCacheItemPoolTrait;
38
39
    /**
40
     * @return bool
41
     */
42
    public function driverCheck(): bool
43
    {
44
        if (extension_loaded('Redis')) {
45
            trigger_error('The native Redis extension is installed, you should use Redis instead of Predis to increase performances', E_USER_NOTICE);
46
        }
47
48
        return class_exists(\Predis\Client::class);
49
    }
50
51
    /**
52
     * @return string
53
     */
54
    public function getHelp(): string
55
    {
56
        return <<<HELP
57
<p>
58
To install the Predis library via Composer:
59
<code>composer require "predis/predis" "~1.1.0"</code>
60
</p>
61
HELP;
62
    }
63
64
    /**
65
     * @return DriverStatistic
66
     */
67
    public function getStats(): DriverStatistic
68
    {
69
        $info = $this->instance->info();
70
        $size = (isset($info['Memory']['used_memory']) ? $info['Memory']['used_memory'] : 0);
71
        $version = (isset($info['Server']['redis_version']) ? $info['Server']['redis_version'] : 0);
72
        $date = (isset($info['Server']['uptime_in_seconds']) ? (new DateTime())->setTimestamp(time() - $info['Server']['uptime_in_seconds']) : 'unknown date');
73
74
        return (new DriverStatistic())
75
            ->setData(implode(', ', array_keys($this->itemInstances)))
76
            ->setRawData($info)
77
            ->setSize((int)$size)
78
            ->setInfo(
79
                sprintf(
80
                    "The Redis daemon v%s is up since %s.\n For more information see RawData. \n Driver size includes the memory allocation size.",
81
                    $version,
82
                    $date->format(DATE_RFC2822)
83
                )
84
            );
85
    }
86
87
    /**
88
     * @return bool
89
     * @throws PhpfastcacheDriverException
90
     * @throws PhpfastcacheLogicException
91
     */
92
    protected function driverConnect(): bool
93
    {
94
        /**
95
         * In case of an user-provided
96
         * Predis client just return here
97
         */
98
        if ($this->getConfig()->getPredisClient() instanceof PredisClient) {
99
            $this->instance = $this->getConfig()->getPredisClient();
100
            if (!$this->instance->isConnected()) {
101
                $this->instance->connect();
102
            }
103
            return true;
104
        }
105
106
        $options = [];
107
108
        if ($this->getConfig()->getOptPrefix()) {
109
            $options['prefix'] = $this->getConfig()->getOptPrefix();
110
        }
111
112
        if (!empty($this->getConfig()->getPath())) {
113
            $this->instance = new PredisClient(
114
                [
115
                    'scheme' => $this->getConfig()->getScheme(),
116
                    'persistent' => $this->getConfig()->isPersistent(),
117
                    'timeout' => $this->getConfig()->getTimeout(),
118
                    'path' => $this->getConfig()->getPath(),
119
                ],
120
                $options
121
            );
122
        } else {
123
            $this->instance = new PredisClient($this->getConfig()->getPredisConfigArray(), $options);
124
        }
125
126
        try {
127
            $this->instance->connect();
128
        } catch (PredisConnectionException $e) {
129
            throw new PhpfastcacheDriverException(
130
                'Failed to connect to predis server. Check the Predis documentation: https://github.com/nrk/predis/tree/v1.1#how-to-install-and-use-predis',
131
                0,
132
                $e
133
            );
134
        }
135
136
        return true;
137
    }
138
139
    /**
140
     * @param ExtendedCacheItemInterface $item
141
     * @return null|array
142
     */
143
    protected function driverRead(ExtendedCacheItemInterface $item): ?array
144
    {
145
        $val = $this->instance->get($item->getKey());
146
        if ($val == false) {
147
            return null;
148
        }
149
150
        return $this->decode($val);
151
    }
152
153
    /**
154
     * @param ExtendedCacheItemInterface $item
155
     * @return mixed
156
     * @throws PhpfastcacheInvalidArgumentException
157
     * @throws PhpfastcacheLogicException
158
     */
159
    protected function driverWrite(ExtendedCacheItemInterface $item): bool
160
    {
161
        $this->assertCacheItemType($item, Item::class);
162
163
        $ttl = $item->getExpirationDate()->getTimestamp() - time();
164
165
        /**
166
         * @see https://redis.io/commands/setex
167
         * @see https://redis.io/commands/expire
168
         */
169
        if ($ttl <= 0) {
170
            return (bool)$this->instance->expire($item->getKey(), 0);
171
        }
172
173
        return $this->instance->setex($item->getKey(), $ttl, $this->encode($this->driverPreWrap($item)))->getPayload() === 'OK';
174
    }
175
176
    /**
177
     * @param ExtendedCacheItemInterface $item
178
     * @return bool
179
     * @throws PhpfastcacheInvalidArgumentException
180
     */
181
    protected function driverDelete(ExtendedCacheItemInterface $item): bool
182
    {
183
        $this->assertCacheItemType($item, Item::class);
184
185
        return (bool)$this->instance->del([$item->getKey()]);
186
    }
187
188
    /**
189
     * @return bool
190
     */
191
    protected function driverClear(): bool
192
    {
193
        return $this->instance->flushdb()->getPayload() === 'OK';
194
    }
195
}
196