Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Pull Request — master (#208)
by Renato
07:25
created

Configuration::getConfigTreeBuilder()   C

Complexity

Conditions 7
Paths 1

Size

Total Lines 171
Code Lines 159

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 161
CRAP Score 7

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 171
ccs 161
cts 162
cp 0.9938
rs 6.4589
c 2
b 0
f 0
cc 7
eloc 159
nc 1
nop 0
crap 7

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 OverblogGraphQLBundle package.
5
 *
6
 * (c) Overblog <http://github.com/overblog/>
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 Overblog\GraphQLBundle\DependencyInjection;
13
14
use GraphQL\Validator\Rules\QueryComplexity;
15
use GraphQL\Validator\Rules\QueryDepth;
16
use Overblog\GraphQLBundle\Error\ErrorHandler;
17
use Overblog\GraphQLBundle\Resolver\Resolver;
18
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
19
use Symfony\Component\Config\Definition\ConfigurationInterface;
20
21
class Configuration implements ConfigurationInterface
22
{
23
    /** bool */
24
    private $debug;
25
26
    /** null|string */
27
    private $cacheDir;
28
29
    /**
30
     * Constructor.
31
     *
32
     * @param bool        $debug    Whether to use the debug mode
33
     * @param null|string $cacheDir
34
     */
35 13
    public function __construct($debug, $cacheDir = null)
36
    {
37 13
        $this->debug = (bool) $debug;
38 13
        $this->cacheDir = $cacheDir;
39 13
    }
40
41 13
    public function getConfigTreeBuilder()
42
    {
43 13
        $treeBuilder = new TreeBuilder();
44 13
        $rootNode = $treeBuilder->root('overblog_graphql');
45
46
        $rootNode
47 13
            ->children()
48 13
                ->enumNode('batching_method')
49 13
                    ->values(['relay', 'apollo'])
50 13
                    ->defaultValue('relay')
51 13
                ->end()
52 13
                ->arrayNode('definitions')
53 13
                    ->addDefaultsIfNotSet()
54 13
                    ->children()
55 13
                        ->scalarNode('internal_error_message')->defaultNull()->end()
56 13
                        ->variableNode('default_resolver')->defaultValue([Resolver::class, 'defaultResolveFn'])->end()
57 13
                        ->scalarNode('class_namespace')->defaultValue('Overblog\\GraphQLBundle\\__DEFINITIONS__')->end()
58 13
                        ->scalarNode('cache_dir')->defaultValue($this->cacheDir.'/overblog/graphql-bundle/__definitions__')->end()
59 13
                        ->booleanNode('use_classloader_listener')->defaultTrue()->end()
60 13
                        ->booleanNode('show_debug_info')->defaultFalse()->end()
61 13
                        ->booleanNode('config_validation')->defaultValue($this->debug)->end()
62 13
                        ->arrayNode('schema')
63 13
                            ->beforeNormalization()
64 13
                                ->ifTrue(function ($v) {
65 10
                                    $needNormalization = isset($v['query']) && is_string($v['query']) ||
66
                                        isset($v['mutation']) && is_string($v['mutation']) ||
67 10
                                        isset($v['subscription']) && is_string($v['subscription']);
68
69 10
                                    return $needNormalization;
70 13
                                })
71 13
                                ->then(function ($v) {
72 10
                                    return ['default' => $v];
73 13
                                })
74 13
                            ->end()
75 13
                            ->useAttributeAsKey('name')
76 13
                            ->prototype('array')
77 13
                                ->addDefaultsIfNotSet()
78 13
                                ->children()
79 13
                                    ->scalarNode('query')->defaultNull()->end()
80 13
                                    ->scalarNode('mutation')->defaultNull()->end()
81 13
                                    ->scalarNode('subscription')->defaultNull()->end()
82 13
                                ->end()
83 13
                            ->end()
84 13
                        ->end()
85 13
                        ->arrayNode('auto_mapping')
86 13
                            ->treatFalseLike(['enabled' => false])
87 13
                            ->treatTrueLike(['enabled' => true])
88 13
                            ->treatNullLike(['enabled' => true])
89 13
                            ->addDefaultsIfNotSet()
90 13
                            ->children()
91 13
                                ->booleanNode('enabled')->defaultTrue()->end()
92 13
                                ->arrayNode('directories')
93 13
                                    ->info('List of directories containing GraphQL classes.')
94 13
                                    ->prototype('scalar')->end()
95 13
                                ->end()
96 13
                            ->end()
97 13
                        ->end()
98 13
                        ->arrayNode('mappings')
99 13
                            ->children()
100 13
                                ->arrayNode('auto_discover')
101 13
                                    ->treatFalseLike(['bundles' => false, 'root_dir' => false])
102 13
                                    ->treatTrueLike(['bundles' => true, 'root_dir' => true])
103 13
                                    ->treatNullLike(['bundles' => true, 'root_dir' => true])
104 13
                                    ->addDefaultsIfNotSet()
105 13
                                    ->children()
106 13
                                        ->booleanNode('bundles')->defaultTrue()->end()
107 13
                                        ->booleanNode('root_dir')->defaultTrue()->end()
108 13
                                    ->end()
109 13
                                ->end()
110 13
                                ->arrayNode('types')
111 13
                                    ->prototype('array')
112 13
                                        ->addDefaultsIfNotSet()
113 13
                                        ->beforeNormalization()
114 13
                                            ->ifTrue(function ($v) {
115 9
                                                return isset($v['type']) && $v['type'] === 'yml';
116 13
                                            })
117 13
                                            ->then(function ($v) {
118 1
                                                $v['type'] = 'yaml';
119
120 1
                                                return $v;
121 13
                                            })
122 13
                                        ->end()
123 13
                                        ->children()
124 13
                                            ->enumNode('type')->values(['yaml', 'xml'])->defaultNull()->end()
125 13
                                            ->scalarNode('dir')->defaultNull()->end()
126 13
                                            ->scalarNode('suffix')->defaultValue(OverblogGraphQLTypesExtension::DEFAULT_TYPES_SUFFIX)->end()
127 13
                                        ->end()
128 13
                                    ->end()
129 13
                                ->end()
130 13
                            ->end()
131 13
                        ->end()
132 13
                        ->arrayNode('exceptions')
133 13
                            ->addDefaultsIfNotSet()
134 13
                            ->children()
135 13
                                ->arrayNode('warnings')
136 13
                                    ->treatNullLike([])
137 13
                                    ->prototype('scalar')->end()
138 13
                                ->end()
139 13
                                ->arrayNode('errors')
140 13
                                    ->treatNullLike([])
141 13
                                    ->prototype('scalar')->end()
142 13
                                ->end()
143 13
                                ->arrayNode('types')
144 13
                                    ->addDefaultsIfNotSet()
145 13
                                    ->children()
146 13
                                        ->scalarNode('warnings')
147 13
                                            ->defaultValue(ErrorHandler::DEFAULT_USER_WARNING_CLASS)
148 13
                                        ->end()
149 13
                                        ->scalarNode('errors')
150 13
                                            ->defaultValue(ErrorHandler::DEFAULT_USER_ERROR_CLASS)
151 13
                                        ->end()
152 13
                                    ->end()
153 13
                                ->end()
154 13
                            ->end()
155 13
                        ->end()
156
157 13
                        ->arrayNode('builders')
158 13
                            ->children()
159 13
                                ->append($this->addBuilderSection('field'))
160 13
                                ->append($this->addBuilderSection('args'))
161 13
                            ->end()
162 13
                        ->end()
163
164 13
                    ->end()
165 13
                ->end()
166 13
                ->arrayNode('templates')
167 13
                    ->addDefaultsIfNotSet()
168 13
                    ->children()
169 13
                        ->scalarNode('graphiql')
170 13
                            ->defaultValue('@OverblogGraphQL/GraphiQL/index.html.twig')
171 13
                        ->end()
172 13
                    ->end()
173 13
                ->end()
174 13
                ->arrayNode('services')
175 13
                    ->addDefaultsIfNotSet()
176 13
                    ->children()
177 13
                        ->scalarNode('executor')
178 13
                            ->defaultValue('overblog_graphql.executor.default')
179 13
                        ->end()
180 13
                        ->scalarNode('promise_adapter')
181 13
                            ->defaultValue('overblog_graphql.promise_adapter.default')
182 13
                        ->end()
183 13
                        ->scalarNode('expression_language')
184 13
                            ->defaultValue('overblog_graphql.expression_language.default')
185 13
                        ->end()
186 13
                        ->scalarNode('cache_expression_language_parser')
187 13
                            ->defaultValue('overblog_graphql.cache_expression_language_parser.default')
188 13
                        ->end()
189 13
                    ->end()
190 13
                ->end()
191 13
                ->arrayNode('security')
192 13
                    ->addDefaultsIfNotSet()
193 13
                    ->children()
194 13
                        ->append($this->addSecurityQuerySection('query_max_depth', QueryDepth::DISABLED))
195 13
                        ->append($this->addSecurityQuerySection('query_max_complexity', QueryComplexity::DISABLED))
196 13
                        ->booleanNode('handle_cors')->defaultFalse()->end()
197 13
                    ->end()
198 13
                ->end()
199 13
                ->arrayNode('versions')
200 13
                    ->addDefaultsIfNotSet()
201 13
                    ->children()
202 13
                        ->scalarNode('graphiql')->defaultValue('0.11')->end()
203 13
                        ->scalarNode('react')->defaultValue('15.6')->end()
204 13
                        ->scalarNode('fetch')->defaultValue('2.0')->end()
205 13
                        ->enumNode('relay')->values(['modern', 'classic'])->defaultValue('classic')->end()
206 13
                    ->end()
207 13
                ->end()
208 13
            ->end();
209
210 13
        return $treeBuilder;
211
    }
212
213 13
    private function addBuilderSection($name)
214
    {
215 13
        $builder = new TreeBuilder();
216 13
        $node = $builder->root($name);
217 13
        $node->beforeNormalization()
218 13
            ->ifTrue(function ($v) {
219 1
                return is_array($v) && !empty($v);
220 13
            })
221 13
            ->then(function ($v) {
222 1
                foreach ($v as $key => &$config) {
223 1
                    if (is_string($config)) {
224
                        $config = [
225 1
                            'alias' => $key,
226 1
                            'class' => $config,
227
                        ];
228
                    }
229
                }
230
231 1
                return $v;
232 13
            })
233 13
        ->end();
234
235 13
        $node->prototype('array')
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Config...\Builder\NodeDefinition as the method children() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
236 13
            ->children()
237 13
                ->scalarNode('alias')->isRequired()->end()
238 13
                ->scalarNode('class')->isRequired()->end()
239 13
            ->end()
240 13
        ->end()
241
        ;
242
243 13
        return $node;
244
    }
245
246 13
    private function addSecurityQuerySection($name, $disabledValue)
247
    {
248 13
        $builder = new TreeBuilder();
249 13
        $node = $builder->root($name, 'scalar');
250 13
        $node->beforeNormalization()
251 13
                ->ifTrue(function ($v) {
252
                    return is_string($v) && is_numeric($v);
253 13
                })
254 13
                ->then(function ($v) {
255
                    return (int) $v;
256 13
                })
257 13
            ->end();
258
259
        $node
260 13
            ->info('Disabled if equal to false.')
261 13
            ->beforeNormalization()
262 13
                ->ifTrue(function ($v) {
263
                    return false === $v;
264 13
                })
265 13
                ->then(function () use ($disabledValue) {
266
                    return $disabledValue;
267 13
                })
268 13
            ->end()
269 13
            ->defaultFalse()
270 13
            ->validate()
271 13
                ->ifTrue(function ($v) {
272
                    return is_int($v) && $v < 0;
273 13
                })
274
                ->thenInvalid('"overblog_graphql.security.'.$name.'" must be greater or equal to 0.')
275
            ->end()
276
        ;
277
278
        return $node;
279
    }
280
}
281