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
Push — 0.13 ( ff6287...cab464 )
by Jérémiah
16s queued 11s
created

OverblogGraphQLExtension::setSchemaArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

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