Completed
Pull Request — final (#566)
by Georges
02:39
created

Driver::driverConnect()   F

Complexity

Conditions 19
Paths 240

Size

Total Lines 47
Code Lines 25

Duplication

Lines 16
Ratio 34.04 %

Importance

Changes 0
Metric Value
dl 16
loc 47
rs 3.8176
c 0
b 0
f 0
cc 19
eloc 25
nc 240
nop 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
15
namespace phpFastCache\Drivers\Memcached;
16
17
use Memcached as MemcachedSoftware;
18
use phpFastCache\Core\Pool\DriverBaseTrait;
19
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
20
use phpFastCache\Entities\DriverStatistic;
21
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
22
use phpFastCache\Exceptions\phpFastCacheDriverException;
23
use phpFastCache\Exceptions\phpFastCacheInvalidArgumentException;
24
use phpFastCache\Util\MemcacheDriverCollisionDetectorTrait;
25
use Psr\Cache\CacheItemInterface;
26
27
/**
28
 * Class Driver
29
 * @package phpFastCache\Drivers
30
 * @property MemcachedSoftware $instance
31
 */
32
class Driver implements ExtendedCacheItemPoolInterface
33
{
34
    use DriverBaseTrait, MemcacheDriverCollisionDetectorTrait;
35
36
    /**
37
     * Driver constructor.
38
     * @param array $config
39
     * @throws phpFastCacheDriverException
40
     */
41 View Code Duplication
    public function __construct(array $config = [])
42
    {
43
        self::checkCollision('Memcached');
44
        $this->setup($config);
45
46
        if (!$this->driverCheck()) {
47
            throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
48
        } else {
49
            $this->driverConnect();
50
        }
51
    }
52
53
    /**
54
     * @return bool
55
     */
56
    public function driverCheck()
57
    {
58
        return class_exists('Memcached');
59
    }
60
61
    /**
62
     * @param \Psr\Cache\CacheItemInterface $item
63
     * @return mixed
64
     * @throws phpFastCacheInvalidArgumentException
65
     */
66 View Code Duplication
    protected function driverWrite(CacheItemInterface $item)
67
    {
68
        /**
69
         * Check for Cross-Driver type confusion
70
         */
71
        if ($item instanceof Item) {
72
            $ttl = $item->getTtl();
73
74
            // Memcache will only allow a expiration timer less than 2592000 seconds,
75
            // otherwise, it will assume you're giving it a UNIX timestamp.
76
            if ($ttl >= 2592000) {
77
                $ttl = $item->getExpirationDate()->getTimestamp();
78
            }
79
80
            return $this->instance->set($item->getKey(), $this->driverPreWrap($item), $ttl);
81
        } else {
82
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
83
        }
84
85
        return true;
0 ignored issues
show
Unused Code introduced by
return true; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
86
    }
87
88
    /**
89
     * @param \Psr\Cache\CacheItemInterface $item
90
     * @return null|array
91
     */
92 View Code Duplication
    protected function driverRead(CacheItemInterface $item)
93
    {
94
        $val = $this->instance->get($item->getKey());
95
96
        if ($val === false) {
97
            return null;
98
        } else {
99
            return $val;
100
        }
101
    }
102
103
    /**
104
     * @param \Psr\Cache\CacheItemInterface $item
105
     * @return bool
106
     * @throws phpFastCacheInvalidArgumentException
107
     */
108 View Code Duplication
    protected function driverDelete(CacheItemInterface $item)
109
    {
110
        /**
111
         * Check for Cross-Driver type confusion
112
         */
113
        if ($item instanceof Item) {
114
            return $this->instance->delete($item->getKey());
115
        } else {
116
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
117
        }
118
    }
119
120
    /**
121
     * @return bool
122
     */
123
    protected function driverClear()
124
    {
125
        return $this->instance->flush();
126
    }
127
128
    /**
129
     * @return bool
130
     */
131
    protected function driverConnect()
132
    {
133
        $this->instance = new MemcachedSoftware();
134
        $this->instance->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
135
        $servers = (!empty($this->config[ 'servers' ]) && is_array($this->config[ 'servers' ]) ? $this->config[ 'servers' ] : []);
136 View Code Duplication
        if (count($servers) < 1) {
137
            $servers = [
138
              [
139
                'host' => !empty($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1',
140
                'path' => !empty($this->config[ 'path' ]) ? $this->config[ 'path' ] : false,
141
                'port' => !empty($this->config[ 'port' ]) ? $this->config[ 'port' ] : 11211,
142
                'sasl_user' => !empty($this->config[ 'sasl_user' ]) ? $this->config[ 'sasl_user' ] : false,
143
                'sasl_password' =>!empty($this->config[ 'sasl_password' ]) ? $this->config[ 'sasl_password' ]: false,
144
              ],
145
            ];
146
        }
147
148
        foreach ($servers as $server) {
149
            try {
150
                /**
151
                 * If path is provided we consider it as an UNIX Socket
152
                 */
153 View Code Duplication
                if(!empty($server[ 'path' ]) && !$this->instance->addServer($server[ 'path' ], 0)){
154
                    $this->fallback = true;
155
                }else if (!empty($server[ 'host' ]) && !$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
156
                    $this->fallback = true;
157
                }
158
159
                if (!empty($server[ 'sasl_user' ]) && !empty($server[ 'sasl_password' ])) {
160
                    $this->instance->setSaslAuthData($server[ 'sasl_user' ], $server[ 'sasl_password' ]);
161
                }
162
163
            } catch (\Exception $e) {
164
                $this->fallback = true;
165
            }
166
        }
167
168
        /**
169
         * Since Memcached does not throw
170
         * any error if not connected ...
171
         */
172
        $version = $this->instance->getVersion();
173
        if(!$version || $this->instance->getResultCode() !== MemcachedSoftware::RES_SUCCESS){
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
174
            throw new phpFastCacheDriverException('Memcached seems to not be connected');
175
        }
176
        return true;
177
    }
178
179
    /********************
180
     *
181
     * PSR-6 Extended Methods
182
     *
183
     *******************/
184
185
    /**
186
     * @return DriverStatistic
187
     */
188 View Code Duplication
    public function getStats()
189
    {
190
        $stats = current($this->instance->getStats());
191
        $stats[ 'uptime' ] = (isset($stats[ 'uptime' ]) ? $stats[ 'uptime' ] : 0);
192
        $stats[ 'version' ] = (isset($stats[ 'version' ]) ? $stats[ 'version' ] : $this->instance->getVersion());
193
        $stats[ 'bytes' ] = (isset($stats[ 'bytes' ]) ? $stats[ 'version' ] : 0);
194
195
        $date = (new \DateTime())->setTimestamp(time() - $stats[ 'uptime' ]);
196
197
        return (new DriverStatistic())
198
          ->setData(implode(', ', array_keys($this->itemInstances)))
199
          ->setInfo(sprintf("The memcache daemon v%s is up since %s.\n For more information see RawData.", $stats[ 'version' ], $date->format(DATE_RFC2822)))
200
          ->setRawData($stats)
201
          ->setSize($stats[ 'bytes' ]);
202
    }
203
}