Completed
Push — 6.7 ( b24229...92b24b )
by André
36:36 queued 21:55
created

EzPublishCoreExtension::handleImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 3
dl 0
loc 4
rs 10
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 Symfony\Component\Config\Resource\FileResource;
19
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
20
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
21
use Symfony\Component\DependencyInjection\ContainerBuilder;
22
use Symfony\Component\DependencyInjection\Loader;
23
use Symfony\Component\DependencyInjection\Loader\FileLoader;
24
use Symfony\Component\Config\FileLocator;
25
use InvalidArgumentException;
26
use Symfony\Component\Yaml\Yaml;
27
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface;
28
use RuntimeException;
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
    public function __construct(array $configParsers = array())
61
    {
62
        $this->configParsers = $configParsers;
63
        $this->suggestionCollector = new SuggestionCollector();
64
    }
65
66
    public function getAlias()
67
    {
68
        return 'ezpublish';
69
    }
70
71
    /**
72
     * Loads a specific configuration.
73
     *
74
     * @param mixed[] $configs An array of configuration values
75
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container A ContainerBuilder instance
76
     *
77
     * @throws \InvalidArgumentException When provided tag is not defined in this extension
78
     *
79
     * @api
80
     */
81
    public function load(array $configs, ContainerBuilder $container)
82
    {
83
        $loader = new Loader\YamlFileLoader(
84
            $container,
85
            new FileLocator(__DIR__ . '/../Resources/config')
86
        );
87
88
        $configuration = $this->getConfiguration($configs, $container);
89
90
        // Note: this is where the transformation occurs
91
        $config = $this->processConfiguration($configuration, $configs);
92
93
        // Base services and services overrides
94
        $loader->load('services.yml');
95
        // Security services
96
        $loader->load('security.yml');
97
        // Slots
98
        $loader->load('slot.yml');
99
100
        // Default settings
101
        $this->handleDefaultSettingsLoading($container, $loader);
102
103
        $this->registerRepositoriesConfiguration($config, $container);
104
        $this->registerSiteAccessConfiguration($config, $container);
105
        $this->registerImageMagickConfiguration($config, $container);
106
        $this->registerPageConfiguration($config, $container);
107
108
        // Routing
109
        $this->handleRouting($config, $container, $loader);
110
        // Public API loading
111
        $this->handleApiLoading($container, $loader);
112
        $this->handleTemplating($container, $loader);
113
        $this->handleSessionLoading($container, $loader);
114
        $this->handleCache($config, $container, $loader);
115
        $this->handleLocale($config, $container, $loader);
116
        $this->handleHelpers($config, $container, $loader);
117
        $this->handleImage($config, $container, $loader);
118
119
        // Map settings
120
        $processor = new ConfigurationProcessor($container, 'ezsettings');
121
        $processor->mapConfig($config, $this->getMainConfigParser());
122
123
        if ($this->suggestionCollector->hasSuggestions()) {
124
            $message = '';
125
            $suggestionFormatter = new YamlSuggestionFormatter();
126
            foreach ($this->suggestionCollector->getSuggestions() as $suggestion) {
127
                $message .= $suggestionFormatter->format($suggestion) . "\n\n";
128
            }
129
130
            throw new InvalidArgumentException($message);
131
        }
132
133
        $this->handleSiteAccessesRelation($container);
134
        $this->buildPolicyMap($container);
135
    }
136
137
    /**
138
     * @param array $config
139
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
140
     *
141
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration
142
     */
143
    public function getConfiguration(array $config, ContainerBuilder $container)
144
    {
145
        return new Configuration($this->getMainConfigParser(), $this->suggestionCollector);
146
    }
147
148
    /**
149
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface
150
     */
151
    private function getMainConfigParser()
152
    {
153
        if ($this->mainConfigParser === null) {
154
            foreach ($this->configParsers as $parser) {
155
                if ($parser instanceof SuggestionCollectorAwareInterface) {
156
                    $parser->setSuggestionCollector($this->suggestionCollector);
157
                }
158
            }
159
160
            $this->mainConfigParser = new ConfigParser($this->configParsers);
161
        }
162
163
        return $this->mainConfigParser;
164
    }
165
166
    /**
167
     * Handle default settings.
168
     *
169
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
170
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
171
     */
172
    private function handleDefaultSettingsLoading(ContainerBuilder $container, FileLoader $loader)
173
    {
174
        $loader->load('default_settings.yml');
175
176
        foreach ($this->defaultSettingsCollection as $fileLocation => $files) {
177
            $externalLoader = new Loader\YamlFileLoader($container, new FileLocator($fileLocation));
178
            foreach ($files as $file) {
179
                $externalLoader->load($file);
180
            }
181
        }
182
    }
