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 (#494)
by Jérémiah
18:56
created

setDefinitionParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Overblog\GraphQLBundle\DependencyInjection;
6
7
use GraphQL\Error\UserError;
8
use GraphQL\Type\Schema;
9
use Overblog\GraphQLBundle\CacheWarmer\CompileCacheWarmer;
10
use Overblog\GraphQLBundle\Config\Processor\BuilderProcessor;
11
use Overblog\GraphQLBundle\Error\ErrorHandler;
12
use Overblog\GraphQLBundle\Error\UserWarning;
13
use Overblog\GraphQLBundle\Event\Events;
14
use Overblog\GraphQLBundle\EventListener\ClassLoaderListener;
15
use Overblog\GraphQLBundle\EventListener\DebugListener;
16
use Overblog\GraphQLBundle\EventListener\ErrorHandlerListener;
17
use Overblog\GraphQLBundle\EventListener\ErrorLoggerListener;
18
use Overblog\GraphQLBundle\EventListener\TypeDecoratorListener;
19
use Symfony\Component\Config\FileLocator;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\ContainerInterface;
22
use Symfony\Component\DependencyInjection\Definition;
23
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
24
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
25
use Symfony\Component\DependencyInjection\Reference;
26
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
27
28
class OverblogGraphQLExtension extends Extension implements PrependExtensionInterface
29
{
30 28
    public function load(array $configs, ContainerBuilder $container): void
31
    {
32 28
        $this->loadConfigFiles($container);
33 28
        $config = $this->treatConfigs($configs, $container);
34
35 28
        $this->setBatchingMethod($config, $container);
36 28
        $this->setServicesAliases($config, $container);
37 28
        $this->setSchemaBuilderArguments($config, $container);
38 28
        $this->setSchemaArguments($config, $container);
39 28
        $this->setErrorHandler($config, $container);
40 28
        $this->setSecurity($config, $container);
41 28
        $this->setConfigBuilders($config, $container);
42 28
        $this->setDebugListener($config, $container);
43 28
        $this->setDefinitionParameters($config, $container);
44 28
        $this->setClassLoaderListener($config, $container);
45 28
        $this->setCompilerCacheWarmer($config, $container);
46
47 28
        $container->setParameter($this->getAlias().'.resources_dir', \realpath(__DIR__.'/../Resources'));
48 28
    }
49
50 22
    public function prepend(ContainerBuilder $container): void
51
    {
52 22
        $configs = $container->getExtensionConfig($this->getAlias());
53 22
        $configs = $container->getParameterBag()->resolveValue($configs);
54 22
        $config = $this->treatConfigs($configs, $container, true);
55
56
        /** @var OverblogGraphQLTypesExtension $typesExtension */
57 22
        $typesExtension = $container->getExtension($this->getAlias().'_types');
58 22
        $typesExtension->containerPrependExtensionConfig($config, $container);
59 22
    }
60
61 28
    public function getAlias()
62
    {
63 28
        return Configuration::NAME;
64
    }
65
66 28
    public function getConfiguration(array $config, ContainerBuilder $container)
67
    {
68 28
        return new Configuration(
69 28
            $container->getParameter('kernel.debug'),
70 28
            $container->hasParameter('kernel.cache_dir') ? $container->getParameter('kernel.cache_dir') : null
71
        );
72
    }
73
74 28
    private function loadConfigFiles(ContainerBuilder $container): void
75
    {
76 28
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
77 28
        $loader->load('services.yml');
78 28
        $loader->load('graphql_types.yml');
79 28
        $loader->load('graphql_resolvers.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): void
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): void
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): void
112
    {
113
        // generator and config
114 28
        $container->setParameter($this->getAlias().'.default_resolver', $config['definitions']['default_resolver']);
115 28
        $container->setParameter($this->getAlias().'.class_namespace', $config['definitions']['class_namespace']);
116 28
        $container->setParameter($this->getAlias().'.cache_dir', $config['definitions']['cache_dir']);
117 28
        $container->setParameter($this->getAlias().'.cache_dir_permissions', $config['definitions']['cache_dir_permissions']);
118 28
        $container->setParameter($this->getAlias().'.argument_class', $config['definitions']['argument_class']);
119 28
    }
120
121 28
    private function setBatchingMethod(array $config, ContainerBuilder $container): void
122
    {
123 28
        $container->setParameter($this->getAlias().'.batching_method', $config['batching_method']);
124 28
    }
125
126 28
    private function setDebugListener(array $config, ContainerBuilder $container): void
127
    {
128 28
        if ($config['definitions']['show_debug_info']) {
129
            $definition = $container->setDefinition(
130
                DebugListener::class,
131
                new Definition(DebugListener::class)
132
            );
133
            $definition->addTag('kernel.event_listener', ['event' => Events::PRE_EXECUTOR, 'method' => 'onPreExecutor']);
134
            $definition->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
135
        }
136 28
    }
137
138 28
    private function setConfigBuilders(array $config, ContainerBuilder $container): void
139
    {
140 28
        foreach (BuilderProcessor::BUILDER_TYPES as $type) {
141 28
            if (!empty($config['definitions']['builders'][$type])) {
142 5
                foreach ($config['definitions']['builders'][$type] as $params) {
143 5
                    $container->addObjectResource($params['class']);
144 5
                    BuilderProcessor::addBuilderClass($params['alias'], $type, $params['class']);
145
                }
146
            }
147
        }
148 28
    }
149
150 28
    private function treatConfigs(array $configs, ContainerBuilder $container, $forceReload = false)
151
    {
152 28
        static $config = null;
153
154 28
        if ($forceReload || null === $config) {
155 28
            $configuration = $this->getConfiguration($configs, $container);
156 28
            $config = $this->processConfiguration($configuration, $configs);
157
        }
158
159 28
        return $config;
160
    }
161
162 28
    private function setSecurity(array $config, ContainerBuilder $container): void
163
    {
164 28
        $executorDefinition = $container->getDefinition($this->getAlias().'.request_executor');
165 28
        if ($config['security']['enable_introspection']) {
166 28
            $executorDefinition->addMethodCall('enableIntrospectionQuery');
167
        } else {
168
            $executorDefinition->addMethodCall('disableIntrospectionQuery');
169
        }
170
171 28
        foreach ($config['security'] as $key => $value) {
172 28
            $container->setParameter(\sprintf('%s.%s', $this->getAlias(), $key), $value);
173
        }
174 28
    }
175
176 28
    private function setErrorHandler(array $config, ContainerBuilder $container): void
177
    {
178 28
        if ($config['errors_handler']['enabled']) {
179 28
            $id = $this->getAlias().'.error_handler';
180 28
            $errorHandlerDefinition = $container->setDefinition($id, new Definition(ErrorHandler::class));
181 28
            $errorHandlerDefinition->setPublic(false)
182 28
                ->setArguments(
183
                    [
184 28
                        new Reference('event_dispatcher'),
185 28
                        $config['errors_handler']['internal_error_message'],
186 28
                        $this->buildExceptionMap($config['errors_handler']['exceptions']),
187 28
                        $config['errors_handler']['map_exceptions_to_parent'],
188
                    ]
189
                );
190
191 28
            $errorHandlerListenerDefinition = $container->setDefinition(ErrorHandlerListener::class, new Definition(ErrorHandlerListener::class));
192 28
            $errorHandlerListenerDefinition->setPublic(true)
193 28
                ->setArguments([new Reference($id), $config['errors_handler']['rethrow_internal_exceptions'], $config['errors_handler']['debug']])
194 28
                ->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
195
196 28
            if ($config['errors_handler']['log']) {
197 28
                $loggerServiceId = $config['errors_handler']['logger_service'];
198 28
                $invalidBehavior = ErrorLoggerListener::DEFAULT_LOGGER_SERVICE === $loggerServiceId ? ContainerInterface::NULL_ON_INVALID_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
199 28
                $errorHandlerListenerDefinition = $container->setDefinition(ErrorLoggerListener::class, new Definition(ErrorLoggerListener::class));
200 28
                $errorHandlerListenerDefinition->setPublic(true)
201 28
                    ->setArguments([new Reference($loggerServiceId, $invalidBehavior)])
202 28
                    ->addTag('kernel.event_listener', ['event' => Events::ERROR_FORMATTING, 'method' => 'onErrorFormatting']);
203
            }
204
        }
205 28
    }
206
207 28
    private function setSchemaBuilderArguments(array $config, ContainerBuilder $container): void
208
    {
209 28
        $container->getDefinition($this->getAlias().'.schema_builder')
210 28
            ->replaceArgument(1, $config['definitions']['config_validation']);
211 28
    }
212
213 28
    private function setSchemaArguments(array $config, ContainerBuilder $container): void
214
    {
215 28
        if (isset($config['definitions']['schema'])) {
216 28
            $executorDefinition = $container->getDefinition($this->getAlias().'.request_executor');
217 28
            $typeDecoratorListenerDefinition = $container->getDefinition(TypeDecoratorListener::class);
218
219 28
            foreach ($config['definitions']['schema'] as $schemaName => $schemaConfig) {
220 20
                $schemaID = \sprintf('%s.schema_%s', $this->getAlias(), $schemaName);
221 20
                $definition = new Definition(Schema::class);
222 20
                $definition->setFactory([new Reference('overblog_graphql.schema_builder'), 'create']);
223 20
                $definition->setArguments([
224 20
                    $schemaName,
225 20
                    $schemaConfig['query'],
226 20
                    $schemaConfig['mutation'],
227 20
                    $schemaConfig['subscription'],
228 20
                    $schemaConfig['types'],
229
                ]);
230 20
                $definition->setPublic(false);
231 20
                $container->setDefinition($schemaID, $definition);
232
233 20
                if (!empty($schemaConfig['resolver_maps'])) {
234
                    $typeDecoratorListenerDefinition->addMethodCall(
235
                        'addSchemaResolverMaps',
236
                        [
237
                            $schemaName,
238
                            \array_map(function ($id) {
239
                                return new Reference($id);
240
                            }, $schemaConfig['resolver_maps']),
241
                        ]
242
                    );
243
                }
244 20
                $executorDefinition->addMethodCall('addSchema', [$schemaName, new Reference($schemaID)]);
245
            }
246
        }
247 28
    }
248
249 28
    private function setServicesAliases(array $config, ContainerBuilder $container): void
250
    {
251 28
        if (isset($config['services'])) {
252 28
            foreach ($config['services'] as $name => $id) {
253 28
                $alias = \sprintf('%s.%s', $this->getAlias(), $name);
254 28
                $container->setAlias($alias, $id);
255
            }
256
        }
257 28
    }
258
259
    /**
260
     * Returns a list of custom exceptions mapped to error/warning classes.
261
     *
262
     * @param array $exceptionConfig
263
     *
264
     * @return array Custom exception map, [exception => UserError/UserWarning]
265
     */
266 28
    private function buildExceptionMap(array $exceptionConfig)
267
    {
268 28
        $exceptionMap = [];
269
        $errorsMapping = [
270 28
            'errors' => UserError::class,
271
            'warnings' => UserWarning::class,
272
        ];
273
274 28
        foreach ($exceptionConfig as $type => $exceptionList) {
275 28
            foreach ($exceptionList as $exception) {
276 2
                $exceptionMap[$exception] = $errorsMapping[$type];
277
            }
278
        }
279
280 28
        return $exceptionMap;
281
    }
282
}
283