YamlDriver   B
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 10
dl 0
loc 211
c 0
b 0
f 0
rs 8.8

11 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 8 2
C loadFile() 0 28 7
A mapQuery() 0 10 2
A mapMutation() 0 10 2
A mapTypes() 0 7 2
A mapInterfaces() 0 7 2
B createType() 0 23 5
A populateType() 0 6 2
A populateFieldContainer() 0 19 4
A createInterface() 0 12 2
B createField() 0 21 6
1
<?php
2
namespace Arthem\GraphQLMapper\Mapping\Driver;
3
4
use Arthem\GraphQLMapper\Mapping\AbstractType;
5
use Arthem\GraphQLMapper\Mapping\Field;
6
use Arthem\GraphQLMapper\Mapping\FieldContainer;
7
use Arthem\GraphQLMapper\Mapping\InterfaceType;
8
use Arthem\GraphQLMapper\Mapping\Mutation;
9
use Arthem\GraphQLMapper\Mapping\Query;
10
use Arthem\GraphQLMapper\Mapping\SchemaContainer;
11
use Arthem\GraphQLMapper\Mapping\Type;
12
use Symfony\Component\Yaml\Yaml;
13
14
class YamlDriver extends FileDriver
15
{
16
    /**
17
     * {@inheritdoc}
18
     */
19
    public function load(SchemaContainer $schema)
20
    {
21
        $paths = $this->getPaths();
22
23
        foreach ($paths as $path) {
24
            $this->loadFile($path, $schema);
25
        }
26
    }
27
28
    /**
29
     * @param string          $path
30
     * @param SchemaContainer $schemaContainer
31
     */
32
    private function loadFile($path, SchemaContainer $schemaContainer)
33
    {
34
        $config = Yaml::parse($this->getFileContent($path));
35
36
        if (!is_array($config)) {
37
            return;
38
        }
39
40
        /** @var array $config */
41
        foreach ($config as $type => $mapping) {
42
            switch ($type) {
43
                case 'query':
44
                    $this->mapQuery($schemaContainer, $mapping);
45
                    break;
46
                case 'mutation':
47
                    $this->mapMutation($schemaContainer, $mapping);
48
                    break;
49
                case 'types':
50
                    $this->mapTypes($schemaContainer, $mapping);
51
                    break;
52
                case 'interfaces':
53
                    $this->mapInterfaces($schemaContainer, $mapping);
54
                    break;
55
                default:
56
                    throw new \UnexpectedValueException(sprintf('Unsupported key "%s"', $type));
57
            }
58
        }
59
    }
60
61
    /**
62
     * @param SchemaContainer $schemaContainer
63
     * @param array           $mapping
64
     */
65
    private function mapQuery(SchemaContainer $schemaContainer, array $mapping)
66
    {
67
        $querySchema = $schemaContainer->getQuerySchema();
68
        if (null === $querySchema) {
69
            $querySchema = new Query();
70
            $schemaContainer->setQuerySchema($querySchema);
71
        }
72
73
        $this->populateFieldContainer($querySchema, $mapping, true);
74
    }
75
76
    /**
77
     * @param SchemaContainer $schemaContainer
78
     * @param array           $mapping
79
     */
80
    private function mapMutation(SchemaContainer $schemaContainer, array $mapping)
81
    {
82
        $mutationSchema = $schemaContainer->getMutationSchema();
83
        if (null === $mutationSchema) {
84
            $mutationSchema = new Mutation();
85
            $schemaContainer->setMutationSchema($mutationSchema);
86
        }
87
88
        $this->populateFieldContainer($mutationSchema, $mapping);
89
    }
90
91
    /**
92
     * @param SchemaContainer $schemaContainer
93
     * @param array           $mapping
94
     */
95
    private function mapTypes(SchemaContainer $schemaContainer, array $mapping)
96
    {
97
        foreach ($mapping as $name => $typeMapping) {
98
            $type = $this->createType($name, $typeMapping);
99
            $schemaContainer->addType($type);
100
        }
101
    }
102
103
    /**
104
     * @param SchemaContainer $schemaContainer
105
     * @param array           $mapping
106
     */
107
    private function mapInterfaces(SchemaContainer $schemaContainer, array $mapping)
108
    {
109
        foreach ($mapping as $name => $interfaceMapping) {
110
            $interface = $this->createInterface($name, $interfaceMapping);
111
            $schemaContainer->addInterface($interface);
112
        }
113
    }
114
115
    /**
116
     * @param string $name
117
     * @param array  $mapping
118
     * @return Type
119
     */
120
    private function createType($name, array $mapping)
121
    {
122
        $type = new Type();
123
        $type
124
            ->setName($name)
125
            ->setResolveConfig(isset($mapping['resolve']) ? $mapping['resolve'] : []);
126
127
        if (!empty($mapping['interfaces'])) {
128
            $type->setInterfaces((array) $mapping['interfaces']);
129
        }
130
131
        if (isset($mapping['values'])) {
132
            $type->setValues($mapping['values']);
133
        }
134
135
        if (isset($mapping['model'])) {
136
            $type->setModel($mapping['model']);
137
        }
138
139
        $this->populateFieldContainer($type, $mapping);
140
141
        return $type;
142
    }
143
144
    /**
145
     * @param AbstractType $type
146
     * @param array        $mapping
147
     */
148
    private function populateType(AbstractType $type, array $mapping)
149
    {
150
        if (isset($mapping['description'])) {
151
            $type->setDescription($mapping['description']);
152
        }
153
    }
154
155
    /**
156
     * @param FieldContainer $type
157
     * @param array          $mapping
158
     * @param bool           $append
159
     */
160
    private function populateFieldContainer(FieldContainer $type, array $mapping, $append = false)
161
    {
162
        $this->populateType($type, $mapping);
163
164
        if (!isset($mapping['fields'])) {
165
            return;
166
        }
167
168
        $fields = [];
169
        foreach ($mapping['fields'] as $name => $fieldMapping) {
170
            $fields[] = $this->createField($name, $fieldMapping);
171
        }
172
173
        if ($append) {
174
            $type->addFields($fields);
175
        } else {
176
            $type->setFields($fields);
177
        }
178
    }
179
180
    /**
181
     * @param string $name
182
     * @param array  $mapping
183
     * @return InterfaceType
184
     */
185
    private function createInterface($name, array $mapping)
186
    {
187
        $interface = new InterfaceType();
188
        $interface->setName($name);
189
        $this->populateFieldContainer($interface, $mapping);
190
191
        if (isset($mapping['model'])) {
192
            $interface->setModel($mapping['model']);
193
        }
194
195
        return $interface;
196
    }
197
198
    /**
199
     * @param string $name
200
     * @param array  $mapping
201
     * @return Field
202
     */
203
    private function createField($name, array $mapping)
204
    {
205
        $field = new Field();
206
        $field
207
            ->setName($name)
208
            ->setType(isset($mapping['type']) ? $mapping['type'] : null)
209
            ->setProperty(isset($mapping['property']) ? $mapping['property'] : null)
210
            ->setResolveConfig(isset($mapping['resolve']) ? $mapping['resolve'] : []);
211
212
        $this->populateType($field, $mapping);
213
214
        if (isset($mapping['args'])) {
215
            $args = [];
216
            foreach ($mapping['args'] as $argName => $argMapping) {
217
                $args[] = $this->createField($argName, $argMapping);
218
            }
219
            $field->setArguments($args);
220
        }
221
222
        return $field;
223
    }
224
}
225