183
184
    private function registerRepositoriesConfiguration(array $config, ContainerBuilder $container)
185
    {
186
        if (!isset($config['repositories'])) {
187
            $config['repositories'] = array();
188
        }
189
190
        foreach ($config['repositories'] as $name => &$repository) {
191
            if (empty($repository['fields_groups']['list'])) {
192
                $repository['fields_groups']['list'] = $container->getParameter('ezsettings.default.content.field_groups.list');
193
            }
194
        }
195
196
        $container->setParameter('ezpublish.repositories', $config['repositories']);
197
    }
198
199
    private function registerSiteAccessConfiguration(array $config, ContainerBuilder $container)
200
    {
201
        if (!isset($config['siteaccess'])) {
202
            $config['siteaccess'] = array();
203
            $config['siteaccess']['list'] = array('setup');
204
            $config['siteaccess']['default_siteaccess'] = 'setup';
205
            $config['siteaccess']['groups'] = array();
206
            $config['siteaccess']['match'] = null;
207
        }
208
209
        $container->setParameter('ezpublish.siteaccess.list', $config['siteaccess']['list']);
210
        ConfigurationProcessor::setAvailableSiteAccesses($config['siteaccess']['list']);
211
        $container->setParameter('ezpublish.siteaccess.default', $config['siteaccess']['default_siteaccess']);
212
        $container->setParameter('ezpublish.siteaccess.match_config', $config['siteaccess']['match']);
213
214
        // Register siteaccess groups + reverse
215
        $container->setParameter('ezpublish.siteaccess.groups', $config['siteaccess']['groups']);
216
        $groupsBySiteaccess = array();
217 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...
218
            foreach ($groupMembers as $member) {
219
                if (!isset($groupsBySiteaccess[$member])) {
220
                    $groupsBySiteaccess[$member] = array();
221
                }
222
223
                $groupsBySiteaccess[$member][] = $groupName;
224
            }
225
        }
226
        $container->setParameter('ezpublish.siteaccess.groups_by_siteaccess', $groupsBySiteaccess);
227
        ConfigurationProcessor::setGroupsBySiteAccess($groupsBySiteaccess);
228
    }
229
230
    private function registerImageMagickConfiguration(array $config, ContainerBuilder $container)
231
    {
232
        if (isset($config['imagemagick'])) {
233
            $container->setParameter('ezpublish.image.imagemagick.enabled', $config['imagemagick']['enabled']);
234
            if ($config['imagemagick']['enabled']) {
235
                $container->setParameter('ezpublish.image.imagemagick.executable_path', dirname($config['imagemagick']['path']));
236
                $container->setParameter('ezpublish.image.imagemagick.executable', basename($config['imagemagick']['path']));
237
            }
238
        }
239
240
        $filters = isset($config['imagemagick']['filters']) ? $config['imagemagick']['filters'] : array();
241
        $filters = $filters + $container->getParameter('ezpublish.image.imagemagick.filters');
242
        $container->setParameter('ezpublish.image.imagemagick.filters', $filters);
243
    }
244
245
    private function registerPageConfiguration(array $config, ContainerBuilder $container)
246
    {
247
        if (isset($config['ezpage']['layouts'])) {
248
            $container->setParameter(
249
                'ezpublish.ezpage.layouts',
250
                $config['ezpage']['layouts'] + $container->getParameter('ezpublish.ezpage.layouts')
251
            );
252
        }
253
        if (isset($config['ezpage']['blocks'])) {
254
            $container->setParameter(
255
                'ezpublish.ezpage.blocks',
256
                $config['ezpage']['blocks'] + $container->getParameter('ezpublish.ezpage.blocks')
257
            );
258
        }
259
        if (isset($config['ezpage']['enabledLayouts'])) {
260
            $container->setParameter(
261
                'ezpublish.ezpage.enabledLayouts',
262
                $config['ezpage']['enabledLayouts'] + $container->getParameter('ezpublish.ezpage.enabledLayouts')
263
            );
264
        }
265
        if (isset($config['ezpage']['enabledBlocks'])) {
266
            $container->setParameter(
267
                'ezpublish.ezpage.enabledBlocks',
268
                $config['ezpage']['enabledBlocks'] + $container->getParameter('ezpublish.ezpage.enabledBlocks')
269
            );
270
        }
271
    }
272
273
    /**
274
     * Handle routing parameters.
275
     *
276
     * @param array $config
277
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
278
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
279
     */
280
    private function handleRouting(array $config, ContainerBuilder $container, FileLoader $loader)
