Passed
Pull Request — master (#4)
by Ryuichi
43:13
created

anonymous//Driver/CacheDriverFactory.php$1   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 5
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 1
c 1
b 0
f 0
dl 0
loc 5
rs 10
1
<?php
2
3
namespace WebStream\Cache\Driver;
4
5
use WebStream\Container\Container;
0 ignored issues
show
Bug introduced by
The type WebStream\Container\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use WebStream\IO\File;
0 ignored issues
show
Bug introduced by
The type WebStream\IO\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use WebStream\IO\Reader\FileReader;
0 ignored issues
show
Bug introduced by
The type WebStream\IO\Reader\FileReader was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use WebStream\IO\Writer\FileWriter;
0 ignored issues
show
Bug introduced by
The type WebStream\IO\Writer\FileWriter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
/**
11
 * CacheDriverFactory
12
 * @author Ryuichi Tanaka
13
 * @since 2015/07/10
14
 * @version 0.7
15
 */
16
class CacheDriverFactory
17
{
18
    /**
19
     * キャッシュドライバオブジェクトを作成する
20
     * @param string $classpath ドライバクラスパス
21
     * @param Container $config 依存コンテナ
22
     * @return ICache キャッシュドライバオブジェクト
23
     */
24
    public function create(string $classpath, Container $config = null): ICache
25
    {
26
        $cache = null;
27
28
        if ($config === null) {
29
            $config = new Container(false);
30
        }
31
32
        switch ($classpath) {
33
            case "WebStream\Cache\Driver\Apcu":
34
                $cache = new $classpath($this->getApcuContainer($config));
35
                break;
36
            case "WebStream\Cache\Driver\Memcached":
37
                $cache = new $classpath($this->getMemcachedContainer($config));
38
                break;
39
            case "WebStream\Cache\Driver\Redis":
40
                $cache = new $classpath($this->getRedisContainer($config));
41
                break;
42
            case "WebStream\Cache\Driver\TemporaryFile":
43
                $cache = new $classpath($this->getTemporaryFileContainer($config));
44
                break;
45
        }
46
47
        return $cache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $cache could return the type null which is incompatible with the type-hinted return WebStream\Cache\Driver\ICache. Consider adding an additional type-check to rule them out.
Loading history...
48
    }
49
50
    /**
51
     * APCuオブジェクトを返却する
52
     * @param Container $container 依存コンテナ
53
     * @return Container キャッシュ依存コンテナ
54
     */
55
    private function getApcuContainer(Container $container): Container
56
    {
57
        $cacheContainer = new Container();
58
        $cacheContainer->available = extension_loaded('apcu');
59
        $cacheContainer->cachePrefix = "cache.apcu";
60
        $cacheContainer->classPrefix = $container->classPrefix ?: "";
61
        $cacheContainer->driver = new class ()
62
        {
63
            public function delegate($function, array $args = [])
64
            {
65
                return function_exists($function) ? call_user_func_array($function, $args) : null;
66
            }
67
        };
68
69
        return $cacheContainer;
70
    }
71
72
    /**
73
     * Memcachedオブジェクトを返却する
74
     * @param Container $container 依存コンテナ
75
     * @return Container キャッシュ依存コンテナ
76
     */
77
    private function getMemcachedContainer(Container $container): Container
78
    {
79
        $cacheContainer = new Container();
80
        $cacheContainer->driver = new \Memcached();
81
        $cacheContainer->available = extension_loaded('memcached');
82
        $cacheContainer->cachePrefix = "cache.memcached";
83
        $cacheContainer->classPrefix = $container->classPrefix ?: "";
84
        $cacheContainer->codes = [
85
            'success' => \Memcached::RES_SUCCESS,
86
            'notfound' => \Memcached::RES_NOTFOUND
87
        ];
88
89
        if ($cacheContainer->available) {
90
            $cacheContainer->driver->addServers($container->servers);
91
92
            $defaultOptions = [
93
                \Memcached::OPT_CONNECT_TIMEOUT => 50,
94
                \Memcached::OPT_RETRY_TIMEOUT => 50,
95
                \Memcached::OPT_SEND_TIMEOUT => 50,
96
                \Memcached::OPT_RECV_TIMEOUT => 50,
97
                \Memcached::OPT_POLL_TIMEOUT => 50,
98
                \Memcached::OPT_COMPRESSION => true,
99
                \Memcached::OPT_LIBKETAMA_COMPATIBLE => true,
100
                \Memcached::OPT_BINARY_PROTOCOL => true
101
            ];
102
103
            if (\Memcached::HAVE_IGBINARY) {
104
                $defaultOptions[\Memcached::OPT_SERIALIZER] = \Memcached::SERIALIZER_IGBINARY;
105
            }
106
107
            $cacheContainer->driver->setOptions($defaultOptions);
108
        }
109
110
        return $cacheContainer;
111
    }
112
113
    /**
114
     * Redisオブジェクトを返却する
115
     * @param Container $container 依存コンテナ
116
     * @return Container キャッシュ依存コンテナ
117
     */
118
    private function getRedisContainer(Container $container): Container
119
    {
120
        $cacheContainer = new Container();
121
        $cacheContainer->driver = new \Redis();
122
        $cacheContainer->available = extension_loaded('redis');
123
        $cacheContainer->cachePrefix = "cache.redis";
124
        $cacheContainer->classPrefix = $container->classPrefix ?: "";
125
        $cacheContainer->redisOptPrefix = \Redis::OPT_PREFIX;
126
127
        if ($cacheContainer->available) {
128
            $host = $container->host;
129
            $port = $container->port;
130
            $socket = $container->socket;
131
            $password = $container->password;
132
            $isAuthed = true;
133
134
            if ($password !== null) {
135
                $isAuthed = $cacheContainer->driver->auth($password);
136
            }
137
138
            if ($isAuthed) {
139
                if ($host !== null && $port !== null) {
140
                    $cacheContainer->available = $cacheContainer->driver->connect($host, $port);
141
                } elseif ($socket !== null) {
142
                    $cacheContainer->available = $cacheContainer->driver->connect($socket);
143
                }
144
145
                if (defined('\Redis::SERIALIZER_IGBINARY')) {
146
                    $cacheContainer->driver->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_IGBINARY);
147
                }
148
149
                $cacheContainer->driver->setOption(\Redis::OPT_PREFIX, $container->cachePrefix . '.' . $container->classPrefix);
150
                $cacheContainer->driver->setOption(\Redis::OPT_SCAN, \Redis::SCAN_RETRY);
151
            }
152
        }
153
154
        return $cacheContainer;
155
    }
156
157
    /**
158
     * TemporaryFileオブジェクトを返却する
159
     * @param Container $container 依存コンテナ
160
     * @return Container キャッシュ依存コンテナ
161
     */
162
    private function getTemporaryFileContainer(Container $container): Container
163
    {
164
        $cacheContainer = new Container();
165
        $cacheContainer->cachePrefix = "cache.file";
166
        $cacheContainer->classPrefix = $container->classPrefix ?: "";
167
        $dir = new File($container->cacheDir);
168
        $cacheContainer->available = $dir->isWritable();
169
        $cacheContainer->cacheDir = $container->cacheDir;
170
        $cacheContainer->ioContainer = new Container();
171
        $cacheContainer->ioContainer->fileReader = new class ()
172
        {
173
            public function getReader(File $file)
174
            {
175
                return new FileReader($file);
176
            }
177
        };
178
        $cacheContainer->ioContainer->fileWriter = new class ()
179
        {
180
            public function getWriter($file, $isAppend)
181
            {
182
                return new FileWriter($file, $isAppend);
183
            }
184
        };
185
        $cacheContainer->ioContainer->fileIterator = new class ()
186
        {
187
            public function getIterator($dirPath)
188
            {
189
                $file = new File($dirPath);
190
                $iterator = [];
191
                if ($file->isDirectory()) {
192
                    $iterator = new \RecursiveIteratorIterator(
193
                        new \RecursiveDirectoryIterator($file->getFilePath()),
194
                        \RecursiveIteratorIterator::LEAVES_ONLY,
195
                        \RecursiveIteratorIterator::CATCH_GET_CHILD // for Permission deny
196
                    );
197
                }
198
199
                return $iterator;
200
            }
201
        };
202
203
        return $cacheContainer;
204
    }
205
}
206