Completed
Push — 2.x-dev-kit ( e2c8e7 )
by
unknown
01:19
created

DependencyInjection/SonataCacheExtension.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\CacheBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Processor;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
18
use Symfony\Component\DependencyInjection\Reference;
19
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
20
21
/**
22
 * PageExtension.
23
 *
24
 *
25
 * @author     Thomas Rabaix <[email protected]>
26
 */
27
class SonataCacheExtension extends Extension
28
{
29
    /**
30
     * Loads the url shortener configuration.
31
     *
32
     * @param array            $configs   An array of configuration settings
33
     * @param ContainerBuilder $container A ContainerBuilder instance
34
     */
35
    public function load(array $configs, ContainerBuilder $container)
36
    {
37
        $processor = new Processor();
38
        $configuration = new Configuration();
39
        $config = $processor->processConfiguration($configuration, $configs);
40
41
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
42
        $loader->load('cache.xml');
43
        $loader->load('counter.xml');
44
45
        $useOrm = 'auto' == $config['cache_invalidation']['orm_listener'] ?
46
            class_exists('Doctrine\\ORM\\Version') :
47
            $config['cache_invalidation']['orm_listener'];
48
49
        if ($useOrm) {
50
            $loader->load('orm.xml');
51
        }
52
53
        $usePhpcrOdm = 'auto' == $config['cache_invalidation']['phpcr_odm_listener'] ?
54
            class_exists('Doctrine\\PHPCR\\ODM\\Version') :
55
            $config['cache_invalidation']['phpcr_odm_listener'];
56
        if ($usePhpcrOdm) {
57
            $loader->load('phpcr_odm.xml');
58
        }
59
60
        $this->configureInvalidation($container, $config);
61
        if ($useOrm) {
62
            $this->configureORM($container, $config);
63
        }
64
        if ($usePhpcrOdm) {
65
            $this->configurePHPCRODM($container, $config);
66
        }
67
        $this->configureCache($container, $config);
68
        $this->configureCounter($container, $config);
69
    }
70
71
    /**
72
     * @param ContainerBuilder $container
73
     * @param array            $config
74
     */
75
    public function configureInvalidation(ContainerBuilder $container, $config)
76
    {
77
        $cacheManager = $container->getDefinition('sonata.cache.manager');
78
79
        $cacheManager->replaceArgument(0, new Reference($config['cache_invalidation']['service']));
80
81
        $recorder = $container->getDefinition('sonata.cache.model_identifier');
82
        foreach ($config['cache_invalidation']['classes'] as $class => $method) {
83
            $recorder->addMethodCall('addClass', [$class, $method]);
84
        }
85
86
        $cacheManager->addMethodCall('setRecorder', [new Reference($config['cache_invalidation']['recorder'])]);
87
    }
88
89
    /**
90
     * @param ContainerBuilder $container
91
     * @param array            $config
92
     */
93
    public function configureORM(ContainerBuilder $container, $config)
0 ignored issues
show
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
    {
95
        $cacheManager = $container->getDefinition('sonata.cache.orm.event_subscriber');
96
97
        $connections = array_keys($container->getParameter('doctrine.connections'));
98
        foreach ($connections as $conn) {
99
            $cacheManager->addTag('doctrine.event_subscriber', ['connection' => $conn]);
100
        }
101
    }
102
103
    /**
104
     * @param ContainerBuilder $container
105
     * @param array            $config
106
     */
107
    public function configurePHPCRODM(ContainerBuilder $container, $config)
0 ignored issues
show
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
108
    {
109
        $cacheManager = $container->getDefinition('sonata.cache.phpcr_odm.event_subscriber');
110
111
        $sessions = array_keys($container->getParameter('doctrine_phpcr.odm.sessions'));
112
        foreach ($sessions as $session) {
113
            $cacheManager->addTag('doctrine_phpcr.event_subscriber', ['session' => $session]);
114
        }
115
    }
116
117
    /**
118
     * @param ContainerBuilder $container
119
     * @param array            $config
120
     *
121
     * @throws \RuntimeException if the Mongo or Memcached library is not installed
122
     */
123
    public function configureCache(ContainerBuilder $container, $config)
124
    {
125
        if ($config['default_cache']) {
126
            $container->setAlias('sonata.cache', $config['default_cache']);
127
        }
128
129
        if (isset($config['caches']['esi'])) {
130
            $container
131
                ->getDefinition('sonata.cache.esi')
132
                ->replaceArgument(0, $config['caches']['esi']['token'])
133
                ->replaceArgument(1, $config['caches']['esi']['servers'])
134
                ->replaceArgument(3, 3 === $config['caches']['esi']['version'] ? 'ban' : 'purge');
135
        } else {
136
            $container->removeDefinition('sonata.cache.esi');
137
        }
138
139
        if (isset($config['caches']['ssi'])) {
140
            $container
141
                ->getDefinition('sonata.cache.ssi')
142
                ->replaceArgument(0, $config['caches']['ssi']['token'])
143
            ;
144
        } else {
145
            $container->removeDefinition('sonata.cache.ssi');
146
        }
147
148
        if (isset($config['caches']['mongo'])) {
149
            $this->checkMongo();
150
151
            $database = $config['caches']['mongo']['database'];
152
            $servers = [];
153
            foreach ($config['caches']['mongo']['servers'] as $server) {
154
                if ($server['user']) {
155
                    $servers[] = sprintf('%s:%s@%s:%s/%s', $server['user'], $server['password'], $server['host'], $server['port'], $database);
156
                } else {
157
                    $servers[] = sprintf('%s:%s', $server['host'], $server['port']);
158
                }
159
            }
160
161
            $container
162
                ->getDefinition('sonata.cache.mongo')
163
                ->replaceArgument(0, $servers)
164
                ->replaceArgument(1, $database)
165
                ->replaceArgument(2, $config['caches']['mongo']['collection'])
166
            ;
167
        } else {
168
            $container->removeDefinition('sonata.cache.mongo');
169
        }
170
171
        if (isset($config['caches']['memcached'])) {
172
            $this->checkMemcached();
173
174
            $container
175
                ->getDefinition('sonata.cache.memcached')
176
                ->replaceArgument(0, $config['caches']['memcached']['prefix'])
177
                ->replaceArgument(1, $config['caches']['memcached']['servers'])
178
            ;
179
        } else {
180
            $container->removeDefinition('sonata.cache.memcached');
181
        }
182
183
        if (isset($config['caches']['predis'])) {
184
            $this->checkPRedis();
185
186
            $container
187
                ->getDefinition('sonata.cache.predis')
188
                ->replaceArgument(0, $config['caches']['predis']['servers'])
189
            ;
190
        } else {
191
            $container->removeDefinition('sonata.cache.predis');
192
        }
193
194
        if (isset($config['caches']['apc'])) {
195
            $this->checkApc();
196
197
            $container
198
                ->getDefinition('sonata.cache.apc')
199
                ->replaceArgument(1, $config['caches']['apc']['token'])
200
                ->replaceArgument(2, $config['caches']['apc']['prefix'])
201
                ->replaceArgument(3, $this->configureServers($config['caches']['apc']['servers']))
202
                ->replaceArgument(4, $config['caches']['apc']['timeout'])
203
            ;
204
        } else {
205
            $container->removeDefinition('sonata.cache.apc');
206
        }
207
208
        if (isset($config['caches']['symfony'])) {
209
            $container
210
                ->getDefinition('sonata.cache.symfony')
211
                ->replaceArgument(3, $config['caches']['symfony']['token'])
212
                ->replaceArgument(4, $config['caches']['symfony']['php_cache_enabled'])
213
                ->replaceArgument(5, $config['caches']['symfony']['types'])
214
                ->replaceArgument(6, $this->configureServers($config['caches']['symfony']['servers']))
215
                ->replaceArgument(7, $config['caches']['symfony']['timeout'])
216
            ;
217
        } else {
218
            $container->removeDefinition('sonata.cache.symfony');
219
        }
220
    }
221
222
    /**
223
     * @param ContainerBuilder $container
224
     * @param array            $config
225
     *
226
     * @throws \RuntimeException if the Mongo or Memcached library is not installed
227
     */
228
    public function configureCounter(ContainerBuilder $container, $config)
229
    {
230
        if ($config['default_counter']) {
231
            $container->setAlias('sonata.counter', $config['default_counter']);
232
        }
233
234
        if (isset($config['counters']['mongo'])) {
235
            $this->checkMongo();
236
237
            $servers = [];
238
            foreach ($config['counters']['mongo']['servers'] as $server) {
239
                if ($server['user']) {
240
                    $servers[] = sprintf('%s:%s@%s:%s', $server['user'], $server['password'], $server['host'], $server['port']);
241
                } else {
242
                    $servers[] = sprintf('%s:%s', $server['host'], $server['port']);
243
                }
244
            }
245
246
            $container
247
                ->getDefinition('sonata.cache.counter.mongo')
248
                ->replaceArgument(0, $servers)
249
                ->replaceArgument(1, $config['counters']['mongo']['database'])
250
                ->replaceArgument(2, $config['counters']['mongo']['collection'])
251
            ;
252
        } else {
253
            $container->removeDefinition('sonata.cache.counter.mongo');
254
        }
255
256
        if (isset($config['counters']['memcached'])) {
257
            $this->checkMemcached();
258
259
            $container
260
                ->getDefinition('sonata.cache.counter.memcached')
261
                ->replaceArgument(0, $config['counters']['memcached']['prefix'])
262
                ->replaceArgument(1, $config['counters']['memcached']['servers'])
263
            ;
264
        } else {
265
            $container->removeDefinition('sonata.cache.counter.memcached');
266
        }
267
268
        if (isset($config['counters']['predis'])) {
269
            $this->checkPRedis();
270
271
            $container
272
                ->getDefinition('sonata.cache.counter.predis')
273
                ->replaceArgument(0, $config['counters']['predis']['servers'])
274
            ;
275
        } else {
276
            $container->removeDefinition('sonata.cache.counter.predis');
277
        }
278
279
        if (isset($config['counters']['apc'])) {
280
            $this->checkApc();
281
282
            $container
283
                ->getDefinition('sonata.cache.counter.apc')
284
                ->replaceArgument(0, $config['counters']['apc']['prefix'])
285
            ;
286
        } else {
287
            $container->removeDefinition('sonata.cache.counter.apc');
288
        }
289
    }
290
291
    /**
292
     * Returns servers list with hash for basic auth computed if provided.
293
     *
294
     * @param array $servers
295
     *
296
     * @return array
297
     */
298
    public function configureServers(array $servers)
299
    {
300
        return array_map(
301
            function ($item) {
302
                if ($item['basic']) {
303
                    $item['basic'] = base64_encode($item['basic']);
304
                }
305
306
                return $item;
307
            },
308
            $servers
309
        );
310
    }
311
312
    protected function checkMemcached()
313
    {
314
        if (!class_exists('\Memcached', true)) {
315
            throw new \RuntimeException(<<<'HELP'
316
The `sonata.cache.memcached` service is configured, however the Memcached class is not available.
317
318
To resolve this issue, please install the related library : http://php.net/manual/en/book.memcached.php
319
or remove the memcached cache settings from the configuration file.
320
HELP
321
            );
322
        }
323
    }
324
325
    protected function checkApc()
326
    {
327
        if (!function_exists('apc_fetch')) {
328
            throw new \RuntimeException(<<<'HELP'
329
The `sonata.cache.apc` service is configured, however the apc_* functions are not available.
330
331
To resolve this issue, please install the related library : http://php.net/manual/en/book.apc.php
332
or remove the APC cache settings from the configuration file.
333
HELP
334
            );
335
        }
336
    }
337
338
    protected function checkMongo()
339
    {
340
        if (!class_exists('\Mongo', true)) {
341
            throw new \RuntimeException(<<<'HELP'
342
The `sonata.cache.mongo` service is configured, however the Mongo class is not available.
343
344
To resolve this issue, please install the related library : http://php.net/manual/en/book.mongo.php
345
or remove the mongo cache settings from the configuration file.
346
HELP
347
            );
348
        }
349
    }
350
351
    protected function checkPRedis()
352
    {
353
        if (!class_exists('\Predis\Client', true)) {
354
            throw new \RuntimeException(<<<HELP
355
The `sonata.cache.predis` service is configured, however the Predis\Client class is not available.
356
357
Please add the lib in your composer.json file: "predis/predis": "~0.8".
358
HELP
359
            );
360
        }
361
    }
362
}
363