Completed
Push — 2.x-dev-kit ( 6f250c )
by
unknown
02:44
created

SonataCacheExtension::load()   C

Complexity

Conditions 7
Paths 64

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 1
Metric Value
c 7
b 1
f 1
dl 0
loc 35
rs 6.7272
cc 7
eloc 24
nc 64
nop 2
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', array($class, $method));
84
        }
85
86
        $cacheManager->addMethodCall('setRecorder', array(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
Unused Code introduced by
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', array('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
Unused Code introduced by
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', array('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 = array();
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
            ;
216
        } else {
217
            $container->removeDefinition('sonata.cache.symfony');
218
        }
219
    }
220
221
    /**
222
     * @param ContainerBuilder $container
223
     * @param array            $config
224
     *
225
     * @throws \RuntimeException if the Mongo or Memcached library is not installed
226
     */
227
    public function configureCounter(ContainerBuilder $container, $config)
228
    {
229
        if ($config['default_counter']) {
230
            $container->setAlias('sonata.counter', $config['default_counter']);
231
        }
232
233
        if (isset($config['counters']['mongo'])) {
234
            $this->checkMongo();
235
236
            $servers = array();
237
            foreach ($config['counters']['mongo']['servers'] as $server) {
238
                if ($server['user']) {
239
                    $servers[] = sprintf('%s:%s@%s:%s', $server['user'], $server['password'], $server['host'], $server['port']);
240
                } else {
241
                    $servers[] = sprintf('%s:%s', $server['host'], $server['port']);
242
                }
243
            }
244
245
            $container
246
                ->getDefinition('sonata.cache.counter.mongo')
247
                ->replaceArgument(0, $servers)
248
                ->replaceArgument(1, $config['counters']['mongo']['database'])
249
                ->replaceArgument(2, $config['counters']['mongo']['collection'])
250
            ;
251
        } else {
252
            $container->removeDefinition('sonata.cache.counter.mongo');
253
        }
254
255
        if (isset($config['counters']['memcached'])) {
256
            $this->checkMemcached();
257
258
            $container
259
                ->getDefinition('sonata.cache.counter.memcached')
260
                ->replaceArgument(0, $config['counters']['memcached']['prefix'])
261
                ->replaceArgument(1, $config['counters']['memcached']['servers'])
262
            ;
263
        } else {
264
            $container->removeDefinition('sonata.cache.counter.memcached');
265
        }
266
267
        if (isset($config['counters']['predis'])) {
268
            $this->checkPRedis();
269
270
            $container
271
                ->getDefinition('sonata.cache.counter.predis')
272
                ->replaceArgument(0, $config['counters']['predis']['servers'])
273
            ;
274
        } else {
275
            $container->removeDefinition('sonata.cache.counter.predis');
276
        }
277
278
        if (isset($config['counters']['apc'])) {
279
            $this->checkApc();
280
281
            $container
282
                ->getDefinition('sonata.cache.counter.apc')
283
                ->replaceArgument(0, $config['counters']['apc']['prefix'])
284
            ;
285
        } else {
286
            $container->removeDefinition('sonata.cache.counter.apc');
287
        }
288
    }
289
290
    /**
291
     * Returns servers list with hash for basic auth computed if provided.
292
     *
293
     * @param array $servers
294
     *
295
     * @return array
296
     */
297
    public function configureServers(array $servers)
298
    {
299
        return array_map(
300
            function ($item) {
301
                if ($item['basic']) {
302
                    $item['basic'] = base64_encode($item['basic']);
303
                }
304
305
                return $item;
306
            },
307
            $servers
308
        );
309
    }
310
311
    protected function checkMemcached()
312
    {
313
        if (!class_exists('\Memcached', true)) {
314
            throw new \RuntimeException(<<<'HELP'
315
The `sonata.cache.memcached` service is configured, however the Memcached class is not available.
316
317
To resolve this issue, please install the related library : http://php.net/manual/en/book.memcached.php
318
or remove the memcached cache settings from the configuration file.
319
HELP
320
            );
321
        }
322
    }
323
324
    protected function checkApc()
325
    {
326
        if (!function_exists('apc_fetch')) {
327
            throw new \RuntimeException(<<<'HELP'
328
The `sonata.cache.apc` service is configured, however the apc_* functions are not available.
329
330
To resolve this issue, please install the related library : http://php.net/manual/en/book.apc.php
331
or remove the APC cache settings from the configuration file.
332
HELP
333
            );
334
        }
335
    }
336
337
    protected function checkMongo()
338
    {
339
        if (!class_exists('\Mongo', true)) {
340
            throw new \RuntimeException(<<<'HELP'
341
The `sonata.cache.mongo` service is configured, however the Mongo class is not available.
342
343
To resolve this issue, please install the related library : http://php.net/manual/en/book.mongo.php
344
or remove the mongo cache settings from the configuration file.
345
HELP
346
            );
347
        }
348
    }
349
350
    protected function checkPRedis()
351
    {
352
        if (!class_exists('\Predis\Client', true)) {
353
            throw new \RuntimeException(<<<HELP
354
The `sonata.cache.predis` service is configured, however the Predis\Client class is not available.
355
356
Please add the lib in your composer.json file: "predis/predis": "~0.8".
357
HELP
358
            );
359
        }
360
    }
361
}
362