Completed
Push — v7 ( 183c7c...c29e1f )
by Georges
02:11
created

Driver::driverConnect()   F

Complexity

Conditions 20
Paths 3036

Size

Total Lines 44
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 22
nc 3036
nop 0
dl 0
loc 44
rs 2.6863
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Memcache;
17
18
use Memcache as MemcacheSoftware;
19
use Phpfastcache\Config\ConfigurationOption;
20
use Phpfastcache\Core\Pool\{DriverBaseTrait, ExtendedCacheItemPoolInterface};
21
use Phpfastcache\Entities\DriverStatistic;
22
use Phpfastcache\Exceptions\{
23
  phpFastCacheInvalidArgumentException, phpFastCacheDriverException
24
};
25
use Phpfastcache\Util\{ArrayObject, MemcacheDriverCollisionDetectorTrait};
26
use Psr\Cache\CacheItemInterface;
27
28
/**
29
 * Class Driver
30
 * @package phpFastCache\Drivers
31
 * @property MemcacheSoftware $instance
32
 * @property Config $config Config object
33
 * @method Config getConfig() Return the config object
34
 */
35
class Driver implements ExtendedCacheItemPoolInterface
36
{
37
    use DriverBaseTrait {
38
        __construct as protected __parentConstruct;
39
    }
40
    use MemcacheDriverCollisionDetectorTrait;
41
42
    /**
43
     * @var int
44
     */
45
    protected $memcacheFlags = 0;
46
47
    /**
48
     * Driver constructor.
49
     * @param ConfigurationOption $config
50
     * @param string $instanceId
51
     * @throws phpFastCacheDriverException
52
     */
53
    public function __construct(ConfigurationOption $config, string $instanceId)
54
    {
55
        self::checkCollision('Memcache');
56
        $this->__parentConstruct($config, $instanceId);
57
    }
58
59
    /**
60
     * @return bool
61
     */
62
    public function driverCheck(): bool
63
    {
64
        return \class_exists('Memcache');
65
    }
66
67
    /**
68
     * @return bool
69
     */
70
    protected function driverConnect(): bool
71
    {
72
        $this->instance = new MemcacheSoftware();
73
        $servers = (!empty($this->config->getOption('servers')) && \is_array($this->config->getOption('servers')) ? $this->config->getOption('servers') : []);
74
        if (\count($servers) < 1) {
75
            $servers = [
76
              [
77
                'host' => !empty($this->config->getOption('host')) ? $this->config->getOption('host') : '127.0.0.1',
78
                'path' => !empty($this->config->getOption('path')) ? $this->config->getOption('path') : false,
79
                'port' => !empty($this->config->getOption('port')) ? $this->config->getOption('port') : 11211,
80
                'saslUser' => !empty($this->config->getOption('saslUser')) ? $this->config->getOption('saslUser') : false,
81
                'saslPassword' =>!empty($this->config->getOption('saslPassword')) ? $this->config->getOption('saslPassword'): false,
82
              ],
83
            ];
84
        }
85
86
        foreach ($servers as $server) {
87
            try {
88
                /**
89
                 * If path is provided we consider it as an UNIX Socket
90
                 */
91
                if(!empty($server[ 'path' ]) && !$this->instance->addServer($server[ 'path' ], 0)){
92
                    $this->fallback = true;
93
                }else if (!empty($server[ 'host' ]) && !$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
94
                    $this->fallback = true;
95
                }
96
97
                if (!empty($server[ 'saslUser' ]) && !empty($server[ 'saslPassword' ])) {
98
                    throw new phpFastCacheDriverException('Unlike Memcached, Memcache does not support SASL authentication');
99
                }
100
            } catch (\Exception $e) {
101
                $this->fallback = true;
102
            }
103
104
            /**
105
             * Since Memcached does not throw
106
             * any error if not connected ...
107
             */
108
            if(!$this->instance->getServerStatus(!empty($server[ 'path' ]) ? $server[ 'path' ] : $server[ 'host' ], !empty($server[ 'port' ]) ? $server[ 'port' ] : 0)){
109
                throw new phpFastCacheDriverException('Memcache seems to not be connected');
110
            }
111
        }
112
113
        return true;
114
    }
115
116
    /**
117
     * @param \Psr\Cache\CacheItemInterface $item
118
     * @return null|array
119
     */
120
    protected function driverRead(CacheItemInterface $item)
121
    {
122
        $val = $this->instance->get($item->getKey());
123
124
        if ($val === false) {
0 ignored issues
show
introduced by
The condition $val === false can never be true.
Loading history...
125
            return null;
126
        }
127
128
        return $val;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $val also could return the type string which is incompatible with the documented return type null|array.
Loading history...
129
    }
130
131
    /**
132
     * @param \Psr\Cache\CacheItemInterface $item
133
     * @return mixed
134
     * @throws phpFastCacheInvalidArgumentException
135
     */
136
    protected function driverWrite(CacheItemInterface $item): bool
137
    {
138
        /**
139
         * Check for Cross-Driver type confusion
140
         */
141
        if ($item instanceof Item) {
142
            $ttl = $item->getExpirationDate()->getTimestamp() - time();
143
144
            // Memcache will only allow a expiration timer less than 2592000 seconds,
145
            // otherwise, it will assume you're giving it a UNIX timestamp.
146
            if ($ttl > 2592000) {
147
                $ttl = time() + $ttl;
148
            }
149
            return $this->instance->set($item->getKey(), $this->driverPreWrap($item), $this->memcacheFlags, $ttl);
150
        }
151
152
        throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
153
    }
154
155
    /**
156
     * @param \Psr\Cache\CacheItemInterface $item
157
     * @return bool
158
     * @throws phpFastCacheInvalidArgumentException
159
     */
160
    protected function driverDelete(CacheItemInterface $item): bool
161
    {
162
        /**
163
         * Check for Cross-Driver type confusion
164
         */
165
        if ($item instanceof Item) {
166
            return $this->instance->delete($item->getKey());
167
        }
168
169
        throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
170
    }
171
172
    /**
173
     * @return bool
174
     */
175
    protected function driverClear(): bool
176
    {
177
        return $this->instance->flush();
178
    }
179
180
    /********************
181
     *
182
     * PSR-6 Extended Methods
183
     *
184
     *******************/
185
186
    /**
187
     * @return DriverStatistic
188
     */
189
    public function getStats(): DriverStatistic
190
    {
191
        $stats = (array)$this->instance->getstats();
192
        $stats[ 'uptime' ] = (isset($stats[ 'uptime' ]) ? $stats[ 'uptime' ] : 0);
193
        $stats[ 'version' ] = (isset($stats[ 'version' ]) ? $stats[ 'version' ] : 'UnknownVersion');
194
        $stats[ 'bytes' ] = (isset($stats[ 'bytes' ]) ? $stats[ 'version' ] : 0);
195
196
        $date = (new \DateTime())->setTimestamp(time() - $stats[ 'uptime' ]);
197
198
        return (new DriverStatistic())
199
          ->setData(\implode(', ', \array_keys($this->itemInstances)))
200
          ->setInfo(\sprintf("The memcache daemon v%s is up since %s.\n For more information see RawData.", $stats[ 'version' ], $date->format(DATE_RFC2822)))
201
          ->setRawData($stats)
202
          ->setSize((int)$stats[ 'bytes' ]);
203
    }
204
}