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 (#264)
by Jérémiah
16:33
created

OverblogGraphQLExtension::setErrorHandler()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 38
ccs 25
cts 25
cp 1
rs 8.8571
cc 3
eloc 24
nc 3
nop 2
crap 3
1
<?php
2
3
namespace Overblog\GraphQLBundle\DependencyInjection;
4
5
use GraphQL\Type\Schema;
6
use Overblog\GraphQLBundle\CacheWarmer\CompileCacheWarmer;
7
use Overblog\GraphQLBundle\Config\Processor\BuilderProcessor;
8
use Overblog\GraphQLBundle\Error\ErrorHandler;
9
use Overblog\GraphQLBundle\Event\Events;
10
use Overblog\GraphQLBundle\EventListener\ClassLoaderListener;
11
use Overblog\GraphQLBundle\EventListener\DebugListener;
12
use Overblog\GraphQLBundle\EventListener\ErrorHandlerListener;
13
use Overblog\GraphQLBundle\EventListener\ErrorLoggerListener;
14
use Symfony\Component\Cache\Adapter\ArrayAdapter;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Definition;
18
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
19
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
20
use Symfony\Component\DependencyInjection\Reference;
21
use Symfony\Component\ExpressionLanguage\ParserCache\ArrayParserCache;
22
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23
use Symfony\Component\HttpKernel\Kernel;
24
25
class OverblogGraphQLExtension extends Extension implements PrependExtensionInterface
26
{
27 27
    public function load(array $configs, ContainerBuilder $container)
28
    {
29 27
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
30 27
        $loader->load('services.yml');
31 27
        $loader->load('graphql_types.yml');
32
33 27
        $config = $this->treatConfigs($configs, $container);
34
35 27
        $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 27
        $this->setExpressionLanguageDefaultParser($container);
37 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $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 27
        $container->setParameter($this->getAlias().'.resources_dir', realpath(__DIR__.'/../Resources'));
49 27
    }
50
51 25
    public function prepend(ContainerBuilder $container)
52
    {
53 25
        $configs = $container->getExtensionConfig($this->getAlias());
54 25
        $configs = $container->getParameterBag()->resolveValue($configs);
55 25
        $config = $this->treatConfigs($configs, $container, true);
56
57
        /** @var OverblogGraphQLTypesExtension $typesExtension */
58 25
        $typesExtension = $container->getExtension($this->getAlias().'_types');
59 25
        $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 25
    }
61
62 27
    public function getAlias()
63
    {
64 27
        return Configuration::NAME;
65
    }
66
67 27
    public function getConfiguration(array $config, ContainerBuilder $container)
68
    {
69 27
        return new Configuration(
70 27
            $container->getParameter('kernel.debug'),
71 27
            $container->hasParameter('kernel.cache_dir') ? $container->getParameter('kernel.cache_dir') : null
72
        );
73
    }
74
75 27
    private function setCompilerCacheWarmer(array $config, ContainerBuilder $container)
76
    {
77 27
        if ($config['definitions']['auto_compile']) {
78 26
            $definition = $container->setDefinition(
79 26
                CompileCacheWarmer::class,
80 26
                new Definition(CompileCacheWarmer::class)
81
            );
82 26
            $definition->setArguments([new Reference($this->getAlias().'.cache_compiler')]);
83 26
            $definition->addTag('kernel.cache_warmer', ['priority' => 50]);
84
        }
85 27
    }
86
87 27
    private function setClassLoaderListener(array $config, ContainerBuilder $container)
88
    {
89 27
        $container->setParameter($this->getAlias().'.use_classloader_listener', $config['definitions']['use_classloader_listener']);
90 27
        if ($config['definitions']['use_classloader_listener']) {
91 26
            $definition = $container->setDefinition(
92 26
                $this->getAlias().'.event_listener.classloader_listener',
93 26
                new Definition(ClassLoaderListener::class)
94
            );
95 26
            $definition->setPublic(true);
96 26
            $definition->setArguments([new Reference($this->getAlias().'.cache_compiler')]);
97 26
            $definition->addTag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'load', 'priority' => 255]);
98 26
            $definition->addTag('kernel.event_listener', ['event' => 'console.command', 'method' => 'load', 'priority' => 255]);
99
        }
100 27
    }
