Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Pull Request — 0.14 (#851)
by Jérémiah
08:23
created

TypeDefinition::descriptionSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Overblog\GraphQLBundle\Config;
6
7
use Overblog\GraphQLBundle\ExpressionLanguage\ExpressionLanguage;
8
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
9
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
10
use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
11
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
12
use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition;
13
use function is_array;
14
use function is_int;
15
use function is_string;
16
use function preg_match;
17
18
abstract class TypeDefinition
19
{
20
    public const VALIDATION_LEVEL_CLASS = 0;
21
    public const VALIDATION_LEVEL_PROPERTY = 1;
22
23
    abstract public function getDefinition(): ArrayNodeDefinition;
24
25 49
    final protected function __construct()
26
    {
27 49
    }
28
29
    /**
30
     * @return static
31
     */
32 49
    public static function create(): self
33
    {
34 49
        return new static();
35
    }
36
37 49
    protected function nameSection(): ScalarNodeDefinition
38
    {
39
        /** @var ScalarNodeDefinition $node */
40 49
        $node = self::createNode('name', 'scalar');
41
42
        $node
43 49
            ->isRequired()
44 49
            ->validate()
45 49
                ->ifTrue(fn ($name) => !preg_match('/^[_a-z][_0-9a-z]*$/i', $name))
46 49
                ->thenInvalid('Invalid type name "%s". (see http://spec.graphql.org/June2018/#sec-Names)')
47 49
            ->end()
48
        ;
49
50 49
        return $node;
51
    }
52
53 49
    protected function defaultValueSection(): VariableNodeDefinition
54
    {
55 49
        return self::createNode('defaultValue', 'variable');
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::createNode(...aultValue', 'variable') returns the type Symfony\Component\Config...\Builder\NodeDefinition which includes types incompatible with the type-hinted return Symfony\Component\Config...\VariableNodeDefinition.
Loading history...
56
    }
57
58 49
    protected function validationSection(int $level): ArrayNodeDefinition
59
    {
60
        /** @var ArrayNodeDefinition $node */
61 49
        $node = self::createNode('validation', 'array');
62
63
        /** @phpstan-ignore-next-line */
64
        $node
65
            // allow shorthands
66 49
            ->beforeNormalization()
67 49
                ->always(function ($value) {
68 3
                    if (is_string($value)) {
69
                        // shorthand: cascade or link
70 2
                        return 'cascade' === $value ? ['cascade' => null] : ['link' => $value];
71
                    }
72
73 2
                    if (is_array($value)) {
74 2
                        foreach ($value as $k => $a) {
75 2
                            if (!is_int($k)) {
76
                                // validation: { link: ... , constraints: ..., cascade: ... }
77 1
                                return $value;
78
                            }
79
                        }
80
                        // validation: [list of constraints]
81 2
                        return ['constraints' => $value];
82
                    }
83
84 1
                    return [];
85 49
                })
86 49
            ->end()
87 49
            ->children()
88 49
                ->scalarNode('link')
89 49
                    ->validate()
90 49
                        ->ifTrue(function ($link) use ($level) {
91 1
                            if (self::VALIDATION_LEVEL_PROPERTY === $level) {
92 1
                                return !preg_match('/^(?:\\\\?[A-Za-z][A-Za-z\d]+)*[A-Za-z\d]+::(?:[$]?[A-Za-z][A-Za-z_\d]+|[A-Za-z_\d]+\(\))$/m', $link);
93
                            } else {
94 1
                                return !preg_match('/^(?:\\\\?[A-Za-z][A-Za-z\d]+)*[A-Za-z\d]$/m', $link);
95
                            }
96 49
                        })
97 49
                        ->thenInvalid('Invalid link provided: "%s".')
98 49
                    ->end()
99 49
                ->end()
100 49
                ->variableNode('constraints')->end()
101 49
            ->end();
102
103
        // Add the 'cascade' option if it's a property level validation section
104 49
        if (self::VALIDATION_LEVEL_PROPERTY === $level) {
105
            /** @phpstan-ignore-next-line */
106
            $node
107 49
                ->children()
108 49
                    ->arrayNode('cascade')
109 49
                        ->children()
110 49
                            ->arrayNode('groups')
111 49
                                ->beforeNormalization()
112 49
                                    ->castToArray()
113 49
                                ->end()
114 49
                                ->scalarPrototype()->end()
0 ignored issues
show
Bug introduced by
The method scalarPrototype() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. It seems like you code against a sub-type of Symfony\Component\Config...\Builder\NodeDefinition such as Symfony\Component\Config...der\ArrayNodeDefinition. ( Ignorable by Annotation )

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

114
                                ->/** @scrutinizer ignore-call */ scalarPrototype()->end()
Loading history...
115 49
                            ->end()
116 49
                        ->end()
117 49
                    ->end()
118 49
                ->end();
119
        }
120
121 49
        return $node;
122
    }
123
124 49
    protected function descriptionSection(): ScalarNodeDefinition
125
    {
126
        /** @var ScalarNodeDefinition $node */
127 49
        $node = self::createNode('description', 'scalar');
128
129 49
        return $node;
130
    }
131
132 49
    protected function deprecationReasonSection(): ScalarNodeDefinition
133
    {
134
        /** @var ScalarNodeDefinition $node */
135 49
        $node = self::createNode('deprecationReason', 'scalar');
136
137 49
        $node->info('Text describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)');
138
139 49
        return $node;
140
    }
141
142 49
    protected function typeSection(bool $isRequired = false): ScalarNodeDefinition
143
    {
144
        /** @var ScalarNodeDefinition $node */
145 49
        $node = self::createNode('type', 'scalar');
146
147 49
        $node->info('One of internal or custom types.');
148
149 49
        if ($isRequired) {
150 49
            $node->isRequired();
151
        }
152
153 49
        return $node;
154
    }
155
156 49
    protected function callbackNormalization(NodeDefinition $node, string $new, string $old): void
157
    {
158
        $node
159 49
            ->beforeNormalization()
160 49
                ->ifTrue(fn ($options) => !empty($options[$old]) && empty($options[$new]))
161 49
                ->then(function ($options) use ($old, $new) {
162 32
                    if (is_callable($options[$old])) {
163 1
                        if (is_array($options[$old])) {
164 1
                            $options[$new]['method'] = implode('::', $options[$old]);
165
                        } else {
166 1
                            $options[$new]['method'] = $options[$old];
167
                        }
168 31
                    } elseif (is_string($options[$old])) {
169 30
                        $options[$new]['expression'] = ExpressionLanguage::stringHasTrigger($options[$old]) ?
170 30
                            ExpressionLanguage::unprefixExpression($options[$old]) :
171 30
                            json_encode($options[$old]);
172
                    } else {
173 2
                        $options[$new]['expression'] = json_encode($options[$old]);
174
                    }
175
176 32
                    return $options;
177 49
                })
178 49
            ->end()
179 49
            ->beforeNormalization()
180 49
                ->ifTrue(fn ($options) => is_array($options) && array_key_exists($old, $options))
181 49
                ->then(function ($options) use ($old) {
182 32
                    unset($options[$old]);
183
184 32
                    return $options;
185 49
                })
186 49
            ->end()
187 49
            ->validate()
188 49
                ->ifTrue(fn (array $v) => !empty($v[$new]) && !empty($v[$old]))
189 49
                ->thenInvalid(sprintf(
190 49
                    '"%s" and "%s" should not be use together in "%%s".',
191
                    $new,
192
                    $old,
193
                ))
194 49
            ->end()
195
            ;
196 49
    }
197
198 49
    protected function callbackSection(string $name, string $info): ArrayNodeDefinition
199
    {
200
        /** @var ArrayNodeDefinition $node */
201 49
        $node = self::createNode($name);
202
        /** @phpstan-ignore-next-line */
203
        $node
204 49
            ->info($info)
205 49
            ->validate()
206 49
                ->ifTrue(fn (array $v) => !empty($v['method']) && !empty($v['expression']))
207 49
                ->thenInvalid('"method" and "expression" should not be use together.')
208 49
            ->end()
209 49
            ->beforeNormalization()
210
                // Allow short syntax
211 49
                ->ifTrue(fn ($options) => is_string($options) && ExpressionLanguage::stringHasTrigger($options))
212 49
                ->then(fn ($options) => ['expression' => ExpressionLanguage::unprefixExpression($options)])
213 49
            ->end()
214 49
            ->beforeNormalization()
215 49
                ->ifTrue(fn ($options) => is_string($options) && !ExpressionLanguage::stringHasTrigger($options))
216 49
                ->then(fn ($options) => ['method' => $options])
217 49
            ->end()
218 49
            ->beforeNormalization()
219
                // clean expression
220 49
                ->ifTrue(fn ($options) => isset($options['expression']) && is_string($options['expression']) && ExpressionLanguage::stringHasTrigger($options['expression']))
221 49
                ->then(function ($options) {
222
                    $options['expression'] = ExpressionLanguage::unprefixExpression($options['expression']);
223
224
                    return $options;
225 49
                })
226 49
            ->end()
227 49
            ->children()
228 49
                ->scalarNode('method')->end()
229 49
                ->scalarNode('expression')->end()
230 49
                ->scalarNode('id')->end()
231 49
            ->end()
232
        ;
233
234 49
        return $node;
235
    }
236
237
    /**
238
     * @return mixed
239
     *
240
     * @internal
241
     */
242 49
    protected static function createNode(string $name, string $type = 'array')
243
    {
244 49
        return (new TreeBuilder($name, $type))->getRootNode();
245
    }
246
}
247