QueryTrait::printType()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 5
c 1
b 0
f 1
nc 4
nop 1
dl 0
loc 9
rs 9.6111
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 static::class === Mutation::class ? sprintf('%s', static::KEYWORD) : '';
0 ignored issues
show
introduced by
The condition static::class === Fnash\GraphQL\Mutation::class is always false.
Loading history...
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
                if (preg_match_all('/"""/', $argValue) !== 2) { // if not a multi line argument value
162
                    $argValue = sprintf('"%s"', $argValue);
163
                }
164
            }
165
166
            if (\is_bool($argValue) || \is_float($argValue)) {
167
                $argValue = var_export($argValue, true);
168
            }
169
170
            $args[] = sprintf('%s: %s', $argName, $argValue);
171
        }
172
173
        return sprintf('(%s)', implode(', ', $args));
174
    }
175
176
    /**
177
     * @param array $fields
178
     *
179
     * @return self
180
     */
181
    public function fields(array $fields = [])
182
    {
183
        foreach ($fields as $fieldAlias => $field) {
184
            if (\is_string($field)) {
185
                if (\is_string($fieldAlias)) {
186
                    $this->fields[$fieldAlias] = $field;
187
                } else {
188
                    $this->fields[$field] = $field;
189
                }
190
            }
191
192
            if ($field instanceof Query) {
193
                $field->isRootQuery = false;
194
                $this->fields[$fieldAlias] = $field;
195
            }
196
        }
197
198
        ksort($this->fields);
199
200
        return $this;
201
    }
202
203
    /**
204
     * @param array $fields
205
     *
206
     * @return self
207
     */
208
    public function removeFields(array $fields = []): Query
209
    {
210
        foreach ($fields as $field) {
211
            unset($this->fields[$field]);
212
        }
213
214
        return $this;
215
    }
216
217
    /**
218
     * @param array $value
219
     * @param array $skipIf
220
     * @param array $includeIf
221
     *
222
     * @return string
223
     */
224
    private static function printFields(array $value, array $skipIf = [], array $includeIf = []): string
225
    {
226
        $fields = [];
227
228
        foreach ($value as $fieldAlias => $field) {
229
            $directive = '';
230
231
            if (\is_string($field)) {
232
                if ($fieldAlias !== $field) {
233
                    if (array_key_exists($fieldAlias, $skipIf)) {
234
                        $directive = sprintf('@skip(if: %s)', $skipIf[$fieldAlias]);
235
                    } elseif (array_key_exists($fieldAlias, $includeIf)) {
236
                        $directive = sprintf('@include(if: %s)', $includeIf[$fieldAlias]);
237
                    }
238
239
                    $fields[] = sprintf('%s: %s %s', $fieldAlias, $field, $directive);
240
                } else {
241
                    if (array_key_exists($field, $skipIf)) {
242
                        $directive = sprintf('@skip(if: %s)', $skipIf[$field]);
243
                    } elseif (array_key_exists($field, $includeIf)) {
244
                        $directive = sprintf('@include(if: %s)', $includeIf[$field]);
245
                    }
246
247
                    $fields[] = sprintf('%s %s', $field, $directive);
248
                }
249
            }
250
251
            if ($field instanceof Query) {
252
                $field->isRootQuery = false;
253
254
                if (array_key_exists($fieldAlias, $skipIf)) {
255
                    $directive = sprintf('@skip(if: %s)', $skipIf[$fieldAlias]);
256
                } elseif (array_key_exists($fieldAlias, $includeIf)) {
257
                    $directive = sprintf('@include(if: %s)', $includeIf[$fieldAlias]);
258
                }
259
260
                if (null !== $field->type) {
261
                    $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

261
                    $fieldAlias = sprintf('%s: %s', $fieldAlias, /** @scrutinizer ignore-type */ $field->type);
Loading history...
262
                }
263
264
                $fields[] = sprintf('%s %s { %s }', $fieldAlias, $directive, static::printFields($field->fields));
265
            }
266
        }
267
268
        return implode(', ', $fields);
269
    }
270
271
    /**
272
     * @param array $values
273
     *
274
     * @return self
275
     */
276
    public function skipIf(array $values = [])
277
    {
278
        foreach ($values as $field => $argument) {
279
            $this->skipIf[$field] = $argument;
280
        }
281
282
        return $this;
283
    }
284
285
    /**
286
     * @param array $values
287
     *
288
     * @return self
289
     */
290
    public function includeIf(array $values = [])
291
    {
292
        foreach ($values as $field => $argument) {
293
            $this->includeIf[$field] = $argument;
294
        }
295
296
        return $this;
297
    }
298
299
    public function __toString()
300
    {
301
        if ($this->isRootQuery) {
302
            $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

302
            $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...
303
        } else {
304
            $query = sprintf('%s { %s }', static::printType($this->type), static::printFields($this->fields, $this->skipIf, $this->includeIf));
305
        }
306
307
        $query = \GraphQL\Language\Printer::doPrint(\GraphQL\Language\Parser::parse((string) $query));
308
309
        $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...
310
311
        return $query;
312
    }
313
314
    /**
315
     * @param Fragment $fragment
316
     *
317
     * @return $this
318
     */
319
    public function addFragment(Fragment $fragment)
320
    {
321
        $this->fragments[$fragment->name] = $fragment;
322
323
        return $this;
324
    }
325
326
    /**
327
     * @param $value
328
     *
329
     * @return string
330
     */
331
    private function printFragments($value)
332
    {
333
        $fragments = '';
334
        foreach ($value as $fragment) {
335
            $fragments .= (string) $fragment;
336
        }
337
338
        return $fragments;
339
    }
340
341
    /**
342
     * @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...
343
     * @param array $args
344
     * @param array $fields
345
     */
346
    private function __construct($type = null, array $args = [], array $fields = [])
347
    {
348
        $this->type = $type;
349
350
        $this->arguments($args);
351
352
        $this->fields($fields);
353
    }
354
355
    private static function printType($value): string
356
    {
357
        if (\is_string($value)) {
358
            return $value;
359
        }
360
361
        if (\is_array($value) && \count($value)) {
362
            foreach ($value as $alias => $type) {
363
                return sprintf('%s: %s', $alias, $type);
364
            }
365
        }
366
    }
367
}
368