281
    {
282
        $loader->load('routing.yml');
283
        $container->setAlias('router', 'ezpublish.chain_router');
284
285
        if (isset($config['router']['default_router']['non_siteaccess_aware_routes'])) {
286
            $container->setParameter(
287
                'ezpublish.default_router.non_siteaccess_aware_routes',
288
                array_merge(
289
                    $container->getParameter('ezpublish.default_router.non_siteaccess_aware_routes'),
290
                    $config['router']['default_router']['non_siteaccess_aware_routes']
291
                )
292
            );
293
        }
294
    }
295
296
    /**
297
     * Handle public API loading.
298
     *
299
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
300
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
301
     */
302
    private function handleApiLoading(ContainerBuilder $container, FileLoader $loader)
303
    {
304
        // Loading configuration from Core/settings
305
        $coreLoader = new Loader\YamlFileLoader(
306
            $container,
307
            new FileLocator(__DIR__ . '/../../../Publish/Core/settings')
308
        );
309
        $coreLoader->load('repository.yml');
310
        $coreLoader->load('fieldtype_external_storages.yml');
311
        $coreLoader->load('fieldtypes.yml');
312
        $coreLoader->load('indexable_fieldtypes.yml');
313
        $coreLoader->load('roles.yml');
314
        $coreLoader->load('storage_engines/common.yml');
315
        $coreLoader->load('storage_engines/cache.yml');
316
        $coreLoader->load('storage_engines/legacy.yml');
317
        $coreLoader->load('storage_engines/shortcuts.yml');
318
        $coreLoader->load('search_engines/common.yml');
319
        $coreLoader->load('utils.yml');
320
        $coreLoader->load('io.yml');
321
322
        // Public API services
323
        $loader->load('papi.yml');
324
325
        // Built-in field types
326
        $loader->load('fieldtype_services.yml');
327
328
        // Storage engine
329
        $loader->load('storage_engines.yml');
330
    }
331
332
    /**
333
     * Handle templating parameters.
334
     *
335
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
336
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
337
     */
338
    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...
339
    {
340
        $loader->load('templating.yml');
341
    }
342
343
    /**
344
     * Handle session parameters.
345
     *
346
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
347
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
348
     */
349
    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...
350
    {
351
        $loader->load('session.yml');
352
    }
353
354
    /**
355
     * Handle cache parameters.
356
     *
357
     * @param array $config
358
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
359
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
360
     *
361
     * @throws \InvalidArgumentException
362
     */
363
    private function handleCache(array $config, ContainerBuilder $container, FileLoader $loader)
364
    {
365
        $loader->load('cache.yml');
366
367
        if (isset($config['http_cache']['purge_type'])) {
368
            switch ($config['http_cache']['purge_type']) {
369
                case 'local':
370
                    $purgeService = 'ezpublish.http_cache.purge_client.local';
371
                    break;
372
                case 'http':
373
                    $purgeService = 'ezpublish.http_cache.purge_client.fos';
374
                    break;
375
                default:
376
                    if (!$container->has($config['http_cache']['purge_type'])) {
377
                        throw new \InvalidArgumentException("Invalid ezpublish.http_cache.purge_type. Can be 'single', 'multiple' or a valid service identifier implementing PurgeClientInterface.");
378
                    }
379
380
                    $purgeService = $config['http_cache']['purge_type'];
381
            }
382
383
            $container->setAlias('ezpublish.http_cache.purge_client', $purgeService);
384
        }
385
    }
386
387
    /**
388
     * Handle locale parameters.
389
     *
390
     * @param array $config
391
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
392
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
393
     */
394
    private function handleLocale(array $config, ContainerBuilder $container, FileLoader $loader)
395
    {
396
        $loader->load('locale.yml');
397
        $container->setParameter(
398
            'ezpublish.locale.conversion_map',
399
            $config['locale_conversion'] + $container->getParameter('ezpublish.locale.conversion_map')
400
        );
401
    }
402
403
    /**
404
     * Handle helpers.
405
     *
406
     * @param array $config
407
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
408
     * @param \Symfony\Component\DependencyInjection\Loader\FileLoader $loader
409
     */
410
    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...
411
    {
412
        $loader->load('helpers.yml');
413
    }
414
415
    /**
416
     * Handles relation between SiteAccesses.
417
     * Related SiteAccesses share the same repository and root location id.
418
     *
419
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
420
     */
421
    private function handleSiteAccessesRelation(ContainerBuilder $container)
