Passed
Push — v7 ( ba093b...24d66b )
by Georges
02:14
created

Driver::getStats()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 8
nop 0
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
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 = $this->getConfig()->getServers();
74
75
        if (\count($servers) < 1) {
76
            $servers = [
77
              [
78
                'host' => $this->getConfig()->getHost(),
79
                'path' => $this->getConfig()->getPath(),
80
                'port' => $this->getConfig()->getPort(),
81
                'saslUser' => $this->getConfig()->getSaslUser() ?: false,
82
                'saslPassword' => $this->getConfig()->getSaslPassword() ?: false,
83
              ],
84
            ];
85
        }
86
87
        foreach ($servers as $server) {
88
            try {
89
                /**
90
                 * If path is provided we consider it as an UNIX Socket
91
                 */
92
                if(!empty($server[ 'path' ]) && !$this->instance->addServer($server[ 'path' ], 0)){
93
                    $this->fallback = true;
94
                }else if (!empty($server[ 'host' ]) && !$this->instance->addServer($server[ 'host' ], $server[ 'port' ])) {
95
                    $this->fallback = true;
96
                }
97
98
                if (!empty($server[ 'saslUser' ]) && !empty($server[ 'saslPassword' ])) {
99
                    throw new PhpfastcacheDriverException('Unlike Memcached, Memcache does not support SASL authentication');
100
                }
101
            } catch (\Exception $e) {
102
                $this->fallback = true;
103
            }
104
105
            /**
106
             * Since Memcached does not throw
107
             * any error if not connected ...
108
             */
109
            if(!$this->instance->getServerStatus(!empty($server[ 'path' ]) ? $server[ 'path' ] : $server[ 'host' ], !empty($server[ 'port' ]) ? $server[ 'port' ] : 0)){
110
                throw new PhpfastcacheDriverException('Memcache seems to not be connected');
111
            }
112
        }
113
114
        return true;
115
    }
116
117
    /**
118
     * @param \Psr\Cache\CacheItemInterface $item
119
     * @return null|array
120
     */
121
    protected function driverRead(CacheItemInterface $item)
122
    {
123
        $val = $this->instance->get($item->getKey());
124
125
        if ($val === false) {
126
            return null;
127
        }
128
129
        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...
130
    }
131
132
    /**
133
     * @param \Psr\Cache\CacheItemInterface $item
134
     * @return mixed
135
     * @throws PhpfastcacheInvalidArgumentException
136
     */
137
    protected function driverWrite(CacheItemInterface $item): bool
138
    {
139
        /**
140
         * Check for Cross-Driver type confusion
141
         */
142
        if ($item instanceof Item) {
143
            $ttl = $item->getExpirationDate()->getTimestamp() - \time();
144
145
            // Memcache will only allow a expiration timer less than 2592000 seconds,
146
            // otherwise, it will assume you're giving it a UNIX timestamp.
147
            if ($ttl > 2592000) {
148
                $ttl = \time() + $ttl;
149
            }
150
            return $this->instance->set($item->getKey(), $this->driverPreWrap($item), $this->memcacheFlags, $ttl);
151
        }
152
153
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
154
    }
155
156
    /**
157
     * @param \Psr\Cache\CacheItemInterface $item
158
     * @return bool
159
     * @throws PhpfastcacheInvalidArgumentException
160
     */
161
    protected function driverDelete(CacheItemInterface $item): bool
162
    {
163
        /**
164
         * Check for Cross-Driver type confusion
165
         */
166
        if ($item instanceof Item) {
167
            return $this->instance->delete($item->getKey());
168
        }
169
170
        throw new PhpfastcacheInvalidArgumentException('Cross-Driver type confusion detected');
171
    }
172
173
    /**
174
     * @return bool
175
     */
176
    protected function driverClear(): bool
177
    {
178
        return $this->instance->flush();
179
    }
180
181
    /********************
182
     *
183
     * PSR-6 Extended Methods
184
     *
185
     *******************/
186
187
    /**
188
     * @return DriverStatistic
189
     */
190
    public function getStats(): DriverStatistic
191
    {
192
        $stats = (array)$this->instance->getstats();
193
        $stats[ 'uptime' ] = (isset($stats[ 'uptime' ]) ? $stats[ 'uptime' ] : 0);
194
        $stats[ 'version' ] = (isset($stats[ 'version' ]) ? $stats[ 'version' ] : 'UnknownVersion');
195
        $stats[ 'bytes' ] = (isset($stats[ 'bytes' ]) ? $stats[ 'version' ] : 0);
196
197
        $date = (new \DateTime())->setTimestamp(\time() - $stats[ 'uptime' ]);
198
199
        return (new DriverStatistic())
200
          ->setData(\implode(', ', \array_keys($this->itemInstances)))
201
          ->setInfo(\sprintf("The memcache daemon v%s is up since %s.\n For more information see RawData.", $stats[ 'version' ], $date->format(DATE_RFC2822)))
202
          ->setRawData($stats)
203
          ->setSize((int)$stats[ 'bytes' ]);
204
    }
205
}