Skip to content

Commit fa88875

Browse files
committed
Make parsers configurable
1 parent 3d62d90 commit fa88875

File tree

2 files changed

+59
-12
lines changed

2 files changed

+59
-12
lines changed

src/DependencyInjection/Compiler/ConfigParserPass.php

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,34 @@
3636

3737
class ConfigParserPass implements CompilerPassInterface
3838
{
39+
public const TYPE_YAML = 'yaml';
40+
public const TYPE_GRAPHQL = 'graphql';
41+
public const TYPE_ANNOTATION = 'annotation';
42+
public const TYPE_ATTRIBUTE = 'attribute';
43+
44+
public const SUPPORTED_TYPES = [
45+
self::TYPE_YAML,
46+
self::TYPE_GRAPHQL,
47+
self::TYPE_ANNOTATION,
48+
self::TYPE_ATTRIBUTE,
49+
];
50+
3951
public const SUPPORTED_TYPES_EXTENSIONS = [
40-
'yaml' => '{yaml,yml}',
41-
'graphql' => '{graphql,graphqls}',
42-
'annotation' => 'php',
43-
'attribute' => 'php',
52+
self::TYPE_YAML => '{yaml,yml}',
53+
self::TYPE_GRAPHQL => '{graphql,graphqls}',
54+
self::TYPE_ANNOTATION => 'php',
55+
self::TYPE_ATTRIBUTE => 'php',
4456
];
4557

4658
/**
59+
* @deprecated They are going to be configurable.
4760
* @var array<string, class-string<ParserInterface|PreParserInterface>>
4861
*/
4962
public const PARSERS = [
50-
'yaml' => YamlParser::class,
51-
'graphql' => GraphQLParser::class,
52-
'annotation' => AnnotationParser::class,
53-
'attribute' => AttributeParser::class,
63+
self::TYPE_YAML => YamlParser::class,
64+
self::TYPE_GRAPHQL => GraphQLParser::class,
65+
self::TYPE_ANNOTATION => AnnotationParser::class,
66+
self::TYPE_ATTRIBUTE => AttributeParser::class,
5467
];
5568

5669
private const DEFAULT_CONFIG = [
@@ -64,6 +77,7 @@ class ConfigParserPass implements CompilerPassInterface
6477
'types' => [],
6578
],
6679
],
80+
'parsers' => self::PARSERS,
6781
];
6882

6983
/**
@@ -103,7 +117,7 @@ private function getConfigs(ContainerBuilder $container): array
103117
// Pre-parse all files
104118
AnnotationParser::reset($config);
105119
AttributeParser::reset($config);
106-
$typesNeedPreParsing = $this->typesNeedPreParsing();
120+
$typesNeedPreParsing = $this->typesNeedPreParsing($config['parsers']);
107121
foreach ($typesMappings as $params) {
108122
if ($typesNeedPreParsing[$params['type']]) {
109123
$this->parseTypeConfigFiles($params['type'], $params['files'], $container, $config, true);
@@ -122,10 +136,15 @@ private function getConfigs(ContainerBuilder $container): array
122136
return $flattenTypeConfig;
123137
}
124138

125-
private function typesNeedPreParsing(): array
139+
/**
140+
* @param array<string,string> $parsers
141+
*
142+
* @return array<string,bool>
143+
*/
144+
private function typesNeedPreParsing(array $parsers): array
126145
{
127146
$needPreParsing = [];
128-
foreach (self::PARSERS as $type => $className) {
147+
foreach ($parsers as $type => $className) {
129148
$needPreParsing[$type] = is_a($className, PreParserInterface::class, true);
130149
}
131150

@@ -152,7 +171,7 @@ private function parseTypeConfigFiles(string $type, iterable $files, ContainerBu
152171
continue;
153172
}
154173

155-
$parser = [self::PARSERS[$type], $method];
174+
$parser = [$configs['parsers'][$type], $method];
156175
if (is_callable($parser)) {
157176
$config[] = ($parser)($file, $container, $configs);
158177
}

src/DependencyInjection/Configuration.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
88
use GraphQL\Validator\Rules\QueryComplexity;
99
use GraphQL\Validator\Rules\QueryDepth;
10+
use Overblog\GraphQLBundle\Config\Parser\ParserInterface;
1011
use Overblog\GraphQLBundle\Definition\Argument;
1112
use Overblog\GraphQLBundle\DependencyInjection\Compiler\ConfigParserPass;
1213
use Overblog\GraphQLBundle\Error\ErrorHandler;
@@ -57,6 +58,7 @@ public function getConfigTreeBuilder(): TreeBuilder
5758
->append($this->securitySection())
5859
->append($this->doctrineSection())
5960
->append($this->profilerSection())
61+
->append($this->parsersSection())
6062
->end();
6163

6264
return $treeBuilder;
@@ -318,6 +320,32 @@ private function doctrineSection(): ArrayNodeDefinition
318320
return $node;
319321
}
320322

323+
private function parsersSection(): ArrayNodeDefinition
324+
{
325+
/** @var ArrayNodeDefinition $node */
326+
$node = (new TreeBuilder('parsers'))->getRootNode();
327+
$node->useAttributeAsKey('name');
328+
329+
$parserPrototype = $node->scalarPrototype();
330+
$parserPrototype->cannotBeEmpty();
331+
$parserPrototype->validate()
332+
->ifTrue(static function (string $x): bool {
333+
return !is_subclass_of($x, ParserInterface::class, true);
334+
})
335+
->thenInvalid(sprintf('Parser MUST implement "%s', ParserInterface::class));
336+
337+
$node->validate()
338+
->ifTrue(static function (array $x): bool {
339+
return (bool) array_diff(array_keys($x), ConfigParserPass::SUPPORTED_TYPES);
340+
})
341+
->then(static function (array $x) {
342+
$types = implode(', ', array_diff(array_keys($x), ConfigParserPass::SUPPORTED_TYPES));
343+
throw new \InvalidArgumentException(sprintf('Configured parsers for not supported types: %s', $types));
344+
});
345+
346+
return $node;
347+
}
348+
321349
private function profilerSection(): ArrayNodeDefinition
322350
{
323351
$builder = new TreeBuilder('profiler');

0 commit comments

Comments
 (0)