CacheServiceProvider   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 261
Duplicated Lines 0 %

Importance

Changes 8
Bugs 1 Features 3
Metric Value
eloc 88
c 8
b 1
f 3
dl 0
loc 261
rs 10
wmc 16

4 Methods

Rating   Name   Duplication   Size   Complexity  
B registerDrivers() 0 124 7
A register() 0 5 1
A registerService() 0 76 5
A registerMiddleware() 0 30 3
1
<?php
2
3
namespace Charcoal\Cache\ServiceProvider;
4
5
// From Pimple
6
use Charcoal\Cache\Facade\CachePoolFacade;
7
use Pimple\ServiceProviderInterface;
8
use Pimple\Container;
9
10
// From 'tedivm/stash'
11
use Stash\DriverList;
12
use Stash\Interfaces\DriverInterface;
13
use Stash\Pool;
14
15
// From 'charcoal-cache'
16
use Charcoal\Cache\CacheBuilder;
17
use Charcoal\Cache\CacheConfig;
18
use Charcoal\Cache\Middleware\CacheMiddleware;
19
20
/**
21
 * Cache Service Provider
22
 *
23
 * Provides a Stash cache pool (PSR-6 compatible).
24
 *
25
 * ## Dependencies
26
 *
27
 * - `config`: An {@link https://packagist.org/packages/locomotivemtl/charcoal-app application configset}.
28
 * - `logger` A {@link https://packagist.org/providers/psr/log-implementation PSR-3 logging client}.
29
 *
30
 * ## Services
31
 *
32
 * - `cache`: The default PSR-6 cache pool
33
 *
34
 * ## Helpers
35
 *
36
 * - `cache/config`: The cache configset.
37
 * - `cache/driver`: The cache driver of the default pool.
38
 * - `cache/builder`: An advacned cache pool factory.
39
 *
40
 * ## Middleware
41
 *
42
 * - `middlewares/charcoal/cache/middleware/cache`: For caching HTTP responses.
43
 *
44
 */
