Completed
Push — master ( 5621e4...94f5e8 )
by Lars
16:34
created

CacheAdapterAutoManager::getAdapters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 4
cp 0.75
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2.0625
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 18
        $this->validateAdapter($adapter);
34 18
        $this->validateCallable($callableFunction);
35
36 18
        $this->adapter[] = $adapter;
37 18
        $this->callableFunctions[] = $callableFunction;
38
39 18
        return $this;
40
    }
41
42
    /**
43
     * @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...
44
     */
45 1
    public function getAdapters(): \Generator
46
    {
47 1
        foreach ($this->adapter as $key => $value) {
48 1
            yield $this->adapter[$key] => $this->callableFunctions[$key];
49
        }
50
    }
51
52
    /**
53
     * @param self $adapterManager
54
     *
55
     * @throws InvalidArgumentException
56
     *
57
     * @return self
58
     */
59
    public function merge(self $adapterManager): self
60
    {
61
        foreach ($adapterManager->getAdapters() as $adapterTmp => $callableFunctionTmp) {
62
            $this->validateAdapter($adapterTmp);
63
            $this->validateCallable($callableFunctionTmp);
64
65
            $key = \array_search($adapterTmp, $this->adapter, true);
66
67
            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...
68
                $this->adapter[$key] = $adapterTmp;
69
                $this->callableFunctions[$key] = $callableFunctionTmp;
70
            } else {
71
                $this->adapter[] = $adapterTmp;
72
                $this->callableFunctions[] = $callableFunctionTmp;
73
            }
74
        }
75
76
        return $this;
77
    }
78
79
    /**
80
     * @param string $replaceAdapter
81
     *
82
     * @throws InvalidArgumentException
83
     */
84 18
    private function validateAdapter(string $replaceAdapter)
85
    {
86
        /** @noinspection PhpUnhandledExceptionInspection */
87 18
        $interfaces = (new \ReflectionClass($replaceAdapter))->getInterfaces();
88 18
        if (!\array_key_exists(iAdapter::class, $interfaces)) {
89
            throw new InvalidArgumentException('"' . $replaceAdapter . '" did not implement the "iAdapter"-interface [' . \print_r($interfaces, true) . ']');
90
        }
91 18
    }
92
93
    /**
94
     * @param callable $callableFunction
95
     *
96
     * @throws InvalidArgumentException
97
     */
98 18
    private function validateCallable(callable $callableFunction = null)
99
    {
100
        if (
101 18
            $callableFunction !== null
102
            &&
103 18
            !\is_callable($callableFunction)
104
        ) {
105
            throw new InvalidArgumentException('$callableFunction is not callable');
106
        }
107 18
    }
108
109
    /**
110
     * @return CacheAdapterAutoManager
111
     */
112 1
    public static function getDefaultsForAutoInit(): self
113
    {
114 1
        $cacheAdapterManager = new self();
115
116
        /** @noinspection PhpUnhandledExceptionInspection */
117 1
        $cacheAdapterManager->addAdapter(
118 1
            AdapterMemcached::class,
119 1
            static function () {
120
                $memcached = null;
121
                $isMemcachedAvailable = false;
122
                if (\extension_loaded('memcached')) {
123
                    /** @noinspection PhpComposerExtensionStubsInspection */
124
                    $memcached = new \Memcached();
125
                    /** @noinspection PhpUsageOfSilenceOperatorInspection */
126
                    $isMemcachedAvailable = @$memcached->addServer('127.0.0.1', 11211);
127
                }
128
129
                if (!$isMemcachedAvailable) {
130
                    $memcached = null;
131
                }
132
133
                return $memcached;
134 1
            }
135
        );
136
137
        /** @noinspection PhpUnhandledExceptionInspection */
138 1
        $cacheAdapterManager->addAdapter(
139 1
            AdapterMemcache::class,
140 1
            static function () {
141
                $memcache = null;
142
                $isMemcacheAvailable = false;
143
                /** @noinspection ClassConstantCanBeUsedInspection */
144
                if (\class_exists('\Memcache')) {
145
                    /** @noinspection PhpComposerExtensionStubsInspection */
146
                    $memcache = new \Memcache();
147
                    /** @noinspection PhpUsageOfSilenceOperatorInspection */
148
                    $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
149
                }
150
151
                if (!$isMemcacheAvailable) {
152
                    $memcache = null;
153
                }
154
155
                return $memcache;
156 1
            }
157
        );
158
159
        /** @noinspection PhpUnhandledExceptionInspection */
160 1
        $cacheAdapterManager->addAdapter(
161 1
            AdapterPredis::class,
162 1
            static function () {
163
                $redis = null;
164
                $isRedisAvailable = false;
165
                if (
166
                    \extension_loaded('redis')
167
                    &&
168
                    \class_exists('\Predis\Client')
169
                ) {
170
                    /** @noinspection PhpUndefinedNamespaceInspection */
171
                    /** @noinspection PhpUndefinedClassInspection */
172
                    /** @noinspection PhpFullyQualifiedNameUsageInspection */
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