Passed
Push — master ( 6d775d...3ea30a )
by Fayez
03:00
created

QueryTrait::removeFields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Fnash\GraphQL;
4
5
trait QueryTrait
6
{
7
    private static $operationNamePlaceholder = '_operationNamePlaceholder_';
8
9
    /**
10
     * @var string
11
     */
12
    public $operationName;
13
14
    /**
15
     * @var array
16
     */
17
    public $variables = [];
18
19
    /**
20
     * @var bool
21
     */
22
    public $isRootQuery = true;
23
24
    /**
25
     * @var array
26
     */
27
    public $type = [];
28
29
    /**
30
     * @var array
31
     */
32
    public $args = [];
33
34
    /**
35
     * @var array
36
     */
37
    public $fields = [];
38
39
    /**
40
     * @var array
41
     */
42
    public $skipIf = [];
43
44
    /**
45
     * @var array
46
     */
47
    public $includeIf = [];
48
49
    /**
50
     * @var array
51
     */
52
    public $fragments = [];
53
54
    /**
55
     * @param null $type
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $type is correct as it would always require null to be passed?
Loading history...
56
     * @param array $args
57
     * @param array $fields
58
     *
59
     * @return self
60
     */
61
    public static function create($type = null, array $args = [], array $fields = [])
62
    {
63
        return new self($type, $args, $fields);
64
    }
65
66
    /**
67
     * @param string $operationName
68
     *
69
     * @return self
70
     */
71
    public function operationName(string $operationName)
72
    {
73
        $this->operationName = $operationName;
74
75
        return $this;
76
    }
77
78
    /**
79
     * @param $operationName
80
     * @param $variables
81
     *
82
     * @return string
83
     */
84
    private static function printQuery($operationName, $variables): string
85
    {
86
        if (null === $operationName) {
87
            if (\count($variables)) {
88
                $operationName = static::$operationNamePlaceholder;
0 ignored issues
show
Bug introduced by
Since $operationNamePlaceholder is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $operationNamePlaceholder to at least protected.
Loading history...
89
            } else {
90
                return '';
91
            }
92
        }
93
94
        return sprintf('%s %s %s', static::KEYWORD, $operationName, static::printVariables($variables));
0 ignored issues
show
Bug introduced by
The constant Fnash\GraphQL\QueryTrait::KEYWORD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
95
    }
96
97
    /**
98
     * @param array $variables
99
     *
100
     * @return self
101
     */
102
    public function variables(array $variables = [])
103
    {
104
        foreach ($variables as $variableName => $variableType) {
105
            $this->variables[(string) $variableName] = (string) $variableType;
106
        }
107
108
        return $this;
109
    }
110
111
    /**
112
     * @param array $value
113
     *
114
     * @return string
115
     */
116
    private static function printVariables(array $value): string
117
    {
118
        if (!\count($value)) {
119
            return '';
120
        }
121
122
        $variables = [];
123
124
        foreach ($value as $variableName => $variableType) {
125
            $variables[] = sprintf('%s: %s', $variableName, $variableType);
126
        }
127
128
        return sprintf('(%s)', implode(', ', $variables));
129
    }
130
131
    /**
132
     * @param array $args
133
     *
134
     * @return self
135
     */
136
    public function arguments(array $args = [])
137
    {
138
        foreach ($args as $name => $value) {
139
            $this->args[$name] = $value;
140
        }
141
142
        ksort($this->args);
143
144
        return $this;
145
    }
146
147
    /**
148
     * @param array $value
149
     *
150
     * @return string
151
     */
152
    private static function printArgs(array $value): string
153
    {
154
        if (!count($value)) {
155
            return '';
156
        }
157
158
        $args = [];
159
        foreach ($value as $argName => $argValue) {
160
            if (\is_string($argValue) && '$' !== $argValue[0]) {
161
                $argValue = sprintf('"%s"', $argValue);
162
            }
163
164
            if (\is_bool($argValue) || \is_float($argValue)) {
165
                $argValue = var_export($argValue, true);
166
            }
167
168
            $args[] = sprintf('%s: %s', $argName, $argValue);
169
        }
170
171
        return sprintf('(%s)', implode(', ', $args));
172
    }
173
174
    /**
175
     * @param array $fields
176
     *
177
     * @return self
178
     */
179
    public function fields(array $fields = [])
180
    {
181
        foreach ($fields as $fieldAlias => $field) {
182
            if (\is_string($field)) {
183
                if (\is_string($fieldAlias)) {
184
                    $this->fields[$fieldAlias] = $field;
185
                } else {
186
                    $this->fields[$field] = $field;
187
                }
188
            }
189
190
            if ($field instanceof self) {
191
                $field->isRootQuery = false;
192
                $this->fields[$fieldAlias] = $field;
193
            }
194
        }
195
196
        ksort($this->fields);
197
198
        return $this;
199
    }
200
201
    /**
202
     * @param array $fields
203
     *
204
     * @return self
205
     */
206
    public function removeFields(array $fields = []): Query
207
    {
208
        foreach ($fields as $field) {
209
            unset($this->fields[$field]);
210
        }
211
212
        return $this;
213
    }
214
215
    /**
216
     * @param array $value
217
     * @param array $skipIf
218
     * @param array $includeIf
219
     *
220
     * @return string
221
     */
222
    private static function printFields(array $value, array $skipIf = [], array $includeIf = []): string
223
    {
224
        $fields = [];
225
226
        foreach ($value as $fieldAlias => $field) {
227
            $directive = '';
228
229
            if (\is_string($field)) {
230
                if ($fieldAlias !== $field) {
231
                    if (array_key_exists($fieldAlias, $skipIf)) {
232
                        $directive = sprintf('@skip(if: %s)', $skipIf[$fieldAlias]);
233
                    } elseif (array_key_exists($fieldAlias, $includeIf)) {
234
                        $directive = sprintf('@include(if: %s)', $includeIf[$fieldAlias]);
235
                    }
236
237
                    $fields[] = sprintf('%s: %s %s', $fieldAlias, $field, $directive);
238
                } else {
239
                    if (array_key_exists($field, $skipIf)) {
240
                        $directive = sprintf('@skip(if: %s)', $skipIf[$field]);
241
                    } elseif (array_key_exists($field, $includeIf)) {
242
                        $directive = sprintf('@include(if: %s)', $includeIf[$field]);
243
                    }
244
245
                    $fields[] = sprintf('%s %s', $field, $directive);
246
                }
247
            }
248
249
            if ($field instanceof self) {
250
                $field->isRootQuery = false;
251
252
                if (array_key_exists($fieldAlias, $skipIf)) {
253
                    $directive = sprintf('@skip(if: %s)', $skipIf[$fieldAlias]);
254
                } elseif (array_key_exists($fieldAlias, $includeIf)) {
255
                    $directive = sprintf('@include(if: %s)', $includeIf[$fieldAlias]);
256
                }
257
258
                if (null !== $field->type) {
259
                    $fieldAlias = sprintf('%s: %s', $fieldAlias, $field->type);
0 ignored issues
show
Bug introduced by
$field->type of type array is incompatible with the type string expected by parameter $args of sprintf(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

259
                    $fieldAlias = sprintf('%s: %s', $fieldAlias, /** @scrutinizer ignore-type */ $field->type);
Loading history...
260
                }
261
262
                $fields[] = sprintf('%s %s { %s }', $fieldAlias, $directive, static::printFields($field->fields));
263
            }
264
        }
265
266
        return implode(', ', $fields);
267
    }
268
269
    /**
270
     * @param array $values
271
     *
272
     * @return self
273
     */
274
    public function skipIf(array $values = [])
275
    {
276
        foreach ($values as $field => $argument) {
277
            $this->skipIf[$field] = $argument;
278
        }
279
280
        return $this;
281
    }
282
283
    /**
284
     * @param array $values
285
     *
286
     * @return self
287
     */
288
    public function includeIf(array $values = [])
289
    {
290
        foreach ($values as $field => $argument) {
291
            $this->includeIf[$field] = $argument;
292
        }
293
294
        return $this;
295
    }
296
297
    public function __toString()
298
    {
299
        if ($this->isRootQuery) {
300
            $query = sprintf('%s { %s %s { %s } } %s', static::printQuery($this->operationName, $this->variables), static::printType($this->type), static::printArgs($this->args), static::printFields($this->fields, $this->skipIf, $this->includeIf), static::printFragments($this->fragments));
0 ignored issues
show
Bug Best Practice introduced by
The method Fnash\GraphQL\QueryTrait::printFragments() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

300
            $query = sprintf('%s { %s %s { %s } } %s', static::printQuery($this->operationName, $this->variables), static::printType($this->type), static::printArgs($this->args), static::printFields($this->fields, $this->skipIf, $this->includeIf), static::/** @scrutinizer ignore-call */ printFragments($this->fragments));
Loading history...
301
        } else {
302
            $query = sprintf('%s { %s }', static::printType($this->type), static::printFields($this->fields, $this->skipIf, $this->includeIf));
303
        }
304
305
        $query = \GraphQL\Language\Printer::doPrint(\GraphQL\Language\Parser::parse((string) $query));
306
307
        $query = str_replace(static::$operationNamePlaceholder, static::GENERATED_NAME_PREFIX.sha1($query), $query);
0 ignored issues
show
Bug introduced by
Since $operationNamePlaceholder is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $operationNamePlaceholder to at least protected.
Loading history...
Bug introduced by
The constant Fnash\GraphQL\QueryTrait::GENERATED_NAME_PREFIX was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
308
309
        return $query;
310
    }
311
312
    /**
313
     * @param Fragment $fragment
314
     *
315
     * @return $this
316
     */
317
    public function addFragment(Fragment $fragment)
318
    {
319
        $this->fragments[$fragment->name] = $fragment;
320
321
        return $this;
322
    }
323
324
    /**
325
     * @param $value
326
     *
327
     * @return string
328
     */
329
    private function printFragments($value)
330
    {
331
        $fragments = '';
332
        foreach ($value as $fragment) {
333
            $fragments .= (string) $fragment;
334
        }
335
336
        return $fragments;
337
    }
338
339
    /**
340
     * @param null $type
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $type is correct as it would always require null to be passed?
Loading history...
341
     * @param array $args
342
     * @param array $fields
343
     */
344
    private function __construct($type = null, array $args = [], array $fields = [])
345
    {
346
        $this->type = $type;
347
348
        $this->arguments($args);
349
350
        $this->fields($fields);
351
    }
352
353
    private static function printType($value): string
354
    {
355
        if (\is_string($value)) {
356
            return $value;
357
        }
358
359
        if (\is_array($value) && \count($value)) {
360
            foreach ($value as $alias => $type) {
361
                return sprintf('%s: %s', $alias, $type);
362
            }
363
        }
364
    }
365
}
366