101
102 27
    private function setDefinitionParameters(array $config, ContainerBuilder $container)
103
    {
104
        // auto mapping
105 27
        $container->setParameter($this->getAlias().'.auto_mapping.enabled', $config['definitions']['auto_mapping']['enabled']);
106 27
        $container->setParameter($this->getAlias().'.auto_mapping.directories', $config['definitions']['auto_mapping']['directories']);
107
        // generator and config
108 27
        $container->setParameter($this->getAlias().'.default_resolver', $config['definitions']['default_resolver']);
109 27
        $container->setParameter($this->getAlias().'.class_namespace', $config['definitions']['class_namespace']);
110 27
        $container->setParameter($this->getAlias().'.cache_dir', $config['definitions']['cache_dir']);
111 27
    }
112
113 27
    private function setBatchingMethod(array $config, ContainerBuilder $container)
114
    {
115 27
        $container->setParameter($this->getAlias().'.batching_method', $config['batching_method']);
116 27
    }
117
118 27
    private function setExpressionLanguageDefaultParser(ContainerBuilder $container)
119
    {
120 27
        $class = version_compare(Kernel::VERSION, '3.2.0', '>=') ? ArrayAdapter::class : ArrayParserCache::class;
121 27
        $definition = new Definition($class);
122 27
        $definition->setPublic(false);
123 27
        $container->setDefinition($this->getAlias().'.cache_expression_language_parser.default', $definition);
124 27
    }
125
126 27
    private function setDebugListener(array $config, ContainerBuilder $container)
127
    {
128 27
        if ($config['definitions']['show_debug_info']) {
129 1
            $definition = $container->setDefinition(
130 1
                DebugListener::class,
131 1
                new Definition(DebugListener::class)
132
            );
133 1
            $definition->addTag('kernel.event_listener', ['event' => Events::PRE_EXECUTOR, 'method' => 'onPreExecutor']);
134 1
            $definition->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
135
        }
136 27
    }
137
138 27
    private function setConfigBuilders(array $config, ContainerBuilder $container)
139
    {
140 27
        $useObjectToAddResource = method_exists($container, 'addObjectResource');
141 27
        $objectToAddResourceMethod = $useObjectToAddResource ? 'addObjectResource' : 'addClassResource';
142
143 27
        foreach (BuilderProcessor::BUILDER_TYPES as $type) {
144 27
            if (!empty($config['definitions']['builders'][$type])) {
145 1
                foreach ($config['definitions']['builders'][$type] as $params) {
146 1
                    $object = $useObjectToAddResource ? $params['class'] : new \ReflectionClass($params['class']);
147 1
                    $container->$objectToAddResourceMethod($object);
148 27
                    BuilderProcessor::addBuilderClass($params['alias'], $type, $params['class']);
149
                }
150
            }
151
        }
152 27
    }
153
154 27
    private function treatConfigs(array $configs, ContainerBuilder $container, $forceReload = false)
155
    {
156 27
        static $config = null;
157
158 27
        if ($forceReload || null === $config) {
159 27
            $configuration = $this->getConfiguration($configs, $container);
160 27
            $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
Bug introduced by
It seems like $configuration defined by $this->getConfiguration($configs, $container) on line 159 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...
161
        }
162
163 27
        return $config;
164
    }
165
166 27
    private function setSecurity(array $config, ContainerBuilder $container)
167
    {
168 27
        foreach ($config['security'] as $key => $value) {
169 27
            $container->setParameter(sprintf('%s.%s', $this->getAlias(), $key), $value);
170
        }
171 27
    }
172
173 27
    private function setErrorHandler(array $config, ContainerBuilder $container)
