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