Completed
Push — master ( f2b737...934162 )
by Lars
02:06
created

CacheAdapterAutoManager::validateAdapter()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 5
cp 0.8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.032
1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\cache;
6
7
use voku\cache\Exception\InvalidArgumentException;
8
9
class CacheAdapterAutoManager
10
{
11
    /**
12
     * @var string[]
13
     */
14
    private $adapter = [];
15
16
    /**
17
     * @var callable[]|null[]
18
     */
19
    private $callableFunctions = [];
20
21
    /**
22
     * @param string        $adapter
23
     * @param callable|null $callableFunction
24
     *
25
     * @throws InvalidArgumentException
26
     *
27
     * @return $this
28
     */
29 18
    public function addAdapter(
30
        string $adapter,
31
        callable $callableFunction = null
32
    ): self
33
    {
34 18
        $this->validateAdapter($adapter);
35 18
        $this->validateCallable($callableFunction);
36
37 18
        $this->adapter[] = $adapter;
38 18
        $this->callableFunctions[] = $callableFunction;
39
40 18
        return $this;
41
    }
42
43
    /**
44
     * @return \Generator|\Generator<string, callable>
0 ignored issues
show
Documentation introduced by
The doc-type \Generator|\Generator<string, could not be parsed: Expected "|" or "end of type", but got "<" at position 21. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
45
     */
46 1
    public function getAdapters(): \Generator
47
    {
48 1
        foreach ($this->adapter as $key => $value) {
49 1
            yield $this->adapter[$key] => $this->callableFunctions[$key];
50
        }
51
    }
52
53
    /**
54
     * @param self $adapterManager
55
     *
56
     * @throws InvalidArgumentException
57
     *
58
     * @return CacheAdapterAutoManager
59
     */
60
    public function merge(self $adapterManager): self
61
    {
62
        foreach ($adapterManager->getAdapters() as $adapterTmp => $callableFunctionTmp) {
63
            $this->validateAdapter($adapterTmp);
64
            $this->validateCallable($callableFunctionTmp);
65
66
            $key = \array_search($adapterTmp, $this->adapter, true);
67
68
            if ($key) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $key of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
69
                $this->adapter[$key] = $adapterTmp;
70
                $this->callableFunctions[$key] = $callableFunctionTmp;
71
            } else {
72
                $this->adapter[] = $adapterTmp;
73
                $this->callableFunctions[] = $callableFunctionTmp;
74
            }
75
        }
76
77
        return $this;
78
    }
79
80
    /**
81
     * @param string $replaceAdapter
82
     *
83
     * @throws InvalidArgumentException
84
     */
85 18
    private function validateAdapter(string $replaceAdapter)
86
    {
87
        /** @noinspection PhpUnhandledExceptionInspection */
88 18
        $interfaces = (new \ReflectionClass($replaceAdapter))->getInterfaces();
89 18
        if (!\array_key_exists(iAdapter::class, $interfaces)) {
90
            throw new InvalidArgumentException('"' . $replaceAdapter . '" did not implement the "iAdapter"-interface [' . \print_r($interfaces, true) . ']');
91
        }
92 18
    }
93
94
    /**
95
     * @param callable $callableFunction
96
     *
97
     * @throws InvalidArgumentException
98
     */
99 18
    private function validateCallable(callable $callableFunction = null)
100
    {
101
        if (
102 18
            $callableFunction !== null
103
            &&
104 18
            !\is_callable($callableFunction)
105
        ) {
106
            throw new InvalidArgumentException('$callableFunction is not callable');
107
        }
108 18
    }
109
110
    /**
111
     * @return CacheAdapterAutoManager
112
     */
113 1
    public static function getDefaultsForAutoInit(): self
