Completed
Push — 6.12 ( 945ca3...d0ab56 )
by André
58:04 queued 42:29
created

EzPublishCoreExtension::handleCache()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the EzPublishCoreExtension class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Bundle\EzPublishCoreBundle\DependencyInjection;
10
11
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ConfigParser;
12
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ConfigurationProcessor;
13
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\Suggestion\Collector\SuggestionCollector;
14
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\Suggestion\Collector\SuggestionCollectorAwareInterface;
15
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\Suggestion\Formatter\YamlSuggestionFormatter;
16
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Security\PolicyProvider\PoliciesConfigBuilder;
17
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Security\PolicyProvider\PolicyProviderInterface;
18
use eZ\Bundle\EzPublishCoreBundle\SiteAccess\SiteAccessConfigurationFilter;
19
use Symfony\Component\Config\Resource\FileResource;
20
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
21
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
22
use Symfony\Component\DependencyInjection\ContainerBuilder;
23
use Symfony\Component\DependencyInjection\Loader;
24
use Symfony\Component\DependencyInjection\Loader\FileLoader;
25
use Symfony\Component\Config\FileLocator;
26
use InvalidArgumentException;
27
use Symfony\Component\Yaml\Yaml;
28
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface;
29
30
class EzPublishCoreExtension extends Extension implements PrependExtensionInterface
31
{
32
    /**
33
     * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\Suggestion\Collector\SuggestionCollector
34
     */
35
    private $suggestionCollector;
36
37
    /**
38
     * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface
39
     */
40
    private $mainConfigParser;
41
42
    /**
43
     * @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface[]
44
     */
45
    private $configParsers;
46
47
    /**
48
     * @var PolicyProviderInterface[]
49
     */
50
    private $policyProviders = [];
51
52
    /**
53
     * Holds a collection of YAML files, as an array with directory path as a
54
     * key to the array of contained file names.
55
     *
56
     * @var array
57
     */
58
    private $defaultSettingsCollection = [];
59
60
    /**
61
     * @var \eZ\Bundle\EzPublishCoreBundle\SiteAccess\SiteAccessConfigurationFilter[]
62
     */
63
    private $siteaccessConfigurationFilters = [];
64
65
    public function __construct(array $configParsers = array())
66
    {
67
        $this->configParsers = $configParsers;
68
        $this->suggestionCollector = new SuggestionCollector();
69
    }
70
71
    public function getAlias()
72
    {
73
        return 'ezpublish';
74
    }
75
76
    /**
77
     * Loads a specific configuration.
78
     *
79
     * @param mixed[] $configs An array of configuration values
80
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container A ContainerBuilder instance
81
     *
82
     * @throws \InvalidArgumentException When provided tag is not defined in this extension
83
     *
84
     * @api
85
     */
86
    public function load(array $configs, ContainerBuilder $container)
87
    {
88
        $loader = new Loader\YamlFileLoader(
89
            $container,
90
            new FileLocator(__DIR__ . '/../Resources/config')
91
        );
92
93
        $configuration = $this->getConfiguration($configs, $container);
94
95
        // Note: this is where the transformation occurs
96
        $config = $this->processConfiguration($configuration, $configs);
97
98
        // Base services and services overrides
99
        $loader->load('services.yml');
100
        // Security services
101
        $loader->load('security.yml');
102
        // Slots
103
        $loader->load('slot.yml');
104
105
        // Default settings
106
        $this->handleDefaultSettingsLoading($container, $loader);
107
108
        $this->registerRepositoriesConfiguration($config, $container);
109
        $this->registerSiteAccessConfiguration($config, $container);
110
        $this->registerImageMagickConfiguration($config, $container);
111
        $this->registerPageConfiguration($config, $container);
112
113
        // Routing
114
        $this->handleRouting($config, $container, $loader);
115
        // Public API loading
116
        $this->handleApiLoading($container, $loader);
117
        $this->handleTemplating($container, $loader);
118
        $this->handleSessionLoading($container, $loader);
119
        $this->handleCache($config, $container, $loader);
120
        $this->handleLocale($config, $container, $loader);
121
        $this->handleHelpers($config, $container, $loader);
122
        $this->handleImage($config, $container, $loader);
123
124
        // Map settings
125
        $processor = new ConfigurationProcessor($container, 'ezsettings');
126
        $processor->mapConfig($config, $this->getMainConfigParser());
127
128
        if ($this->suggestionCollector->hasSuggestions()) {
129
            $message = '';
130
            $suggestionFormatter = new YamlSuggestionFormatter();
131
            foreach ($this->suggestionCollector->getSuggestions() as $suggestion) {
132
                $message .= $suggestionFormatter->format($suggestion) . "\n\n";
133
            }
134
135
            throw new InvalidArgumentException($message);
136
        }
137
138
        $this->handleSiteAccessesRelation($container);
139
        $this->buildPolicyMap($container);
140
    }
141
142
    /**
143
     * @param array $config
144
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
145
     *
146
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration
147
     */
148
    public function getConfiguration(array $config, ContainerBuilder $container)
149
    {
150
        $configuration = new Configuration($this->getMainConfigParser(), $this->suggestionCollector);
151
        $configuration->setSiteAccessConfigurationFilters($this->siteaccessConfigurationFilters);
152
153
        return $configuration;
154
    }
155
156
    /**
157
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface
158
     */
159
    private function getMainConfigParser()
160
    {
161
        if ($this->mainConfigParser === null) {
162
            foreach ($this->configParsers as $parser) {
163
                if ($parser instanceof SuggestionCollectorAwareInterface) {
164
                    $parser->setSuggestionCollector($this->suggestionCollector);
165
                }
166
            }
167
168
            $this->mainConfigParser = new ConfigParser($this->configParsers);
169
        }
170
171
        return $this->mainConfigParser;
172
    }
173
174
    /**
175
     * Handle default settings.
176
     *
177
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
178
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
179
     */
180
    private function handleDefaultSettingsLoading(ContainerBuilder $container, FileLoader $loader)
181
    {
182
        $loader->load('default_settings.yml');
183
184
        foreach ($this->defaultSettingsCollection as $fileLocation => $files) {
185
            $externalLoader = new Loader\YamlFileLoader($container, new FileLocator($fileLocation));
186
            foreach ($files as $file) {
187
                $externalLoader->load($file);
188
            }
189
        }
190
    }
191
192
    private function registerRepositoriesConfiguration(array $config, ContainerBuilder $container)
193
    {
194
        if (!isset($config['repositories'])) {
195
            $config['repositories'] = array();
196
        }
197
198
        foreach ($config['repositories'] as $name => &$repository) {
199
            if (empty($repository['fields_groups']['list'])) {
200
                $repository['fields_groups']['list'] = $container->getParameter('ezsettings.default.content.field_groups.list');
201
            }
202
        }
203
204
        $container->setParameter('ezpublish.repositories', $config['repositories']);
205
    }
206
207
    private function registerSiteAccessConfiguration(array $config, ContainerBuilder $container)
208
    {
209
        if (!isset($config['siteaccess'])) {
210
            $config['siteaccess'] = array();
211
            $config['siteaccess']['list'] = array('setup');
212
            $config['siteaccess']['default_siteaccess'] = 'setup';
213
            $config['siteaccess']['groups'] = array();
214
            $config['siteaccess']['match'] = null;
215
        }
216
217
        $container->setParameter('ezpublish.siteaccess.list', $config['siteaccess']['list']);
218
        ConfigurationProcessor::setAvailableSiteAccesses($config['siteaccess']['list']);
219
        $container->setParameter('ezpublish.siteaccess.default', $config['siteaccess']['default_siteaccess']);
220
        $container->setParameter('ezpublish.siteaccess.match_config', $config['siteaccess']['match']);
221
222
        // Register siteaccess groups + reverse
223
        $container->setParameter('ezpublish.siteaccess.groups', $config['siteaccess']['groups']);
224
        $groupsBySiteaccess = array();
225 View Code Duplication
        foreach ($config['siteaccess']['groups'] as $groupName => $groupMembers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
226
            foreach ($groupMembers as $member) {
227
                if (!isset($groupsBySiteaccess[$member])) {
228
                    $groupsBySiteaccess[$member] = array();
229
                }
230
231
                $groupsBySiteaccess[$member][] = $groupName;
232
            }
233
        }
234
        $container->setParameter('ezpublish.siteaccess.groups_by_siteaccess', $groupsBySiteaccess);
235
        ConfigurationProcessor::setGroupsBySiteAccess($groupsBySiteaccess);
236
    }
237
238
    private function registerImageMagickConfiguration(array $config, ContainerBuilder $container)
239
    {
240
        if (isset($config['imagemagick'])) {
241
            $container->setParameter('ezpublish.image.imagemagick.enabled', $config['imagemagick']['enabled']);
242
            if ($config['imagemagick']['enabled']) {
243
                $container->setParameter('ezpublish.image.imagemagick.executable_path', dirname($config['imagemagick']['path']));
244
                $container->setParameter('ezpublish.image.imagemagick.executable', basename($config['imagemagick']['path']));
245
            }
246
        }
247
248
        $filters = isset($config['imagemagick']['filters']) ? $config['imagemagick']['filters'] : array();
249
        $filters = $filters + $container->getParameter('ezpublish.image.imagemagick.filters');
250
        $container->setParameter('ezpublish.image.imagemagick.filters', $filters);
251
    }
252
253
    private function registerPageConfiguration(array $config, ContainerBuilder $container)
254
    {
255
        if (isset($config['ezpage']['layouts'])) {
256
            $container->setParameter(
257
                'ezpublish.ezpage.layouts',
258
                $config['ezpage']['layouts'] + $container->getParameter('ezpublish.ezpage.layouts')
259
            );
260
        }
261
        if (isset($config['ezpage']['blocks'])) {
262
            $container->setParameter(
263
                'ezpublish.ezpage.blocks',
264
                $config['ezpage']['blocks'] + $container->getParameter('ezpublish.ezpage.blocks')
265
            );
266
        }
267
        if (isset($config['ezpage']['enabledLayouts'])) {
268
            $container->setParameter(
269
                'ezpublish.ezpage.enabledLayouts',
270
                $config['ezpage']['enabledLayouts'] + $container->getParameter('ezpublish.ezpage.enabledLayouts')
271
            );
272
        }
273
        if (isset($config['ezpage']['enabledBlocks'])) {
274
            $container->setParameter(
275
                'ezpublish.ezpage.enabledBlocks',
276
                $config['ezpage']['enabledBlocks'] + $container->getParameter('ezpublish.ezpage.enabledBlocks')
277
            );
278
        }
279
    }
280
281
    /**
282
     * Handle routing parameters.
283
     *
284
     * @param array $config
285
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
286
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
287
     */
288
    private function handleRouting(array $config, ContainerBuilder $container, FileLoader $loader)
289
    {
290
        $loader->load('routing.yml');
291
        $container->setAlias('router', 'ezpublish.chain_router');
292
293
        if (isset($config['router']['default_router']['non_siteaccess_aware_routes'])) {
294
            $container->setParameter(
295
                'ezpublish.default_router.non_siteaccess_aware_routes',
296
                array_merge(
297
                    $container->getParameter('ezpublish.default_router.non_siteaccess_aware_routes'),
298
                    $config['router']['default_router']['non_siteaccess_aware_routes']
299
                )
300
            );
301
        }
302
    }
303
304
    /**
305
     * Handle public API loading.
306
     *
307
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
308
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
309
     */
310
    private function handleApiLoading(ContainerBuilder $container, FileLoader $loader)
311
    {
312
        // Loading configuration from Core/settings
313
        $coreLoader = new Loader\YamlFileLoader(
314
            $container,
315
            new FileLocator(__DIR__ . '/../../../Publish/Core/settings')
316
        );
317
        $coreLoader->load('repository.yml');
318
        $coreLoader->load('repository/inner.yml');
319
        $coreLoader->load('repository/signalslot.yml');
320
        $coreLoader->load('fieldtype_external_storages.yml');
321
        $coreLoader->load('fieldtypes.yml');
322
        $coreLoader->load('indexable_fieldtypes.yml');
323
        $coreLoader->load('roles.yml');
324
        $coreLoader->load('storage_engines/common.yml');
325
        $coreLoader->load('storage_engines/cache.yml');
326
        $coreLoader->load('storage_engines/legacy.yml');
327
        $coreLoader->load('storage_engines/shortcuts.yml');
328
        $coreLoader->load('search_engines/common.yml');
329
        $coreLoader->load('utils.yml');
330
        $coreLoader->load('io.yml');
331
332
        // Public API services
333
        $loader->load('papi.yml');
334
335
        // Built-in field types
336
        $loader->load('fieldtype_services.yml');
337
338
        // Storage engine
339
        $loader->load('storage_engines.yml');
340
    }
341
342
    /**
343
     * Handle templating parameters.
344
     *
345
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
346
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
347
     */
348
    private function handleTemplating(ContainerBuilder $container, FileLoader $loader)
0 ignored issues
show
Unused Code introduced by
The parameter $container 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...
349
    {
350
        $loader->load('templating.yml');
351
    }
352
353
    /**
354
     * Handle session parameters.
355
     *
356
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
357
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
358
     */
359
    private function handleSessionLoading(ContainerBuilder $container, FileLoader $loader)
0 ignored issues
show
Unused Code introduced by
The parameter $container 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...
360
    {
361
        $loader->load('session.yml');
362
    }
363
364
    /**
365
     * Handle cache parameters.
366
     *
367
     * @param array $config
368
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
369
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
370
     *
371
     * @throws \InvalidArgumentException
372
     */
373
    private function handleCache(array $config, ContainerBuilder $container, FileLoader $loader)
374
    {
375
        $loader->load('cache.yml');
376
377
        $purgeService = null;
0 ignored issues
show
Unused Code introduced by
$purgeService is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
378
        if (isset($config['http_cache']['purge_type'])) {
379
            $container->setParameter('ezpublish.http_cache.purge_type', $config['http_cache']['purge_type']);
380
        }
381
    }
382
383
    /**
384
     * Handle locale parameters.
385
     *
386
     * @param array $config
387
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
388
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
389
     */
390
    private function handleLocale(array $config, ContainerBuilder $container, FileLoader $loader)
391
    {
392
        $loader->load('locale.yml');
393
        $container->setParameter(
394
            'ezpublish.locale.conversion_map',
395
            $config['locale_conversion'] + $container->getParameter('ezpublish.locale.conversion_map')
396
        );
397
    }
398
399
    /**
400
     * Handle helpers.
401
     *
402
     * @param array $config
403
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
404
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
405
     */
406
    private function handleHelpers(array $config, ContainerBuilder $container, FileLoader $loader)
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...
Unused Code introduced by
The parameter $container 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...
407
    {
408
        $loader->load('helpers.yml');
409
    }
410
411
    /**
412
     * Handles relation between SiteAccesses.
413
     * Related SiteAccesses share the same repository and root location id.
414
     *
415
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
416
     */
417
    private function handleSiteAccessesRelation(ContainerBuilder $container)
418
    {
419
        $configResolver = $container->get('ezpublish.config.resolver.core');
420
        $configResolver->setContainer($container);
421
422
        $saRelationMap = array();
423
        $saList = $container->getParameter('ezpublish.siteaccess.list');
424
        // First build the SiteAccess relation map, indexed by repository and rootLocationId.
425
        foreach ($saList as $sa) {
426
            $repository = $configResolver->getParameter('repository', 'ezsettings', $sa);
427
            if (!isset($saRelationMap[$repository])) {
428
                $saRelationMap[$repository] = array();
429
            }
430
431
            $rootLocationId = $configResolver->getParameter('content.tree_root.location_id', 'ezsettings', $sa);
432
            if (!isset($saRelationMap[$repository][$rootLocationId])) {
433
                $saRelationMap[$repository][$rootLocationId] = array();
434
            }
435
            $saRelationMap[$repository][$rootLocationId][] = $sa;
436
        }
437
        $container->setParameter('ezpublish.siteaccess.relation_map', $saRelationMap);
438
439
        // Now build the related SiteAccesses list, based on the relation map.
440
        foreach ($saList as $sa) {
441
            $repository = $configResolver->getParameter('repository', 'ezsettings', $sa);
442
            $rootLocationId = $configResolver->getParameter('content.tree_root.location_id', 'ezsettings', $sa);
443
            $container->setParameter(
444
                "ezsettings.$sa.related_siteaccesses",
445
                $saRelationMap[$repository][$rootLocationId]
446
            );
447
        }
448
    }
449
450
    /**
451
     * @param array $config
452
     * @param ContainerBuilder $container
453
     * @param FileLoader $loader
454
     */
455
    private function handleImage(array $config, ContainerBuilder $container, FileLoader $loader)
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...
Unused Code introduced by
The parameter $container 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...
456
    {
457
        $loader->load('image.yml');
458
    }
459
460
    private function buildPolicyMap(ContainerBuilder $container)
461
    {
462
        $policiesBuilder = new PoliciesConfigBuilder($container);
463
        foreach ($this->policyProviders as $provider) {
464
            $provider->addPolicies($policiesBuilder);
465
        }
466
    }
467
468
    public function prepend(ContainerBuilder $container)
469
    {
470
        // Default settings for FOSHttpCacheBundle
471
        $configFile = __DIR__ . '/../Resources/config/fos_http_cache.yml';
472
        $config = Yaml::parse(file_get_contents($configFile));
473
        $container->prependExtensionConfig('fos_http_cache', $config);
474
        $container->addResource(new FileResource($configFile));
475
    }
476
477
    /**
478
     * Adds a new policy provider to the internal collection.
479
     * One can call this method from a bundle `build()` method.
480
     *
481
     * ```php
482
     * public function build(ContainerBuilder $container)
483
     * {
484
     *     $ezExtension = $container->getExtension('ezpublish');
485
     *     $ezExtension->addPolicyProvider($myPolicyProvider);
486
     * }
487
     * ```
488
     *
489
     * @since 6.0
490
     *
491
     * @param PolicyProviderInterface $policyProvider
492
     */
493
    public function addPolicyProvider(PolicyProviderInterface $policyProvider)
494
    {
495
        $this->policyProviders[] = $policyProvider;
496
    }
497
498
    /**
499
     * Adds a new config parser to the internal collection.
500
     * One can call this method from a bundle `build()` method.
501
     *
502
     * ```php
503
     * public function build(ContainerBuilder $container)
504
     * {
505
     *     $ezExtension = $container->getExtension('ezpublish');
506
     *     $ezExtension->addConfigParser($myConfigParser);
507
     * }
508
     * ```
509
     *
510
     * @since 6.0
511
     *
512
     * @param \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface $configParser
513
     */
514
    public function addConfigParser(ParserInterface $configParser)
515
    {
516
        $this->configParsers[] = $configParser;
517
    }
518
519
    /**
520
     * Adds new default settings to the internal collection.
521
     * One can call this method from a bundle `build()` method.
522
     *
523
     * ```php
524
     * public function build(ContainerBuilder $container)
525
     * {
526
     *     $ezExtension = $container->getExtension('ezpublish');
527
     *     $ezExtension->addDefaultSettings(
528
     *         __DIR__ . '/Resources/config',
529
     *         ['default_settings.yml']
530
     *     );
531
     * }
532
     * ```
533
     *
534
     * @since 6.0
535
     *
536
     * @param string $fileLocation
537
     * @param array $files
538
     */
539
    public function addDefaultSettings($fileLocation, array $files)
540
    {
541
        $this->defaultSettingsCollection[$fileLocation] = $files;
542
    }
543
544
    public function addSiteAccessConfigurationFilter(SiteAccessConfigurationFilter $filter)
545
    {
546
        $this->siteaccessConfigurationFilters[] = $filter;
547
    }
548
}
549