Completed
Push — master ( e81671...a22352 )
by André
93:06 queued 73:42
created

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