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

Completed
Pull Request — master (#264)
by Jérémiah
22:49
created

setExpressionLanguageDefaultParser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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