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 (#586)
by Stefano
20:55
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\Definition\Type;
9
use GraphQL\Type\Schema;
10
use Overblog\GraphQLBundle\CacheWarmer\CompileCacheWarmer;
11
use Overblog\GraphQLBundle\Config\Processor\BuilderProcessor;
12
use Overblog\GraphQLBundle\Definition\Builder\SchemaBuilder;
13
use Overblog\GraphQLBundle\Definition\Resolver\MutationInterface;
14
use Overblog\GraphQLBundle\Definition\Resolver\ResolverInterface;
15
use Overblog\GraphQLBundle\Error\ErrorHandler;
16
use Overblog\GraphQLBundle\Error\ExceptionConverter;
17
use Overblog\GraphQLBundle\Error\ExceptionConverterInterface;
18
use Overblog\GraphQLBundle\Error\UserWarning;
19
use Overblog\GraphQLBundle\Event\Events;
20
use Overblog\GraphQLBundle\EventListener\ClassLoaderListener;
21
use Overblog\GraphQLBundle\EventListener\DebugListener;
22
use Overblog\GraphQLBundle\EventListener\ErrorHandlerListener;
23
use Overblog\GraphQLBundle\EventListener\ErrorLoggerListener;
24
use Overblog\GraphQLBundle\EventListener\TypeDecoratorListener;
25
use Overblog\GraphQLBundle\Request\Executor;
26
use Overblog\GraphQLBundle\Validator\ValidatorFactory;
27
use Symfony\Component\Config\FileLocator;
28
use Symfony\Component\DependencyInjection\ContainerBuilder;
29
use Symfony\Component\DependencyInjection\ContainerInterface;
30
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
31
use Symfony\Component\DependencyInjection\Reference;
32
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
33
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
34
35
class OverblogGraphQLExtension extends Extension
36
{
37 41
    public function load(array $configs, ContainerBuilder $container): void
38
    {
39 41
        $this->loadConfigFiles($container);
40 41
        $configuration = $this->getConfiguration($configs, $container);
41 41
        $config = $this->processConfiguration($configuration, $configs);
42
43 41
        $this->setBatchingMethod($config, $container);
44 41
        $this->setServicesAliases($config, $container);
45 41
        $this->setSchemaBuilderArguments($config, $container);
46 41
        $this->setSchemaArguments($config, $container);
47 41
        $this->setErrorHandler($config, $container);
48 41
        $this->setSecurity($config, $container);
49 41
        $this->setConfigBuilders($config, $container);
50 41
        $this->setDebugListener($config, $container);
51 41
        $this->setDefinitionParameters($config, $container);
52 41
        $this->setClassLoaderListener($config, $container);
53 41
        $this->setCompilerCacheWarmer($config, $container);
54 41
        $this->registerForAutoconfiguration($container);
55 41
        $this->setDefaultFieldResolver($config, $container);
56 41
        $this->registerValidatorFactory($container);
57
58 41
        $container->setParameter($this->getAlias().'.config', $config);
59 41
        $container->setParameter($this->getAlias().'.resources_dir', \realpath(__DIR__.'/../Resources'));
60 41
    }
61
62 41
    public function getAlias()
63
    {
64 41
        return Configuration::NAME;
65
    }
66
67 41
    public function getConfiguration(array $config, ContainerBuilder $container)
68
    {
69 41
        return new Configuration(
70 41
            $container->getParameter('kernel.debug'),
71 41
            $container->hasParameter('kernel.cache_dir') ? $container->getParameter('kernel.cache_dir') : null
72
        );
73
    }
74
75 41
    private function loadConfigFiles(ContainerBuilder $container): void
76
    {
77 41
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
78 41
        $loader->load('services.yaml');
79 41
        $loader->load('commands.yaml');
80 41
        $loader->load('listeners.yaml');
81 41
        $loader->load('graphql_types.yaml');
82 41
        $loader->load('graphql_resolvers.yaml');
83 41
        $loader->load('expression_language_functions.yaml');
84 41
        $loader->load('definition_config_processors.yaml');
85 41
        $loader->load('aliases.yaml');
86 41
    }
87
88 41
    private function registerForAutoconfiguration(ContainerBuilder $container): void
89
    {
90 41
        $container->registerForAutoconfiguration(MutationInterface::class)
91 41
            ->addTag('overblog_graphql.mutation');
92 41
        $container->registerForAutoconfiguration(ResolverInterface::class)
93 41
            ->addTag('overblog_graphql.resolver');
94 41
        $container->registerForAutoconfiguration(Type::class)
95 41
            ->addTag('overblog_graphql.type');
96 41
    }
97
98 41
    private function registerValidatorFactory(ContainerBuilder $container): void
99
    {
100 41
        if (\class_exists('Symfony\\Component\\Validator\\Validation')) {
101 41
            $container->register(ValidatorFactory::class)
102 41
                ->setArguments([
103 41
                    new Reference('validator.validator_factory'),
104 41
                    new Reference('translator.default', $container::NULL_ON_INVALID_REFERENCE),
105
                ])
106 41
                ->addTag(
107 41
                    'overblog_graphql.global_variable',
108
                    [
109 41
                        'alias' => 'validatorFactory',
110
                        'public' => false,
111
                    ]
112
                );
113
        }
114 41
    }
115
116 41
    private function setDefaultFieldResolver(array $config, ContainerBuilder $container): void
117
    {
118 41
        $container->setAlias($this->getAlias().'.default_field_resolver', $config['definitions']['default_field_resolver']);
119 41
    }
120
121 41
    private function setCompilerCacheWarmer(array $config, ContainerBuilder $container): void
122
    {
123 41
        $container->register(CompileCacheWarmer::class)
124 41
            ->setArguments([
125 41
                new Reference($this->getAlias().'.cache_compiler'),
126 41
                $config['definitions']['auto_compile'],
127
            ])
128 41
            ->addTag('kernel.cache_warmer', ['priority' => 50])
129
        ;
130 41
    }
131
132 41
    private function setClassLoaderListener(array $config, ContainerBuilder $container): void
133
    {
134 41
        $container->setParameter($this->getAlias().'.use_classloader_listener', $config['definitions']['use_classloader_listener']);
135 41
        if ($config['definitions']['use_classloader_listener']) {
136 40
            $definition = $container->register(
137 40
                $this->getAlias().'.event_listener.classloader_listener',
138 40
                ClassLoaderListener::class
139
            );
140 40
            $definition->setPublic(true);
141 40
            $definition->setArguments([new Reference($this->getAlias().'.cache_compiler')]);
142 40
            $definition->addTag('kernel.event_listener', ['event' => 'kernel.request', 'method' => 'load', 'priority' => 255]);
143 40
            $definition->addTag('kernel.event_listener', ['event' => 'console.command', 'method' => 'load', 'priority' => 255]);
144
        }
145 41
    }
146
147 41
    private function setDefinitionParameters(array $config, ContainerBuilder $container): void
148
    {
149
        // generator and config
150 41
        $container->setParameter($this->getAlias().'.class_namespace', $config['definitions']['class_namespace']);
151 41
        $container->setParameter($this->getAlias().'.cache_dir', $config['definitions']['cache_dir']);
152 41
        $container->setParameter($this->getAlias().'.cache_dir_permissions', $config['definitions']['cache_dir_permissions']);
153 41
        $container->setParameter($this->getAlias().'.argument_class', $config['definitions']['argument_class']);
154 41
        $container->setParameter($this->getAlias().'.use_experimental_executor', $config['definitions']['use_experimental_executor']);
155 41
    }
156
157 41
    private function setBatchingMethod(array $config, ContainerBuilder $container): void
158
    {
159 41
        $container->setParameter($this->getAlias().'.batching_method', $config['batching_method']);
160 41
    }
161
162 41
    private function setDebugListener(array $config, ContainerBuilder $container): void
163
    {
164 41
        if ($config['definitions']['show_debug_info']) {
165 1
            $definition = $container->register(DebugListener::class);
166 1
            $definition->addTag('kernel.event_listener', ['event' => Events::PRE_EXECUTOR, 'method' => 'onPreExecutor']);
167 1
            $definition->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
168
        }
169 41
    }
170
171 41
    private function setConfigBuilders(array $config, ContainerBuilder $container): void
172
    {
173 41
        foreach (BuilderProcessor::BUILDER_TYPES as $type) {
174 41
            if (!empty($config['definitions']['builders'][$type])) {
175 5
                foreach ($config['definitions']['builders'][$type] as $params) {
176 5
                    $container->addObjectResource($params['class']);
177 5
                    BuilderProcessor::addBuilderClass($params['alias'], $type, $params['class']);
178
                }
179
            }
180
        }
181 41
    }
182
183 41
    private function setSecurity(array $config, ContainerBuilder $container): void
184
    {
185 41
        $executorDefinition = $container->getDefinition(Executor::class);
186 41
        if ($config['security']['enable_introspection']) {
187 40
            $executorDefinition->addMethodCall('enableIntrospectionQuery');
188
        } else {
189 1
            $executorDefinition->addMethodCall('disableIntrospectionQuery');
190
        }
191
192 41
        foreach ($config['security'] as $key => $value) {
193 41
            $container->setParameter(\sprintf('%s.%s', $this->getAlias(), $key), $value);
194
        }
195 41
    }
196
197 41
    private function setErrorHandler(array $config, ContainerBuilder $container): void
198
    {
199 41
        if (!$config['errors_handler']['enabled']) {
200
            return;
201
        }
202
203 41
        $container->register(ExceptionConverter::class)
204 41
            ->setArgument(0, $this->buildExceptionMap($config['errors_handler']['exceptions']))
205 41
            ->setArgument(1, $config['errors_handler']['map_exceptions_to_parent']);
206
207 41
        $container->register(ErrorHandler::class)
208 41
            ->setArgument(0, new Reference(EventDispatcherInterface::class))
209 41
            ->setArgument(1, new Reference(ExceptionConverterInterface::class));
210
211 41
        $container->register(ErrorHandlerListener::class)
212 41
            ->setArgument(0, new Reference(ErrorHandler::class))
213 41
            ->setArgument(1, $config['errors_handler']['rethrow_internal_exceptions'])
214 41
            ->setArgument(2, $config['errors_handler']['debug'])
215 41
            ->addTag('kernel.event_listener', ['event' => Events::POST_EXECUTOR, 'method' => 'onPostExecutor']);
216
217 41
        $container->setAlias(ExceptionConverterInterface::class, ExceptionConverter::class);
218
219 41
        if ($config['errors_handler']['log']) {
220 41
            $loggerServiceId = $config['errors_handler']['logger_service'];
221 41
            $invalidBehavior = ErrorLoggerListener::DEFAULT_LOGGER_SERVICE === $loggerServiceId ? ContainerInterface::NULL_ON_INVALID_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
222
223 41
            $container->register(ErrorLoggerListener::class)
224 41
                ->setPublic(true)
225 41
                ->addArgument(new Reference($loggerServiceId, $invalidBehavior))
226 41
                ->addTag('kernel.event_listener', ['event' => Events::ERROR_FORMATTING, 'method' => 'onErrorFormatting']);
227
        }
228 41
    }
229
230 41
    private function setSchemaBuilderArguments(array $config, ContainerBuilder $container): void
231
    {
232 41
        $container->getDefinition(SchemaBuilder::class)
233 41
            ->replaceArgument(1, $config['definitions']['config_validation']);
234 41
    }
235
236 41
    private function setSchemaArguments(array $config, ContainerBuilder $container): void
237
    {
238 41
        if (isset($config['definitions']['schema'])) {
239 41
            $executorDefinition = $container->getDefinition(Executor::class);
240 41
            $typeDecoratorListenerDefinition = $container->getDefinition(TypeDecoratorListener::class);
241
242 41
            foreach ($config['definitions']['schema'] as $schemaName => $schemaConfig) {
243
                // builder
244 33
                $schemaBuilderID = \sprintf('%s.schema_builder_%s', $this->getAlias(), $schemaName);
245 33
                $definition = $container->register($schemaBuilderID, \Closure::class);
246 33
                $definition->setFactory([new Reference('overblog_graphql.schema_builder'), 'getBuilder']);
247 33
                $definition->setArguments([
248 33
                    $schemaName,
249 33
                    $schemaConfig['query'],
250 33
                    $schemaConfig['mutation'],
251 33
                    $schemaConfig['subscription'],
252 33
                    $schemaConfig['types'],
253
                ]);
254
                // schema
255 33
                $schemaID = \sprintf('%s.schema_%s', $this->getAlias(), $schemaName);
256 33
                $definition = $container->register($schemaID, Schema::class);
257 33
                $definition->setFactory([new Reference($schemaBuilderID), 'call']);
258
259 33
                if (!empty($schemaConfig['resolver_maps'])) {
260 1
                    $typeDecoratorListenerDefinition->addMethodCall(
261 1
                        'addSchemaResolverMaps',
262
                        [
263 1
                            $schemaName,
264
                            \array_map(function ($id) {
265 1
                                return new Reference($id);
266 1
                            }, $schemaConfig['resolver_maps']),
267
                        ]
268
                    );
269
                }
270 33
                $executorDefinition->addMethodCall('addSchemaBuilder', [$schemaName, new Reference($schemaBuilderID)]);
271
            }
272
        }
273 41
    }
274
275 41
    private function setServicesAliases(array $config, ContainerBuilder $container): void
276
    {
277 41
        if (isset($config['services'])) {
278 41
            foreach ($config['services'] as $name => $id) {
279 41
                $alias = \sprintf('%s.%s', $this->getAlias(), $name);
280 41
                $container->setAlias($alias, $id);
281
            }
282
        }
283 41
    }
284
285
    /**
286
     * Returns a list of custom exceptions mapped to error/warning classes.
287
     *
288
     * @param array<string, string[]> $exceptionConfig
289
     *
290
     * @return array<string, string> Custom exception map, [exception => UserError/UserWarning]
291
     */
292 41
    private function buildExceptionMap(array $exceptionConfig): array
293
    {
294 41
        $exceptionMap = [];
295
        $errorsMapping = [
296 41
            'errors' => UserError::class,
297
            'warnings' => UserWarning::class,
298
        ];
299
300 41
        foreach ($exceptionConfig as $type => $exceptionList) {
301 41
            foreach ($exceptionList as $exception) {
302 2
                $exceptionMap[$exception] = $errorsMapping[$type];
303
            }
304
        }
305
306 41
        return $exceptionMap;
307
    }
308
}
309