SchemaBuilder   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
dl 0
loc 96
rs 10
c 1
b 0
f 0
wmc 13

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
C getSchema() 0 79 12
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\GraphQl\Type;
15
16
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
17
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
18
use GraphQL\Type\Definition\ObjectType;
19
use GraphQL\Type\Definition\WrappingType;
20
use GraphQL\Type\Schema;
21
22
/**
23
 * Builds the GraphQL schema.
24
 *
25
 * @experimental
26
 *
27
 * @author Raoul Clais <[email protected]>
28
 * @author Alan Poulain <[email protected]>
29
 * @author Kévin Dunglas <[email protected]>
30
 */
31
final class SchemaBuilder implements SchemaBuilderInterface
32
{
33
    private $resourceNameCollectionFactory;
34
    private $resourceMetadataFactory;
35
    private $typesFactory;
36
    private $typesContainer;
37
    private $fieldsBuilder;
38
39
    public function __construct(ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, TypesFactoryInterface $typesFactory, TypesContainerInterface $typesContainer, FieldsBuilderInterface $fieldsBuilder)
40
    {
41
        $this->resourceNameCollectionFactory = $resourceNameCollectionFactory;
42
        $this->resourceMetadataFactory = $resourceMetadataFactory;
43
        $this->typesFactory = $typesFactory;
44
        $this->typesContainer = $typesContainer;
45
        $this->fieldsBuilder = $fieldsBuilder;
46
    }
47
48
    public function getSchema(): Schema
49
    {
50
        $types = $this->typesFactory->getTypes();
51
        foreach ($types as $typeId => $type) {
52
            $this->typesContainer->set($typeId, $type);
53
        }
54
55
        $queryFields = ['node' => $this->fieldsBuilder->getNodeQueryFields()];
56
        $mutationFields = [];
57
        $subscriptionFields = [];
58
59
        foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) {
60
            $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
61
            /** @var array<string, mixed> $graphqlConfiguration */
62
            $graphqlConfiguration = $resourceMetadata->getGraphql() ?? [];
63
            foreach ($graphqlConfiguration as $operationName => $value) {
64
                if ('item_query' === $operationName) {
65
                    $queryFields += $this->fieldsBuilder->getItemQueryFields($resourceClass, $resourceMetadata, $operationName, []);
66
67
                    continue;
68
                }
69
70
                if ('collection_query' === $operationName) {
71
                    $queryFields += $this->fieldsBuilder->getCollectionQueryFields($resourceClass, $resourceMetadata, $operationName, []);
72
73
                    continue;
74
                }
75
76
                if ($resourceMetadata->getGraphqlAttribute($operationName, 'item_query')) {
77
                    $queryFields += $this->fieldsBuilder->getItemQueryFields($resourceClass, $resourceMetadata, $operationName, $value);
78
79
                    continue;
80
                }
81
82
                if ($resourceMetadata->getGraphqlAttribute($operationName, 'collection_query')) {
83
                    $queryFields += $this->fieldsBuilder->getCollectionQueryFields($resourceClass, $resourceMetadata, $operationName, $value);
84
85
                    continue;
86
                }
87
88
                if ('update' === $operationName) {
89
                    $subscriptionFields += $this->fieldsBuilder->getSubscriptionFields($resourceClass, $resourceMetadata, $operationName);
90
                }
91
92
                $mutationFields += $this->fieldsBuilder->getMutationFields($resourceClass, $resourceMetadata, $operationName);
93
            }
94
        }
95
96
        $schema = [
97
            'query' => new ObjectType([
98
                'name' => 'Query',
99
                'fields' => $queryFields,
100
            ]),
101
            'typeLoader' => function ($name) {
102
                $type = $this->typesContainer->get($name);
103
104
                if ($type instanceof WrappingType) {
105
                    return $type->getWrappedType(true);
106
                }
107
108
                return $type;
109
            },
110
        ];
111
112
        if ($mutationFields) {
113
            $schema['mutation'] = new ObjectType([
114
                'name' => 'Mutation',
115
                'fields' => $mutationFields,
116
            ]);
117
        }
118
119
        if ($subscriptionFields) {
120
            $schema['subscription'] = new ObjectType([
121
                'name' => 'Subscription',
122
                'fields' => $subscriptionFields,
123
            ]);
124
        }
125
126
        return new Schema($schema);
127
    }
128
}
129