174
    {
175 27
        if ($config['errors_handler']['enabled']) {
176 27
            $id = $this->getAlias().'.error_handler';
177 27
            $errorHandlerDefinition = $container->setDefinition($id, new Definition(ErrorHandler::class));
178 27
            $errorHandlerDefinition->setPublic(false)
179 27
                ->setArguments(
180
                    [
181 27
                        new Reference('event_dispatcher'),
182 27
                        $config['errors_handler']['internal_error_message'],
183 27
                        $this->buildExceptionMap($config['errors_handler']['exceptions']),
184 27
                        $config['errors_handler']['map_exceptions_to_parent'],
185
                    ]
186
                )
187 27
                ->addMethodCall('setUserWarningClass', [$config['errors_handler']['exceptions']['types']['warnings']])
188 27
                ->addMethodCall('setUserErrorClass', [$config['errors_handler']['exceptions']['types']['errors']])
189
            ;
190
191 27
            $errorHandlerListenerDefinition = $container->setDefinition(ErrorHandlerListener::class, new Definition(ErrorHandlerListener::class));
192 27
            $errorHandlerListenerDefinition->setPublic(true)
193 27
                ->setArguments([new Reference($id), $config['errors_handler']['rethrow_internal_exceptions'], $config['errors_handler']['debug']])
194 27
                ->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor'])
195
            ;
196
197 27
            if ($config['errors_handler']['log']) {
198 27
                $errorHandlerListenerDefinition = $container->setDefinition(ErrorLoggerListener::class, new Definition(ErrorLoggerListener::class));
199 27
                $errorHandlerListenerDefinition->setPublic(true)
200 27
                    ->setArguments([
201 27
                            new Reference($config['errors_handler']['logger_service']),
202 27
                            $config['errors_handler']['exceptions']['types']['errors'],
203 27
                            $config['errors_handler']['exceptions']['types']['warnings'],
204
                        ]
205
                    )
206 27
                    ->addTag('kernel.event_listener', ['event' => Events::ERROR_FORMATTING, 'method' => 'onErrorFormatting'])
207
                ;
208
            }
209
        }
210 27
    }
211
212 27
    private function setSchemaBuilderArguments(array $config, ContainerBuilder $container)
213
    {
214 27
        $container->getDefinition($this->getAlias().'.schema_builder')
215 27
            ->replaceArgument(1, $config['definitions']['config_validation']);
216 27
    }
217
218 27
    private function setSchemaArguments(array $config, ContainerBuilder $container)
219
    {
220 27
        if (isset($config['definitions']['schema'])) {
221 27
            $executorDefinition = $container->getDefinition($this->getAlias().'.request_executor');
222
223 27
            foreach ($config['definitions']['schema'] as $schemaName => $schemaConfig) {
224 23
                $schemaID = sprintf('%s.schema_%s', $this->getAlias(), $schemaName);
225 23
                $definition = new Definition(Schema::class);
226 23
                $definition->setFactory([new Reference('overblog_graphql.schema_builder'), 'create']);
227 23
                $definition->setArguments([$schemaConfig['query'], $schemaConfig['mutation'], $schemaConfig['subscription']]);
228 23
                $definition->setPublic(false);
229 23
                $container->setDefinition($schemaID, $definition);
230
231 23
                $executorDefinition->addMethodCall('addSchema', [$schemaName, new Reference($schemaID)]);
232
            }
233
        }
234 27
    }
235
236 27
    private function setServicesAliases(array $config, ContainerBuilder $container)
237
    {
238 27
        if (isset($config['services'])) {
239 27
            foreach ($config['services'] as $name => $id) {
240 27
                $alias = sprintf('%s.%s', $this->getAlias(), $name);
241 27
                $container->setAlias($alias, $id);
242
            }
243
        }
244 27
    }
245
246
    /**
247
     * Returns a list of custom exceptions mapped to error/warning classes.
248
     *
249
     * @param array $exceptionConfig
250
     *
251
     * @return array Custom exception map, [exception => UserError/UserWarning]
252
     */
253 27
    private function buildExceptionMap(array $exceptionConfig)
254
    {
255 27
        $exceptionMap = [];
256 27
        $typeMap = $exceptionConfig['types'];
257
258 27
        foreach ($exceptionConfig as $type => $exceptionList) {
259 27
            if ('types' === $type) {
260 27
                continue;
261
            }
262
263 27
            foreach ($exceptionList as $exception) {
264 27
                $exceptionMap[$exception] = $typeMap[$type];
265
            }
266
        }
267
268 27
        return $exceptionMap;
269
    }
270
}
271