45
class CacheServiceProvider implements ServiceProviderInterface
46
{
47
    /**
48
     * @param  Container $container A container instance.
49
     * @return void
50
     */
51
    public function register(Container $container)
52
    {
53
        $this->registerDrivers($container);
54
        $this->registerService($container);
55
        $this->registerMiddleware($container);
56
    }
57
58
    /**
59
     * @param  Container $container A container instance.
60
     * @return void
61
     */
62
    public function registerDrivers(Container $container)
63
    {
64
        /**
65
         * The collection of cache drivers that are supported by this system.
66
         *
67
         * @var array An associative array structured as `"Driver Name" => "Class Name"`.
68
         */
69
        $container['cache/available-drivers'] = DriverList::getAvailableDrivers();
70
71
        /**
72
         * The collection of cache driver instances.
73
         *
74
         * @param  Container $container The service container.
75
         * @return Container Service container of cache drivers from Stash.
76
         */
77
        $container['cache/drivers'] = function (Container $container) {
78
            $drivers = new Container();
79
80
            /**
81
             * @param  Container $container The service container.
82
             * @return \Stash\Driver\Apc|null
83
             */
84
            $drivers['apc'] = function () use ($container) {
85
                $drivers = $container['cache/available-drivers'];
86
                if (!isset($drivers['Apc'])) {
87
                    // Apc is not available on system
88
                    return null;
89
                }
90
91
                $cacheConfig   = $container['cache/config'];
92
                $driverOptions = [
93
                    'ttl'       => $cacheConfig['default_ttl'],
94
                    'namespace' => $cacheConfig['prefix'],
95
                ];
96
97
                return new $drivers['Apc']($driverOptions);
98
            };
99
100
            /**
101
             * @param  Container $container A container instance.
102
             * @return \Stash\Driver\Sqlite|null
103
             */
104
            $drivers['db'] = function () use ($container) {
105
                $drivers = $container['cache/available-drivers'];
106
                if (!isset($drivers['SQLite'])) {
107
                    // SQLite is not available on system
108
                    return null;
109
                }
110
111
                return new $drivers['SQLite']();
112
            };
113
114
            /**
115
             * @param  Container $container A container instance.
116
             * @return \Stash\Driver\FileSystem
117
             */
118
            $drivers['file'] = function () use ($container) {
119
                $drivers = $container['cache/available-drivers'];
120
                return new $drivers['FileSystem']();
121
            };
122
123
            /**
124
             * @param  Container $container A container instance.
125
             * @return \Stash\Driver\Memcache|null
126
             */
127
            $drivers['memcache'] = function () use ($container) {
128
                $drivers = $container['cache/available-drivers'];
129
                if (!isset($drivers['Memcache'])) {
130
                    // Memcache is not available on system
131
                    return null;
132
                }
133
134
                $cacheConfig   = $container['cache/config'];
135
                $driverOptions = [
136
                    'servers' => [],
137
                ];
138
139
                if (isset($cacheConfig['servers'])) {
140
                    $servers = [];
141
                    foreach ($cacheConfig['servers'] as $server) {
142
                        $servers[] = array_values($server);
143
                    }
144
                    $driverOptions['servers'] = $servers;
145
                } else {
146
                    // Default Memcache options: locahost:11211
147
                    $driverOptions['servers'][] = [ '127.0.0.1', 11211 ];
148
                }
149
150
                return new $drivers['Memcache']($driverOptions);
151
            };
152
153
            /**
154
             * @param  Container $container A container instance.
155
             * @return \Stash\Driver\Ephemeral
156
             */
157
            $drivers['memory'] = function () use ($container) {
158
                $drivers = $container['cache/available-drivers'];
159
                return new $drivers['Ephemeral']();
160
            };
161
162
            /**
163
             * @param  Container $container A container instance.
164
             * @return \Stash\Driver\BlackHole
165
             */
166
            $drivers['noop'] = function () use ($container) {
167
                $drivers = $container['cache/available-drivers'];
168
                return new $drivers['BlackHole']();
169
            };
170
171
            /**
172
             * @param  Container $container A container instance.
173
             * @return \Stash\Driver\Redis|null
174
             */
175
            $drivers['redis'] = function () use ($container) {
176
                $drivers = $container['cache/available-drivers'];
177
                if (!isset($drivers['Redis'])) {
178
                    // Redis is not available on system
179
                    return null;
180
                }
181
182
                return new $drivers['Redis']();
183
            };
184
185
            return $drivers;
186
        };
187
    }
188
189
    /**
190
     * @param  Container $container A container instance.
191
     * @return void
192
     */
193
    public function registerService(Container $container)
194
    {
195
        /**
196
         * The cache configset.
197
         *
198
         * @param  Container $container The service container.
199
         * @return CacheConfig
200
         */
201
        $container['cache/config'] = function (Container $container) {
202
            $appConfig   = isset($container['config']) ? $container['config'] : [];
203
            $cacheConfig = isset($appConfig['cache']) ? $appConfig['cache'] : null;
204
            return new CacheConfig($cacheConfig);
205
        };
206
207
        /**
208
         * A cache pool builder, using Stash.
209
         *
210
         * @param  Container $container A Pimple DI container.
211
         * @return CacheBuilder
212
         */
213
        $container['cache/builder'] = function (Container $container) {
214
            $cacheConfig = $container['cache/config'];
215
216
            return new CacheBuilder([
217
                'logger'     => $container['logger'],
218
                'drivers'    => $container['cache/drivers'],
219
                'namespace'  => $cacheConfig['prefix'],
220
            ]);
221
        };
222
223
        /**
224
         * The driver of the main cache pool "cache".
225
         *
226
         * @param  Container $container The service container.
227
         * @return DriverInterface Primary cache driver from Stash.
228
         */
229
        $container['cache/driver'] = $container->factory(function (Container $container) {
230
            return $container['cache']->getDriver();
231
        });
232
233
        /**
234
         * The main cache item pool.
235
         *
236
         * @param  Container $container The service container.
237
         * @return Pool The cache item pool from Stash.
238
         */
239
        $container['cache'] = function (Container $container) {
240
            $cacheBuilder = $container['cache/builder'];
241
            $cacheConfig  = $container['cache/config'];
242
243
            if ($cacheConfig['active'] === true) {
244
                $cacheDrivers = $cacheConfig['types'];
245
            } else {
246
                $cacheDrivers = $cacheConfig['default_types'];
247
            }
248
249
            return $cacheBuilder($cacheDrivers);
250
        };
251
252
        /**
253
         * The facade for the main cache pool.
254
         *
255
         * @param  Container $container The service container.
256
         * @return CachePoolFacade The facade for the main cache pool.
257
         */
258
        $container['cache/facade'] = function (Container $container) {
259
            $args = [
260
                'cache' => $container['cache'],
261
            ];
262
263
            $cacheConfig = $container['cache/config'];
264
            if (isset($cacheConfig['default_ttl'])) {
265
                $args['default_ttl'] = $cacheConfig['default_ttl'];
266
            }
267
268
            return new CachePoolFacade($args);
269
        };
270
    }
271
272
    /**
273
     * @param  Container $container A container instance.
274
     * @return void
275
     */
276
    private function registerMiddleware(Container $container)
277
    {
278
        /**
279
         * The cache middleware configset.
280
         *
281
         * @param  Container $container The service container.
282
         * @return array
283
         */
284
        $container['cache/middleware/config'] = function (Container $container) {
285
            $appConfig = isset($container['config']) ? $container['config'] : [];
286
287
            if (isset($appConfig['middlewares']['charcoal/cache/middleware/cache'])) {
288
                $wareConfig = $appConfig['middlewares']['charcoal/cache/middleware/cache'];
289
            } else {
290
                $wareConfig = [];
291
            }
292
293
            $wareConfig['cache'] = $container['cache'];
294
295
            return $wareConfig;
296
        };
297
298
        /**
299
         * The middleware for caching HTTP responses.
300
         *
301
         * @param  Container $container A container instance.
302
         * @return CacheMiddleware
303
         */
304
        $container['middlewares/charcoal/cache/middleware/cache'] = function (Container $container) {
305
            return new CacheMiddleware($container['cache/middleware/config']);
306
        };
307
    }
308
}
309