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 (#277)
by Jérémiah
22:38 queued 19:05
created

OverblogGraphQLExtension::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 17
cts 17
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 16
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Overblog\GraphQLBundle\DependencyInjection;
4
5
use GraphQL\Error\UserError;
6
use GraphQL\Type\Schema;
7
use Overblog\GraphQLBundle\CacheWarmer\CompileCacheWarmer;
8
use Overblog\GraphQLBundle\Config\Processor\BuilderProcessor;
9
use Overblog\GraphQLBundle\Error\ErrorHandler;
10
use Overblog\GraphQLBundle\Error\UserWarning;
11
use Overblog\GraphQLBundle\Event\Events;
12
use Overblog\GraphQLBundle\EventListener\ClassLoaderListener;
13
use Overblog\GraphQLBundle\EventListener\DebugListener;
14
use Overblog\GraphQLBundle\EventListener\ErrorHandlerListener;
15
use Overblog\GraphQLBundle\EventListener\ErrorLoggerListener;
16
use Symfony\Component\Cache\Adapter\ArrayAdapter;
17
use Symfony\Component\Config\FileLocator;
18
use Symfony\Component\DependencyInjection\ContainerBuilder;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Symfony\Component\DependencyInjection\Definition;
21
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
22
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
23
use Symfony\Component\DependencyInjection\Reference;
24
use Symfony\Component\ExpressionLanguage\ParserCache\ArrayParserCache;
25
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
26
use Symfony\Component\HttpKernel\Kernel;
27
28
class OverblogGraphQLExtension extends Extension implements PrependExtensionInterface
29
{
30 28
    public function load(array $configs, ContainerBuilder $container)
31
    {
32 28
        $this->loadConfigFiles($container);
33 28
        $config = $this->treatConfigs($configs, $container);
34
35 28
        $this->setBatchingMethod($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...on::setBatchingMethod() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
36 28
        $this->setExpressionLanguageDefaultParser($container);
37 28
        $this->setServicesAliases($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...n::setServicesAliases() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
38 28
        $this->setSchemaBuilderArguments($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...chemaBuilderArguments() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
39 28
        $this->setSchemaArguments($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...n::setSchemaArguments() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
40 28
        $this->setErrorHandler($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...sion::setErrorHandler() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
41 28
        $this->setSecurity($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...xtension::setSecurity() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
42 28
        $this->setConfigBuilders($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...on::setConfigBuilders() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
43 28
        $this->setDebugListener($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...ion::setDebugListener() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
44 28
        $this->setDefinitionParameters($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...tDefinitionParameters() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
45 28
        $this->setClassLoaderListener($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...etClassLoaderListener() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
46 28
        $this->setCompilerCacheWarmer($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container) on line 33 can also be of type null; however, Overblog\GraphQLBundle\D...etCompilerCacheWarmer() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
47
48 28
        $container->setParameter($this->getAlias().'.resources_dir', realpath(__DIR__.'/../Resources'));
49 28
    }
50
51 26
    public function prepend(ContainerBuilder $container)
52
    {
53 26
        $configs = $container->getExtensionConfig($this->getAlias());
54 26
        $configs = $container->getParameterBag()->resolveValue($configs);
55 26
        $config = $this->treatConfigs($configs, $container, true);
56
57
        /** @var OverblogGraphQLTypesExtension $typesExtension */
58 26
        $typesExtension = $container->getExtension($this->getAlias().'_types');
59 26
        $typesExtension->containerPrependExtensionConfig($config, $container);
0 ignored issues
show
Bug introduced by
It seems like $config defined by $this->treatConfigs($configs, $container, true) on line 55 can also be of type null; however, Overblog\GraphQLBundle\D...rependExtensionConfig() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
60 26
    }
61
62 28
    public function getAlias()
63
    {
64 28
        return Configuration::NAME;
65
    }
66
67 28
    public function getConfiguration(array $config, ContainerBuilder $container)
68
    {
69 28
        return new Configuration(
70 28
            $container->getParameter('kernel.debug'),
71 28
            $container->hasParameter('kernel.cache_dir') ? $container->getParameter('kernel.cache_dir') : null
72
        );
73
    }
74
75 28
    private function loadConfigFiles(ContainerBuilder $container)
76
    {
77 28
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
78 28
        $loader->load('services.yml');
79 28
        $loader->load('graphql_types.yml');
80 28
        $loader->load('expression_language_functions.yml');
81 28
        $loader->load('definition_config_processors.yml');
82 28
    }
83
84 28
    private function setCompilerCacheWarmer(array $config, ContainerBuilder $container)
85
    {
86 28
        if ($config['definitions']['auto_compile']) {
87 27
            $definition = $container->setDefinition(
88 27
                CompileCacheWarmer::class,
89 27
                new Definition(CompileCacheWarmer::class)
90
            );
91 27
            $definition->setArguments([new Reference($this->getAlias().'.cache_compiler')]);
92 27
            $definition->addTag('kernel.cache_warmer', ['priority' => 50]);
93
        }
94 28
    }
95
96 28
    private function setClassLoaderListener(array $config, ContainerBuilder $container)
97
    {
98 28
        $container->setParameter($this->getAlias().'.use_classloader_listener', $config['definitions']['use_classloader_listener']);
99 28
        if ($config['definitions']['use_classloader_listener']) {
100 27
            $definition = $container->setDefinition(
101 27
                $this->getAlias().'.event_listener.classloader_listener',
102 27
                new Definition(ClassLoaderListener::class)
103
            );
104 27
            $definition->setPublic(true);
105 27
            $definition->setArguments([new Reference($this->getAlias().'.cache_compiler')]);
106 27
            $definition->addTag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'load', 'priority' => 255]);
107 27
            $definition->addTag('kernel.event_listener', ['event' => 'console.command', 'method' => 'load', 'priority' => 255]);
108
        }
109 28
    }
110
111 28
    private function setDefinitionParameters(array $config, ContainerBuilder $container)
112
    {
113
        // auto mapping
114 28
        $container->setParameter($this->getAlias().'.auto_mapping.enabled', $config['definitions']['auto_mapping']['enabled']);
115 28
        $container->setParameter($this->getAlias().'.auto_mapping.directories', $config['definitions']['auto_mapping']['directories']);
116
        // generator and config
117 28
        $container->setParameter($this->getAlias().'.default_resolver', $config['definitions']['default_resolver']);
118 28
        $container->setParameter($this->getAlias().'.class_namespace', $config['definitions']['class_namespace']);
119 28
        $container->setParameter($this->getAlias().'.cache_dir', $config['definitions']['cache_dir']);
120 28
    }
121
122 28
    private function setBatchingMethod(array $config, ContainerBuilder $container)
123
    {
124 28
        $container->setParameter($this->getAlias().'.batching_method', $config['batching_method']);
125 28
    }
126
127 28
    private function setExpressionLanguageDefaultParser(ContainerBuilder $container)
128
    {
129 28
        $class = version_compare(Kernel::VERSION, '3.2.0', '>=') ? ArrayAdapter::class : ArrayParserCache::class;
130 28
        $definition = new Definition($class);
131 28
        $definition->setPublic(false);
132 28
        $container->setDefinition($this->getAlias().'.cache_expression_language_parser.default', $definition);
133 28
    }
134
135 28
    private function setDebugListener(array $config, ContainerBuilder $container)
136
    {
137 28
        if ($config['definitions']['show_debug_info']) {
138 1
            $definition = $container->setDefinition(
139 1
                DebugListener::class,
140 1
                new Definition(DebugListener::class)
141
            );
142 1
            $definition->addTag('kernel.event_listener', ['event' => Events::PRE_EXECUTOR, 'method' => 'onPreExecutor']);
143 1
            $definition->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
144
        }
145 28
    }
146
147 28
    private function setConfigBuilders(array $config, ContainerBuilder $container)
148
    {
149 28
        $useObjectToAddResource = method_exists($container, 'addObjectResource');
150 28
        $objectToAddResourceMethod = $useObjectToAddResource ? 'addObjectResource' : 'addClassResource';
151
152 28
        foreach (BuilderProcessor::BUILDER_TYPES as $type) {
153 28
            if (!empty($config['definitions']['builders'][$type])) {
154 1
                foreach ($config['definitions']['builders'][$type] as $params) {
155 1
                    $object = $useObjectToAddResource ? $params['class'] : new \ReflectionClass($params['class']);
156 1
                    $container->$objectToAddResourceMethod($object);
157 28
                    BuilderProcessor::addBuilderClass($params['alias'], $type, $params['class']);
158
                }
159
            }
160
        }
161 28
    }
162
163 28
    private function treatConfigs(array $configs, ContainerBuilder $container, $forceReload = false)
164
    {
165 28
        static $config = null;
166
167 28
        if ($forceReload || null === $config) {
168 28
            $configuration = $this->getConfiguration($configs, $container);
169 28
            $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
Bug introduced by
It seems like $configuration defined by $this->getConfiguration($configs, $container) on line 168 can be null; however, Symfony\Component\Depend...:processConfiguration() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
170
        }
171
172 28
        return $config;
173
    }
174
175 28
    private function setSecurity(array $config, ContainerBuilder $container)
176
    {
177 28
        foreach ($config['security'] as $key => $value) {
178 28
            $container->setParameter(sprintf('%s.%s', $this->getAlias(), $key), $value);
179
        }
180 28
    }
181
182 28
    private function setErrorHandler(array $config, ContainerBuilder $container)
183
    {
184 28
        if ($config['errors_handler']['enabled']) {
185 28
            $id = $this->getAlias().'.error_handler';
186 28
            $errorHandlerDefinition = $container->setDefinition($id, new Definition(ErrorHandler::class));
187 28
            $errorHandlerDefinition->setPublic(false)
188 28
                ->setArguments(
189
                    [
190 28
                        new Reference('event_dispatcher'),
191 28
                        $config['errors_handler']['internal_error_message'],
192 28
                        $this->buildExceptionMap($config['errors_handler']['exceptions']),
193 28
                        $config['errors_handler']['map_exceptions_to_parent'],
194
                    ]
195
                )
196
            ;
197
198 28
            $errorHandlerListenerDefinition = $container->setDefinition(ErrorHandlerListener::class, new Definition(ErrorHandlerListener::class));
199 28
            $errorHandlerListenerDefinition->setPublic(true)
200 28
                ->setArguments([new Reference($id), $config['errors_handler']['rethrow_internal_exceptions'], $config['errors_handler']['debug']])
201 28
                ->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor'])
202
            ;
203
204 28
            if ($config['errors_handler']['log']) {
205 28
                $loggerServiceId = $config['errors_handler']['logger_service'];
206 28
                $invalidBehavior = ErrorLoggerListener::DEFAULT_LOGGER_SERVICE === $loggerServiceId ? ContainerInterface::NULL_ON_INVALID_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
207 28
                $errorHandlerListenerDefinition = $container->setDefinition(ErrorLoggerListener::class, new Definition(ErrorLoggerListener::class));
208 28
                $errorHandlerListenerDefinition->setPublic(true)
209 28
                    ->setArguments([new Reference($loggerServiceId, $invalidBehavior)])
210 28
                    ->addTag('kernel.event_listener', ['event' => Events::ERROR_FORMATTING, 'method' => 'onErrorFormatting'])
211
                ;
212
            }
213
        }
214 28
    }
215
216 28
    private function setSchemaBuilderArguments(array $config, ContainerBuilder $container)
217
    {
218 28
        $container->getDefinition($this->getAlias().'.schema_builder')
219 28
            ->replaceArgument(2, $config['definitions']['config_validation']);
220 28
    }
221
222 28
    private function setSchemaArguments(array $config, ContainerBuilder $container)
223
    {
224 28
        if (isset($config['definitions']['schema'])) {
225 28
            $executorDefinition = $container->getDefinition($this->getAlias().'.request_executor');
226
227 28
            foreach ($config['definitions']['schema'] as $schemaName => $schemaConfig) {
228 24
                $schemaID = sprintf('%s.schema_%s', $this->getAlias(), $schemaName);
229 24
                $definition = new Definition(Schema::class);
230 24
                $definition->setFactory([new Reference('overblog_graphql.schema_builder'), 'create']);
231 24
                $definition->setArguments([
232 24
                    $schemaConfig['query'],
233 24
                    $schemaConfig['mutation'],
234 24
                    $schemaConfig['subscription'],
235 24
                    array_map(function ($id) {
236 1
                        return new Reference($id);
237 24
                    }, $schemaConfig['resolver_maps']),
238
                ]);
239 24
                $definition->setPublic(false);
240 24
                $container->setDefinition($schemaID, $definition);
241
242 24
                $executorDefinition->addMethodCall('addSchema', [$schemaName, new Reference($schemaID)]);
243
            }
244
        }
245 28
    }
246
247 28
    private function setServicesAliases(array $config, ContainerBuilder $container)
248
    {
249 28
        if (isset($config['services'])) {
250 28
            foreach ($config['services'] as $name => $id) {
251 28
                $alias = sprintf('%s.%s', $this->getAlias(), $name);
252 28
                $container->setAlias($alias, $id);
253
            }
254
        }
255 28
    }
256
257
    /**
258
     * Returns a list of custom exceptions mapped to error/warning classes.
259
     *
260
     * @param array $exceptionConfig
261
     *
262
     * @return array Custom exception map, [exception => UserError/UserWarning]
263
     */
264 28
    private function buildExceptionMap(array $exceptionConfig)
265
    {
266 28
        $exceptionMap = [];
267
        $errorsMapping = [
268 28
            'errors' => UserError::class,
269
            'warnings' => UserWarning::class,
270
        ];
271
272 28
        foreach ($exceptionConfig as $type => $exceptionList) {
273 28
            foreach ($exceptionList as $exception) {
274 28
                $exceptionMap[$exception] = $errorsMapping[$type];
275
            }
276
        }
277
278 28
        return $exceptionMap;
279
    }
280
}
281