Passed
Push — master ( 8763d4...3f89cd )
by Divine Niiquaye
01:54
created

AdapterFactory::getPrefixedAdapter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 3
dl 0
loc 11
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of BiuradPHP opensource projects.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace BiuradPHP\Cache;
19
20
use BiuradPHP\Cache\Exceptions\InvalidArgumentException;
21
use Doctrine\Common\Cache as DoctrineCache;
22
use Memcache;
23
use Memcached;
24
use Redis;
25
use SQLite3;
26
use TypeError;
27
28
/**
29
 * @author Divine Niiquaye Ibok <[email protected]>
30
 */
31
class AdapterFactory
32
{
33
    /**
34
     * @param object|string $connection Connection or DSN
35
     *
36
     * @return DoctrineCache\Cache
37
     */
38
    public static function createHandler($connection): DoctrineCache\Cache
39
    {
40
        if (!(\is_string($connection) || \is_object($connection))) {
41
            throw new TypeError(
42
                \sprintf(
43
                    'Argument 1 passed to %s() must be a string or a connection object, %s given.',
44
                    __METHOD__,
45
                    \gettype($connection)
46
                )
47
            );
48
        }
49
50
        switch (true) {
51
            case $connection instanceof DoctrineCache\Cache:
52
                return $connection;
53
54
            case $connection instanceof Redis:
55
                $adapter = new DoctrineCache\RedisCache();
56
57
                if (!$connection->isConnected()) {
0 ignored issues
show
Bug introduced by
The method isConnected() does not exist on Redis. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

57
                if (!$connection->/** @scrutinizer ignore-call */ isConnected()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
58
                    throw new InvalidArgumentException('Did you forget to call the \'connect\' method');
59
                }
60
                $adapter->setRedis($connection);
61
62
                return $adapter;
63
64
            case $connection instanceof Memcache:
65
                $adapter = new DoctrineCache\MemcacheCache();
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Cache\MemcacheCache has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

65
                $adapter = /** @scrutinizer ignore-deprecated */ new DoctrineCache\MemcacheCache();
Loading history...
66
                $adapter->setMemcache($connection);
67
68
                return $adapter;
69
70
            case $connection instanceof Memcached:
71
                $adapter = new DoctrineCache\MemcachedCache();
72
                $adapter->setMemcached($connection);
73
74
                return $adapter;
75
76
            case self::isPrefixedAdapter($connection, 'array'):
77
                return new DoctrineCache\ArrayCache();
78
79
            case self::isPrefixedAdapter($connection, 'apcu'):
80
                return new DoctrineCache\ApcuCache();
81
82
            case self::isPrefixedAdapter($connection, 'wincache'):
83
                return new DoctrineCache\WinCacheCache();
84
85
            case self::isPrefixedAdapter($connection, 'zenddata'):
86
                return new DoctrineCache\ZendDataCache();
87
88
            case self::isPrefixedAdapter($connection, 'redis://'):
89
                $adapter = new DoctrineCache\RedisCache();
90
91
                [$host, $port] = \explode(':', \substr((string) $connection, 8));
92
                ($redis = new Redis())->connect($host, (int) $port);
93
                $adapter->setRedis($redis);
94
95
                return $adapter;
96
97
            case self::isPrefixedAdapter($connection, 'memcache://'):
98
                $adapter = new DoctrineCache\MemcacheCache();
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\Common\Cache\MemcacheCache has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

98
                $adapter = /** @scrutinizer ignore-deprecated */ new DoctrineCache\MemcacheCache();
Loading history...
99
100
                [$host, $port] = self::getPrefixedAdapter($connection, 11);
101
                $adapter->setMemcache(\memcache_pconnect($host, (int) $port));
102
103
                return $adapter;
104
105
            case self::isPrefixedAdapter($connection, 'memcached://'):
106
                $adapter = new DoctrineCache\MemcachedCache();
107
108
                [$host, $port] = self::getPrefixedAdapter($connection, 12);
109
                ($memcached = new Memcached())->addServer($host, (int) $port);
110
                $adapter->setMemcached($memcached);
111
112
                return $adapter;
113
114
            case self::isPrefixedAdapter($connection, 'file://'):
115
                [$tempDir, $extension] = self::getPrefixedAdapter($connection, 7, false);
116
117
                return new DoctrineCache\FilesystemCache($tempDir, $extension . 'data');
118
119
            case self::isPrefixedAdapter($connection, 'memory://'):
120
                [$tempDir, $extension] = self::getPrefixedAdapter($connection, 9, false);
121
122
                return new DoctrineCache\PhpFileCache($tempDir, $extension . 'php');
123
124
            case self::isPrefixedAdapter($connection, 'sqlite://'):
125
                [$table, $filename] = self::getPrefixedAdapter($connection, 9);
126
127
                return new DoctrineCache\SQLite3Cache(new SQLite3($filename), $table);
128
        }
129
130
        throw new InvalidArgumentException(
131
            \sprintf('Unsupported Cache Adapter: %s.', \is_object($connection) ? \get_class($connection) : $connection)
132
        );
133
    }
134
135
    /**
136
     * @param mixed $connection
137
     * @param bool  $host
138
     *
139
     * @return false|string[]
140
     */
141
    private static function getPrefixedAdapter($connection, int $limit, bool $host = true)
142
    {
143
        if (true === $host) {
144
            return \explode(':', \substr((string) $connection, $limit));
145
        }
146
147
        if (\strpos(':', $tempDir = \substr((string) $connection, $limit))) {
148
            return \explode(':', $tempDir);
149
        }
150
151
        return [$tempDir, '.cache.'];
152
    }
153
154
    /**
155
     * @param mixed  $connection
156
     * @param string $name
157
     *
158
     * @return bool
159
     */
160
    private static function isPrefixedAdapter($connection, string $name): bool
161
    {
162
        return \is_string($connection) && 0 === \strpos($connection, $name);
163
    }
164
}
165