Passed
Branch master (4e035c)
by Roni
02:10
created

Configuration::getRootNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the XiideaEasyAuditBundle package.
5
 *
6
 * (c) Xiidea <http://www.xiidea.net>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Xiidea\EasyAuditBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
use Symfony\Component\Config\Definition\ConfigurationInterface;
17
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
18
19
/**
20
 * This is the class that validates and merges configuration from your app/config files.
21
 *
22
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
23
 */
24
class Configuration implements ConfigurationInterface
25
{
26
    const ROOT_NODE_NAME = 'xiidea_easy_audit';
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function getConfigTreeBuilder()
32
    {
33
        $treeBuilder = new TreeBuilder(self::ROOT_NODE_NAME);
34
35
        $rootNode = $this->getRootNode($treeBuilder);
36
37
        $this->addRequiredConfigs($rootNode);
38
        $this->addDefaultServices($rootNode);
39
        $this->addOptionalConfigs($rootNode);
40
        $this->addChannelHandlers($rootNode);
41
42
        return $treeBuilder;
43
    }
44
45
    /**
46
     * @param ArrayNodeDefinition $rootNode
47
     */
48
    private function addRequiredConfigs(ArrayNodeDefinition $rootNode)
49
    {
50
        $rootNode
51
            ->children()
52
                ->scalarNode('user_property')->isRequired()->end()
53
                ->scalarNode('audit_log_class')->cannotBeOverwritten()->isRequired()->cannotBeEmpty()->end()
0 ignored issues
show
Bug introduced by
The method scalarNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
                ->/** @scrutinizer ignore-call */ scalarNode('audit_log_class')->cannotBeOverwritten()->isRequired()->cannotBeEmpty()->end()
Loading history...
54
                ->scalarNode('entity_class')->cannotBeOverwritten()
55
//                    ->setDeprecated('The "%node%" option is deprecated since XiideaEasyAuditBundle 1.4.10. and will not be supported anymore in 2.0. Use "audit_log_class" instead.')
56
                ->end()
57
            ->end();
58
    }
59
60
    /**
61
     * @param ArrayNodeDefinition $rootNode
62
     */
63
    private function addDefaultServices(ArrayNodeDefinition $rootNode)
64
    {
65
        $rootNode
66
            ->children()
67
                ->scalarNode('resolver')->defaultValue('xiidea.easy_audit.default_event_resolver')->end()
68
                ->scalarNode('doctrine_event_resolver')
69
                    ->defaultValue(null)
70
                ->end()
71
                ->scalarNode('entity_event_resolver')
72
                    ->defaultValue(null)
73
//                    ->setDeprecated('The "%node%" option is deprecated since XiideaEasyAuditBundle 1.4.10. and will not be supported anymore in 2.0. Use "doctrine_event_resolver" instead.')
74
                ->end()
75
                ->booleanNode('default_logger')->defaultValue(true)->end()
76
            ->end();
77
    }
78
79
    /**
80
     * @param ArrayNodeDefinition $rootNode
81
     */
82
    private function addOptionalConfigs(ArrayNodeDefinition $rootNode)
83
    {
84
        $rootNode
85
            ->children()
86
                ->variableNode('doctrine_objects')
87
                    ->defaultValue(array())
88
                ->end()
89
                ->variableNode('doctrine_entities')
0 ignored issues
show
Bug introduced by
The method variableNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
                ->/** @scrutinizer ignore-call */ variableNode('doctrine_entities')
Loading history...
90
                    ->defaultValue(array())
91
//                    ->setDeprecated('The "%node%" option is deprecated since XiideaEasyAuditBundle 1.4.10. and will not be supported anymore in 2.0. Use "doctrine_objects" instead.')
92
                ->end()
93
                ->variableNode('events')->defaultValue(array())->end()
94
                ->variableNode('custom_resolvers')->defaultValue(array())->end()
95
            ->end();
96
    }
97
98
    /**
99
     * @param ArrayNodeDefinition $rootNode
100
     */
101
    private function addChannelHandlers(ArrayNodeDefinition $rootNode)
102
    {
103
        $rootNode
104
            ->fixXmlConfig('loggerChannel')
105
            ->children()
106
                ->arrayNode('logger_channel')
107
                    ->canBeUnset()
108
                    ->useAttributeAsKey('name')
109
                    ->prototype('array')
110
                    ->fixXmlConfig('channel', 'elements')
0 ignored issues
show
Bug introduced by
The method fixXmlConfig() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. It seems like you code against a sub-type of Symfony\Component\Config...\Builder\NodeDefinition such as Symfony\Component\Config...der\ArrayNodeDefinition. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
                    ->/** @scrutinizer ignore-call */ fixXmlConfig('channel', 'elements')
Loading history...
111
                        ->canBeUnset()
112
                        ->beforeNormalization()->ifString()->then($this->changeToArrayFromString())->end()
113
                        ->beforeNormalization()->ifTrue($this->isIndexedArray())->then($this->changeToAssoc())->end()
114
                        ->validate()->ifTrue($this->isEmpty())->thenUnset()->end()
115
                        ->validate()->always($this->getChannelTypeValidator())->end()
116
                        ->children()
117
                            ->scalarNode('type')->validate()
118
                                ->ifNotInArray(array('inclusive', 'exclusive'))
119
                                ->thenInvalid('The type of channels has to be inclusive or exclusive')->end()->end()
120
                            ->arrayNode('elements')->prototype('scalar')->end()->end()->end()
121
                        ->end()
122
                    ->end()
123
                ->end()
124
            ->end();
125
    }
126
127
    /**
128
     * @return \Closure
129
     */
130
    private function getChannelTypeValidator()
131
    {
132
        return function ($v) {
133
            $isExclusiveList = isset($v['type']) ? 'exclusive' === $v['type'] : null;
134
            $elements = array();
135
136
            foreach ($v['elements'] as $element) {
137
                Configuration::appendChannelTypes($element, $isExclusiveList, $elements);
138
            }
139
140
            return array('type' => $isExclusiveList ? 'exclusive' : 'inclusive', 'elements' => $elements);
141
        };
142
    }
143
144
    /**
145
     * @param bool $invalid
146
     *
147
     * @throws InvalidConfigurationException
148
     */
149
    public static function throwExceptionOnInvalid($invalid)
150
    {
151
        if (!$invalid) {
152
            return;
153
        }
154
155
        throw new InvalidConfigurationException(
156
            'Cannot combine exclusive/inclusive definitions in channels list'
157
        );
158
    }
159
160
    public static function appendChannelTypes($element, &$isExclusiveList, &$elements = array())
161
    {
162
        $isExclusiveItem = 0 === strpos($element, '!');
163
164
        self::throwExceptionOnInvalid(!$isExclusiveItem === $isExclusiveList);
165
166
        $elements[] = $isExclusiveItem ? substr($element, 1) : $element;
167
        $isExclusiveList = $isExclusiveItem;
168
    }
169
170
    /**
171
     * @return \Closure
172
     */
173
    private function isIndexedArray()
174
    {
175
        return function ($v) {
176
            return is_array($v) && is_numeric(key($v));
177
        };
178
    }
179
180
    /**
181
     * @return \Closure
182
     */
183
    private function changeToAssoc()
184
    {
185
        return function ($v) {
186
            return array('elements' => $v);
187
        };
188
    }
189
190
    /**
191
     * @return \Closure
192
     */
193
    private function changeToArrayFromString()
194
    {
195
        return function ($v) {
196
            return array('elements' => array($v));
197
        };
198
    }
199
200
    /**
201
     * @return \Closure
202
     */
203
    private function isEmpty()
204
    {
205
        return function ($v) {
206
            return empty($v);
207
        };
208
    }
209
210
    /**
211
     * @param TreeBuilder $treeBuilder
212
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
213
     */
214
    protected function getRootNode($treeBuilder)
215
    {
216
        if (method_exists($treeBuilder, 'getRootNode')) {
217
            return $treeBuilder->getRootNode();
218
        }
219
220
        return $treeBuilder->root(self::ROOT_NODE_NAME);
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Component\Config...der\TreeBuilder::root() has been deprecated: since Symfony 4.3, pass the root name to the constructor instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

220
        return /** @scrutinizer ignore-deprecated */ $treeBuilder->root(self::ROOT_NODE_NAME);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
221
    }
222
}
223