Completed
Push — master ( 2945ff...8605b2 )
by Łukasz
14:21
created

ConfigurationProcessor   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 178
rs 10
c 0
b 0
f 0
wmc 16
lcom 2
cbo 4

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setAvailableSiteAccesses() 0 4 1
A setGroupsBySiteAccess() 0 4 1
A setAvailableSiteAccessGroups() 0 4 1
B mapConfig() 0 24 7
A mapSetting() 0 4 1
A mapConfigArray() 0 4 1
A buildContextualizer() 0 11 1
A setContextualizer() 0 4 1
A getContextualizer() 0 4 1
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware;
8
9
use InvalidArgumentException;
10
use Symfony\Component\DependencyInjection\ContainerInterface;
11
12
/**
13
 * Processor for SiteAccess aware configuration processing.
14
 * Use it when you want to map SiteAccess dependent semantic configuration to internal settings, readable
15
 * with the ConfigResolver.
16
 */
17
class ConfigurationProcessor
18
{
19
    /**
20
     * Registered configuration scopes.
21
     *
22
     * @var array
23
     */
24
    protected static $availableSiteAccesses = [];
25
26
    /**
27
     * Registered scope groups names, indexed by scope.
28
     *
29
     * @var array
30
     */
31
    protected static $groupsBySiteAccess = [];
32
33
    /**
34
     * Keys are Site Access group names and values are an array of Site Access name which belongs to this group.
35
     *
36
     * @var array
37
     */
38
    protected static $availableSiteAccessGroups = [];
39
40
    /**
41
     * Name of the node under which scope based (semantic) configuration takes place.
42
     *
43
     * @var string
44
     */
45
    protected $scopeNodeName;
46
47
    /** @var \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface */
48
    protected $contextualizer;
49
50
    public function __construct(ContainerInterface $containerBuilder, $namespace, $siteAcccessNodeName = 'system')
51
    {
52
        $this->contextualizer = $this->buildContextualizer($containerBuilder, $namespace, $siteAcccessNodeName);
53
    }
54
55
    /**
56
     * Injects available SiteAccesses.
57
     *
58
     * Important: Available SiteAccesses need to be set before ConfigurationProcessor to be constructed by a bundle
59
     * to set its configuration up.
60
     *
61
     * @param string[] $availableSiteAccesses
62
     */
63
    public static function setAvailableSiteAccesses(array $availableSiteAccesses)
64
    {
65
        static::$availableSiteAccesses = $availableSiteAccesses;
66
    }
67
68
    /**
69
     * Injects available scope groups, indexed by scope.
70
     *
71
     * Important: Groups need to be set before ConfigurationProcessor to be constructed by a bundle
72
     * to set its configuration up.
73
     *
74
     * @param array $groupsBySiteAccess Registered scope groups names, indexed by scope.
75
     */
76
    public static function setGroupsBySiteAccess(array $groupsBySiteAccess)
77
    {
78
        static::$groupsBySiteAccess = $groupsBySiteAccess;
79
    }
80
81
    /**
82
     * @param array<string, array<string>> $availableSiteAccessGroups keys are Site Access group names and values are
83
     * an array of Site Access name which belongs to this group
84
     */
85
    public static function setAvailableSiteAccessGroups(array $availableSiteAccessGroups)
86
    {
87
        static::$availableSiteAccessGroups = $availableSiteAccessGroups;
88
    }
89
90
    /**
91
     * Triggers mapping process between semantic and internal configuration.
92
     *
93
     * @param array $config Parsed semantic configuration
94
     * @param ConfigurationMapperInterface|callable $mapper Mapper to use. Can be either an instance of ConfigurationMapper or a callable.
95
     *                                                      HookableConfigurationMapper can also be used. In this case, preMap()
96
     *                                                      and postMap() will be also called respectively before and after the mapping loop.
97
     *
98
     *                                                      If $mapper is a callable, the same arguments as defined in the signature
99
     *                                                      defined in ConfigurationMapper interface will be passed:
100
     *                                                      `array $scopeSettings, $currentScope, ContextualizerInterface $contextualizer`
101
     *
102
     * @throws \InvalidArgumentException
103
     */
104
    public function mapConfig(array $config, $mapper)
105
    {
106
        $mapperCallable = is_callable($mapper);
107
        if (!$mapperCallable && !$mapper instanceof ConfigurationMapperInterface) {
108
            throw new InvalidArgumentException('Configuration mapper must either be a callable or an instance of ConfigurationMapper.');
109
        }
110
111
        if ($mapper instanceof HookableConfigurationMapperInterface) {
112
            $mapper->preMap($config, $this->contextualizer);
113
        }
114
115
        $scopeNodeName = $this->contextualizer->getSiteAccessNodeName();
116
        foreach ($config[$scopeNodeName] as $currentScope => &$scopeSettings) {
117
            if ($mapperCallable) {
118
                call_user_func_array($mapper, [&$scopeSettings, $currentScope, $this->contextualizer]);
119
            } else {
120
                $mapper->mapConfig($scopeSettings, $currentScope, $this->contextualizer);
121
            }
122
        }
123
124
        if ($mapper instanceof HookableConfigurationMapperInterface) {
125
            $mapper->postMap($config, $this->contextualizer);
126
        }
127
    }
128
129
    /**
130
     * Proxy to `Contextualizer::mapSetting()`.
131
     *
132
     * @see ContextualizerInterface::mapSetting()
133
     *
134
     * @param string $id Id of the setting to map.
135
     * @param array $config Full semantic configuration array for current bundle.
136
     */
137
    public function mapSetting($id, array $config)
138
    {
139
        $this->contextualizer->mapSetting($id, $config);
140
    }
141
142
    /**
143
     * Proxy to `Contextualizer::mapConfigArray()`.
144
     *
145
     * @see ContextualizerInterface::mapConfigArray()
146
     *
147
     * @param string $id Id of the setting array to map.
148
     * @param array $config Full semantic configuration array for current bundle.
149
     * @param int $options Bit mask of options (See constants of `ContextualizerInterface`)
150
     */
151
    public function mapConfigArray($id, array $config, $options = 0)
152
    {
153
        $this->contextualizer->mapConfigArray($id, $config, $options);
154
    }
155
156
    /**
157
     * Builds configuration contextualizer (I know, sounds obvious...).
158
     * Override this method if you want to use your own contextualizer class.
159
     *
160
     * static::$scopes and static::$groupsByScope must be injected first.
161
     *
162
     * @param string $namespace
163
     * @param string $siteAccessNodeName
164
     *
165
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface
166
     */
167
    protected function buildContextualizer(ContainerInterface $containerBuilder, $namespace, $siteAccessNodeName)
168
    {
169
        return new Contextualizer(
170
            $containerBuilder,
171
            $namespace,
172
            $siteAccessNodeName,
173
            static::$availableSiteAccesses,
174
            static::$availableSiteAccessGroups,
175
            static::$groupsBySiteAccess
176
        );
177
    }
178
179
    /**
180
     * @param \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface $contextualizer
181
     */
182
    public function setContextualizer(ContextualizerInterface $contextualizer)
183
    {
184
        $this->contextualizer = $contextualizer;
185
    }
186
187
    /**
188
     * @return \eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface
189
     */
190
    public function getContextualizer()
191
    {
192
        return $this->contextualizer;
193
    }
194
}
195