Completed
Push — master ( f88f3d...9aa3e7 )
by Ryuichi
05:31
created

anonymous//Driver/CacheDriverFactory.php$0   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 7
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

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