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
47:23 queued 23:20
created

ExpressionLanguage::getGlobalNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
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\ExpressionLanguage;
6
7
use Overblog\GraphQLBundle\Generator\TypeGenerator;
8
use Symfony\Component\ExpressionLanguage\Expression;
9
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
10
use Symfony\Component\ExpressionLanguage\Lexer;
11
use Symfony\Component\ExpressionLanguage\SyntaxError;
12
use Symfony\Component\ExpressionLanguage\Token;
13
use function array_merge;
14
use function strlen;
15
use function strpos;
16
use function substr;
17
18
class ExpressionLanguage extends BaseExpressionLanguage
19
{
20
    // TODO (murtukov): make names conditional
21
    public const KNOWN_NAMES = ['value', 'args', 'context', 'info', 'object', 'validator', 'errors', 'childrenComplexity', 'typeName', 'fieldName'];
22
    public const EXPRESSION_TRIGGER = '@=';
23
24
    /** @var array<string, string> */
25 149
    public array $globalNames = [];
26
27 149
    /** @var array<string, string> */
28 149
    public array $expressionVariableServiceIds = [];
29
30 16
    public function addExpressionVariableNameServiceId(string $expressionVarName, string $serviceId): void
31
    {
32 16
        $this->expressionVariableServiceIds[$expressionVarName] = $serviceId;
33
        $this->addGlobalName(sprintf(TypeGenerator::GRAPHQL_SERVICES.'->get(\'%s\')', $serviceId), $expressionVarName);
34
    }
35
36
    /**
37
     * @return array<string, string>
38
     */
39
    public function getExpressionVariableServiceIds(): array
40
    {
41 54
        return $this->expressionVariableServiceIds;
42
    }
43 54
44
    public function addGlobalName(string $code, string $expressionVarName): void
45
    {
46
        $this->globalNames[$code] = $expressionVarName;
47
    }
48
49
    /**
50
     * @param string|Expression $expression
51
     * @param array             $names
52
     *
53
     * @return string
54
     */
55
    public function compile($expression, $names = [])
56
    {
57 39
        return parent::compile($expression, array_merge($names, $this->globalNames));
58
    }
59 39
60 34
    /**
61 13
     * Checks if expression string containst specific variable.
62
     *
63
     * Argument can be either an Expression object or a string with or
64
     * without a prefix
65 34
     *
66
     * @param string            $name       - name of the searched variable (needle)
67
     * @param string|Expression $expression - expression to search in (haystack)
68
     *
69
     * @throws SyntaxError
70
     */
71
    public static function expressionContainsVar(string $name, $expression): bool
72
    {
73 60
        foreach (static::extractExpressionVarNames($expression) as $varName) {
74
            if ($name === $varName) {
75 60
                return true;
76 2
            }
77 58
        }
78 33
79
        return false;
80
    }
81
82 60
    /**
83 60
     * @param string|Expression $expression - expression to search in (haystack)
84 60
     *
85 60
     * @throws SyntaxError
86
     */
87 60
    public static function extractExpressionVarNames($expression): iterable
88 60
    {
89 29
        if ($expression instanceof Expression) {
90 60
            $expression = $expression->__toString();
91 60
        } elseif (self::stringHasTrigger($expression)) {
92 60
            $expression = self::unprefixExpression($expression);
93
        }
94 60
95 60
        /** @var string $expression */
96 54
        $stream = (new Lexer())->tokenize($expression);
97
        $current = &$stream->current;
98 60
        $isProperty = false;
99
        $varNames = [];
100 29
101
        while (!$stream->isEOF()) {
102
            if ('.' === $current->value) {
103
                $isProperty = true;
104 59
            } elseif (Token::NAME_TYPE === $current->type) {
105
                if (!$isProperty) {
106
                    $name = $current->value;
107 60
                    // Also check that it's not a function's name
108
                    $stream->next();
109
                    if ('(' !== $current->value) {
110
                        $varNames[] = $name;
111
                    }
112
                    continue;
113
                } else {
114
                    $isProperty = false;
115 38
                }
116
            }
117 38
118 38
            $stream->next();
119
        }
120
121 3
        return $varNames;
122
    }
123
124
    /**
125
     * Checks if value is a string and has the expression trigger prefix.
126
     *
127 66
     * @param mixed $value
128
     */
129 66
    public static function isStringWithTrigger($value): bool
130
    {
131
        if (is_string($value)) {
132
            return self::stringHasTrigger($value);
133
        }
134
135
        return false;
136
    }
137
138
    /**
139
     * Checks if a string has the expression trigger prefix.
140 33
     */
141
    public static function stringHasTrigger(string $maybeExpression): bool
142 33
    {
143
        return 0 === strpos($maybeExpression, self::EXPRESSION_TRIGGER);
144 33
    }
145
146
    /**
147
     * Removes the expression trigger prefix from a string. If no prefix found,
148
     * returns the initial string.
149
     *
150
     * @param string $expression - String expression with a trigger prefix
151
     *
152
     * @return string
153
     */
154
    public static function unprefixExpression(string $expression)
155
    {
156
        $string = substr($expression, strlen(self::EXPRESSION_TRIGGER));
157
158
        return '' !== $string ? $string : $expression;
159
    }
160
}
161