422
    {
423
        $configResolver = $container->get('ezpublish.config.resolver.core');
424
        $configResolver->setContainer($container);
425
426
        $saRelationMap = array();
427
        $saList = $container->getParameter('ezpublish.siteaccess.list');
428
        // First build the SiteAccess relation map, indexed by repository and rootLocationId.
429
        foreach ($saList as $sa) {
430
            $repository = $configResolver->getParameter('repository', 'ezsettings', $sa);
431
            if (!isset($saRelationMap[$repository])) {
432
                $saRelationMap[$repository] = array();
433
            }
434
435
            $rootLocationId = $configResolver->getParameter('content.tree_root.location_id', 'ezsettings', $sa);
436
            if (!isset($saRelationMap[$repository][$rootLocationId])) {
437
                $saRelationMap[$repository][$rootLocationId] = array();
438
            }
439
            $saRelationMap[$repository][$rootLocationId][] = $sa;
440
        }
441
        $container->setParameter('ezpublish.siteaccess.relation_map', $saRelationMap);
442
443
        // Now build the related SiteAccesses list, based on the relation map.
444
        foreach ($saList as $sa) {
445
            $repository = $configResolver->getParameter('repository', 'ezsettings', $sa);
446
            $rootLocationId = $configResolver->getParameter('content.tree_root.location_id', 'ezsettings', $sa);
447
            $container->setParameter(
448
                "ezsettings.$sa.related_siteaccesses",
449
                $saRelationMap[$repository][$rootLocationId]
450
            );
451
        }
452
    }
453
454
    /**
455
     * @param array $config
456
     * @param ContainerBuilder $container
457
     * @param FileLoader $loader
458
     */
459
    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...
460
    {
461
        $loader->load('image.yml');
462
    }
463
464
    private function buildPolicyMap(ContainerBuilder $container)
465
    {
466
        $policiesBuilder = new PoliciesConfigBuilder($container);
467
        foreach ($this->policyProviders as $provider) {
468
            $provider->addPolicies($policiesBuilder);
469
        }
470
    }
471
472 View Code Duplication
    public function prepend(ContainerBuilder $container)
473
    {
474
        // Default settings for FOSHttpCacheBundle
475
        $configFile = __DIR__ . '/../Resources/config/fos_http_cache.yml';
476
        $config = Yaml::parse(file_get_contents($configFile));
477
        $container->prependExtensionConfig('fos_http_cache', $config);
478
        $container->addResource(new FileResource($configFile));
479
    }
480
481
    /**
482
     * Adds a new policy provider to the internal collection.
483
     * One can call this method from a bundle `build()` method.
484
     *
485
     * ```php
486
     * public function build(ContainerBuilder $container)
487
     * {
488
     *     $ezExtension = $container->getExtension('ezpublish');
489
     *     $ezExtension->addPolicyProvider($myPolicyProvider);
490
     * }
491
     * ```
492
     *
493
     * @since 6.0
494
     *
495
     * @param PolicyProviderInterface $policyProvider
496
     */
497
    public function addPolicyProvider(PolicyProviderInterface $policyProvider)
498
    {
499
        $this->policyProviders[] = $policyProvider;
500
    }
501
502
    /**
503
     * Adds a new config parser to the internal collection.
504
     * One can call this method from a bundle `build()` method.
505
     *
506
     * ```php
507
     * public function build(ContainerBuilder $container)
508
     * {
509
     *     $ezExtension = $container->getExtension('ezpublish');
510
     *     $ezExtension->addConfigParser($myConfigParser);
511
     * }
512
     * ```
513
     *
514
     * @since 6.0
515
     *
516
     * @param \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\ParserInterface $configParser
517
     */
518
    public function addConfigParser(ParserInterface $configParser)
519
    {
520
        if ($this->mainConfigParser !== null) {
521
            throw new RuntimeException('Main config parser is already instantiated');
522
        }
523
524
        $this->configParsers[] = $configParser;
525
    }
526
527
    /**
528
     * Adds new default settings to the internal collection.
529
     * One can call this method from a bundle `build()` method.
530
     *
531
     * ```php
532
     * public function build(ContainerBuilder $container)
533
     * {
534
     *     $ezExtension = $container->getExtension('ezpublish');
535
     *     $ezExtension->addDefaultSettings(
536
     *         __DIR__ . '/Resources/config',
537
     *         ['default_settings.yml']
538
     *     );
539
     * }
540
     * ```
541
     *
542
     * @since 6.0
543
     *
544
     * @param string $fileLocation
545
     * @param array $files
546
     */
547
    public function addDefaultSettings($fileLocation, array $files)
548
    {
549
        $this->defaultSettingsCollection[$fileLocation] = $files;
550
    }
551
}
552