Completed
Push — master ( 60f5be...0d3c0c )
by Kamil
24:02
created

Configuration::addResourcesSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 72
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 72
rs 9.102
c 0
b 0
f 0
nc 1
cc 1
eloc 69
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Bundle\ResourceBundle\DependencyInjection;
13
14
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
15
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
16
use Sylius\Component\Resource\Factory\Factory;
17
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
18
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
19
use Symfony\Component\Config\Definition\ConfigurationInterface;
20
21
/**
22
 * This class contains the configuration information for the bundle.
23
 *
24
 * This information is solely responsible for how the different configuration
25
 * sections are normalized, and merged.
26
 *
27
 * @author Paweł Jędrzejewski <[email protected]>
28
 */
29
class Configuration implements ConfigurationInterface
30
{
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function getConfigTreeBuilder()
35
    {
36
        $treeBuilder = new TreeBuilder();
37
        $rootNode = $treeBuilder->root('sylius_resource');
38
39
        $this->addResourcesSection($rootNode);
40
        $this->addSettingsSection($rootNode);
41
        $this->addTranslationsSection($rootNode);
42
        $this->addDriversSection($rootNode);
43
44
        $rootNode
45
            ->children()
46
                ->scalarNode('authorization_checker')
47
                    ->defaultValue('sylius.resource_controller.authorization_checker.disabled')
48
                    ->cannotBeEmpty()
49
                ->end()
50
            ->end()
51
        ;
52
53
        return $treeBuilder;
54
    }
55
56
    /**
57
     * @param ArrayNodeDefinition $node
58
     */
59
    private function addResourcesSection(ArrayNodeDefinition $node)
60
    {
61
        $node
62
            ->children()
63
                ->arrayNode('resources')
64
                    ->useAttributeAsKey('name')
65
                    ->prototype('array')
66
                        ->children()
67
                            ->scalarNode('driver')->defaultValue(SyliusResourceBundle::DRIVER_DOCTRINE_ORM)->end()
68
                            ->variableNode('options')->end()
69
                            ->scalarNode('templates')->cannotBeEmpty()->end()
70
                            ->arrayNode('classes')
71
                                ->isRequired()
72
                                ->addDefaultsIfNotSet()
73
                                ->children()
74
                                    ->scalarNode('model')->isRequired()->cannotBeEmpty()->end()
75
                                    ->scalarNode('interface')->cannotBeEmpty()->end()
76
                                    ->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
77
                                    ->scalarNode('repository')->cannotBeEmpty()->end()
78
                                    ->scalarNode('factory')->defaultValue(Factory::class)->end()
79
                                    ->arrayNode('form')
80
                                        ->prototype('scalar')->end()
81
                                    ->end()
82
                                ->end()
83
                            ->end()
84
                            ->arrayNode('validation_groups')
85
                                ->addDefaultsIfNotSet()
86
                                ->children()
87
                                    ->arrayNode('default')
88
                                        ->prototype('scalar')->end()
89
                                        ->defaultValue([])
90
                                    ->end()
91
                                ->end()
92
                            ->end()
93
                            ->arrayNode('translation')
94
                                ->children()
95
                                    ->variableNode('options')->end()
96
                                    ->arrayNode('classes')
97
                                        ->isRequired()
98
                                        ->addDefaultsIfNotSet()
99
                                        ->children()
100
                                            ->scalarNode('model')->isRequired()->cannotBeEmpty()->end()
101
                                            ->scalarNode('interface')->cannotBeEmpty()->end()
102
                                            ->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
103
                                            ->scalarNode('repository')->cannotBeEmpty()->end()
104
                                            ->scalarNode('factory')->defaultValue(Factory::class)->end()
105
                                            ->arrayNode('form')
106
                                                ->prototype('scalar')->end()
107
                                            ->end()
108
                                        ->end()
109
                                    ->end()
110
                                    ->arrayNode('validation_groups')
111
                                        ->addDefaultsIfNotSet()
112
                                        ->children()
113
                                            ->arrayNode('default')
114
                                                ->prototype('scalar')->end()
115
                                                ->defaultValue([])
116
                                            ->end()
117
                                        ->end()
118
                                    ->end()
119
                                    ->arrayNode('fields')
120
                                        ->prototype('scalar')->end()
121
                                        ->defaultValue([])
122
                                    ->end()
123
                                ->end()
124
                            ->end()
125
                        ->end()
126
                    ->end()
127
                ->end()
128
            ->end()
129
        ;
130
    }
131
132
    /**
133
     * @param $node
134
     */
135
    private function addSettingsSection(ArrayNodeDefinition $node)
136
    {
137
        $node
138
            ->children()
139
                ->arrayNode('settings')
140
                    ->addDefaultsIfNotSet()
141
                    ->children()
142
                        ->variableNode('paginate')->defaultNull()->end()
143
                        ->variableNode('limit')->defaultNull()->end()
144
                        ->arrayNode('allowed_paginate')
145
                            ->prototype('integer')->end()
146
                            ->defaultValue([10, 20, 30])
147
                        ->end()
148
                        ->integerNode('default_page_size')->defaultValue(10)->end()
149
                        ->booleanNode('sortable')->defaultFalse()->end()
150
                        ->variableNode('sorting')->defaultNull()->end()
151
                        ->booleanNode('filterable')->defaultFalse()->end()
152
                        ->variableNode('criteria')->defaultNull()->end()
153
                    ->end()
154
                ->end()
155
            ->end()
156
        ;
157
    }
158
159
    /**
160
     * @param ArrayNodeDefinition $node
161
     */
162
    private function addTranslationsSection(ArrayNodeDefinition $node)
163
    {
164
        $node
165
            ->children()
166
                ->arrayNode('translation')
167
                    ->canBeEnabled()
168
                    ->children()
169
                        ->scalarNode('default_locale')->cannotBeEmpty()->end()
170
                        ->scalarNode('locale_provider')->defaultValue('sylius.translation.locale_provider.request')->cannotBeEmpty()->end()
171
                        ->scalarNode('available_locales_provider')->defaultValue('sylius.translation.locales_provider.array')->cannotBeEmpty()->end()
172
                        ->arrayNode('available_locales') ->prototype('scalar')->end()
173
                    ->end()
174
                ->end()
175
            ->end()
176
        ;
177
    }
178
179
    private function addDriversSection(ArrayNodeDefinition $node)
180
    {
181
        // determine which drivers are distributed with this bundle
182
        $driverDir = __DIR__ . '/../Resources/config/driver';
183
        $iterator = new \RecursiveDirectoryIterator($driverDir);
184
        foreach (new \RecursiveIteratorIterator($iterator) as $file) {
185
            if ($file->getExtension() !== 'xml') {
186
                continue;
187
            }
188
189
            // we use the parent directory name in addition to the filename to
190
            // determine the name of the driver (e.g. doctrine/orm)
191
            $validDrivers[] = substr($file->getPathname(), 1 + strlen($driverDir), -4);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$validDrivers was never initialized. Although not strictly required by PHP, it is generally a good practice to add $validDrivers = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
192
        }
193
194
        $node
195
            ->children()
196
                ->arrayNode('drivers')
197
                    ->info('Enable drivers which are distributed with this bundle')
198
                    ->validate()
199
                    ->ifTrue(function ($value) use ($validDrivers) { 
0 ignored issues
show
Bug introduced by
The variable $validDrivers does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
200
                        return 0 !== count(array_diff($value, $validDrivers)); 
201
                    })
202
                        ->thenInvalid(sprintf('Invalid driver specified in %%s, valid drivers: ["%s"]', implode('", "', $validDrivers)))
203
                    ->end()
204
                    ->defaultValue(['doctrine/orm'])
205
                    ->prototype('scalar')->end()
206
                ->end()
207
            ->end();
208
    }
209
}
210