114
    {
115 1
        $cacheAdapterManager = new self();
116
117
        /** @noinspection PhpUnhandledExceptionInspection */
118 1
        $cacheAdapterManager->addAdapter(
119 1
            AdapterMemcached::class,
120 1
            static function () {
121
                $memcached = null;
122
                $isMemcachedAvailable = false;
123
                if (\extension_loaded('memcached')) {
124
                    /** @noinspection PhpComposerExtensionStubsInspection */
125
                    $memcached = new \Memcached();
126
                    /** @noinspection PhpUsageOfSilenceOperatorInspection */
127
                    $isMemcachedAvailable = @$memcached->addServer('127.0.0.1', 11211);
128
                }
129
130
                if (!$isMemcachedAvailable) {
131
                    $memcached = null;
132
                }
133
134
                return $memcached;
135 1
            }
136
        );
137
138
        /** @noinspection PhpUnhandledExceptionInspection */
139 1
        $cacheAdapterManager->addAdapter(
140 1
            AdapterMemcache::class,
141 1
            static function () {
142
                $memcache = null;
143
                $isMemcacheAvailable = false;
144
                /** @noinspection ClassConstantCanBeUsedInspection */
145
                if (\class_exists('\Memcache')) {
146
                    /** @noinspection PhpComposerExtensionStubsInspection */
147
                    $memcache = new \Memcache();
148
                    /** @noinspection PhpUsageOfSilenceOperatorInspection */
149
                    $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
150
                }
151
152
                if (!$isMemcacheAvailable) {
153
                    $memcache = null;
154
                }
155
156
                return $memcache;
157 1
            }
158
        );
159
160
        /** @noinspection PhpUnhandledExceptionInspection */
161 1
        $cacheAdapterManager->addAdapter(
162 1
            AdapterPredis::class,
163 1
            static function () {
164
                $redis = null;
165
                $isRedisAvailable = false;
166
                if (
167
                    \extension_loaded('redis')
168
                    &&
169
                    \class_exists('\Predis\Client')
170
                ) {
171
                    /** @noinspection PhpUndefinedNamespaceInspection */
172
                    /** @noinspection PhpUndefinedClassInspection */
173
                    $redis = new \Predis\Client(
174
                        [
175
                            'scheme'  => 'tcp',
176
                            'host'    => '127.0.0.1',
177
                            'port'    => 6379,
178
                            'timeout' => '2.0',
179
                        ]
180
                    );
181
182
                    try {
183
                        /** @noinspection PhpUndefinedMethodInspection */
184
                        $redis->connect();
185
                        /** @noinspection PhpUndefinedMethodInspection */
186
                        $isRedisAvailable = $redis->getConnection()->isConnected();
187
                    } catch (\Exception $e) {
188
                        // nothing
189
                    }
190
                }
191
192
                if ($isRedisAvailable === false) {
193
                    $redis = null;
194
                }
195
196
                return $redis;
197 1
            }
198
        );
199
200
        /** @noinspection PhpUnhandledExceptionInspection */
201 1
        $cacheAdapterManager->addAdapter(
202 1
            AdapterXcache::class
203
        );
204
205
        /** @noinspection PhpUnhandledExceptionInspection */
206 1
        $cacheAdapterManager->addAdapter(
207 1
            AdapterApcu::class
208
        );
209
210
        /** @noinspection PhpUnhandledExceptionInspection */
211 1
        $cacheAdapterManager->addAdapter(
212 1
            AdapterApc::class
213
        );
214
215
        /** @noinspection PhpUnhandledExceptionInspection */
216 1
        $cacheAdapterManager->addAdapter(
217 1
            AdapterOpCache::class,
218 1
            static function () {
219
                return \realpath(\sys_get_temp_dir()) . '/simple_php_cache';
220 1
            }
221
        );
222
223
        /** @noinspection PhpUnhandledExceptionInspection */
224 1
        $cacheAdapterManager->addAdapter(
225 1
            AdapterArray::class
226
        );
227
228 1
        return $cacheAdapterManager;
229
    }
230
}
231