Passed
Push — v3 ( 6054b6...238b69 )
by Andrew
27:44 queued 16:28
created

Autocomplete   F

Complexity

Total Complexity 87

Size/Duplication

Total Lines 468
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 264
c 3
b 1
f 0
dl 0
loc 468
ccs 0
cts 312
cp 0
rs 2
wmc 87

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getBehaviorCompletion() 0 6 3
A overrideValues() 0 5 1
C generate() 0 52 13
F getMethodCompletion() 0 79 18
A getComponentCompletion() 0 12 5
B getClassCompletion() 0 30 6
A elementRouteVariables() 0 13 4
F getPropertyCompletion() 0 101 36
A parseObject() 0 16 1

How to fix   Complexity   

Complex Class

Complex classes like Autocomplete often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Autocomplete, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * SEOmatic plugin for Craft CMS 3.x
4
 *
5
 * @link      https://nystudio107.com/
6
 * @copyright Copyright (c) 2021 nystudio107
7
 * @license   https://nystudio107.com/license
0 ignored issues
show
Coding Style introduced by
@license tag must contain a URL and a license name
Loading history...
8
 */
9
10
namespace nystudio107\seomatic\helpers;
11
12
use Craft;
13
use craft\base\Element;
14
use craft\helpers\ArrayHelper;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, nystudio107\seomatic\helpers\ArrayHelper. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
use phpDocumentor\Reflection\DocBlockFactory;
16
use ReflectionClass;
17
use ReflectionException;
18
use ReflectionNamedType;
19
use ReflectionUnionType;
20
use yii\base\Behavior;
21
use yii\base\InvalidConfigException;
22
use yii\di\ServiceLocator;
23
24
/**
25
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
26
 * @package   Seomatic
27
 * @since     3.4.21
28
 */
29
class Autocomplete
30
{
31
    // Constants
32
    // =========================================================================
33
34
    const COMPLETION_KEY = '__completions';
35
    const EXCLUDED_PROPERTY_NAMES = [
36
        'controller',
37
        'Controller',
38
        'CraftEdition',
39
        'CraftSolo',
40
        'CraftPro',
41
    ];
42
    const EXCLUDED_BEHAVIOR_NAMES = [
43
        'fieldHandles',
44
        'hasMethods',
45
        'owner',
46
    ];
47
    const ELEMENT_ROUTE_EXCLUDES = [
48
        'matrixblock',
49
        'globalset'
50
    ];
51
    const EXCLUDED_PROPERTY_REGEXES = [
52
        '^_',
53
    ];
54
    const EXCLUDED_METHOD_REGEXES = [
55
        '^_',
56
    ];
57
58
    // Faux enum, from: https://microsoft.github.io/monaco-editor/api/enums/monaco.languages.completionitemkind.html
59
    const CompletionItemKind = [
0 ignored issues
show
Coding Style introduced by
This class constant is not uppercase (expected COMPLETIONITEMKIND).
Loading history...
60
        'Class' => 5,
61
        'Color' => 19,
62
        'Constant' => 14,
63
        'Constructor' => 2,
64
        'Customcolor' => 22,
65
        'Enum' => 15,
66
        'EnumMember' => 16,
67
        'Event' => 10,
68
        'Field' => 3,
69
        'File' => 20,
70
        'Folder' => 23,
71
        'Function' => 1,
72
        'Interface' => 7,
73
        'Issue' => 26,
74
        'Keyword' => 17,
75
        'Method' => 0,
76
        'Module' => 8,
77
        'Operator' => 11,
78
        'Property' => 9,
79
        'Reference' => 21,
80
        'Snippet' => 27,
81
        'Struct' => 6,
82
        'Text' => 18,
83
        'TypeParameter' => 24,
84
        'Unit' => 12,
85
        'User' => 25,
86
        'Value' => 13,
87
        'Variable' => 4,
88
    ];
89
90
    // Public Static Methods
91
    // =========================================================================
92
93
    /**
94
     * Core function that generates the autocomplete array
95
     * @param null $additionalCompletionsCacheKey
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $additionalCompletionsCacheKey is correct as it would always require null to be passed?
Loading history...
Coding Style introduced by
There must be exactly one blank line before the tags in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
96
     * @return array
0 ignored issues
show
Coding Style introduced by
Tag @return cannot be grouped with parameter tags in a doc comment
Loading history...
97
     */
98
    public static function generate($additionalCompletionsCacheKey = null): array
99
    {
100
        $completionList = [];
101
        // Iterate through the globals in the Twig context
102
        /* @noinspection PhpInternalEntityUsedInspection */
103
        $globals = array_merge(
104
            Craft::$app->view->getTwig()->getGlobals(),
105
            self::elementRouteVariables(),
106
            self::overrideValues()
107
        );
108
        foreach ($globals as $key => $value) {
109
            if (!in_array($key, self::EXCLUDED_PROPERTY_NAMES, true)) {
110
                $type = gettype($value);
111
                switch ($type) {
112
                    case 'object':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
113
                        self::parseObject($completionList, $key, $value);
114
                        break;
115
116
                    case 'array':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
117
                    case 'boolean':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
118
                    case 'double':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
119
                    case 'integer':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
120
                    case 'string':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
121
                        $kind = self::CompletionItemKind['Variable'];
122
                        $path = $key;
123
                        $normalizedKey = preg_replace("/[^A-Za-z]/", '', $key);
124
                        if (ctype_upper($normalizedKey)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
125
                            $kind = self::CompletionItemKind['Constant'];
126
                        }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
127
                        ArrayHelper::setValue($completionList, $path, [
128
                            self::COMPLETION_KEY => [
129
                                'detail' => "$value",
130
                                'kind' => $kind,
131
                                'label' => $key,
132
                                'insertText' => $key,
133
                            ]
134
                        ]);
135
                        break;
136
                }
137
            }
138
        }
139
        // Add in additional completion items from the cache, if present
140
        if ($additionalCompletionsCacheKey) {
0 ignored issues
show
introduced by
$additionalCompletionsCacheKey is of type null, thus it always evaluated to false.
Loading history...
141
            $cache = Craft::$app->getCache();
142
            $additionalCompletions = $cache->get([self::class, $additionalCompletionsCacheKey]);
143
            if ($additionalCompletions !== false && is_array($additionalCompletions)) {
144
                $completionList = array_merge($completionList, $additionalCompletions);
145
            }
146
147
        }
148
149
        return $completionList;
150
    }
151
152
    /**
153
     * Parse the object passed in, including any properties or methods
154
     *
155
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
156
     * @param string $name
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
157
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
158
     * @param string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
159
     */
160
    public static function parseObject(array &$completionList, string $name, $object, string $path = '')
161
    {
162
        // Create the docblock factory
163
        $factory = DocBlockFactory::createInstance();
164
165
        $path = trim(implode('.', [$path, $name]), '.');
166
        // The class itself
167
        self::getClassCompletion($completionList, $object, $factory, $name, $path);
168
        // ServiceLocator Components
169
        self::getComponentCompletion($completionList, $object, $path);
170
        // Class properties
171
        self::getPropertyCompletion($completionList, $object, $factory, $path);
172
        // Class methods
173
        self::getMethodCompletion($completionList, $object, $factory, $path);
174
        // Behavior properties
175
        self::getBehaviorCompletion($completionList, $object, $factory, $path);
176
    }
177
178
    // Protected Static Methods
179
    // =========================================================================
180
181
    /**
182
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
183
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
184
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
185
     * @param string $name
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
186
     * @param $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
187
     */
188
    protected static function getClassCompletion(array &$completionList, $object, DocBlockFactory $factory, string $name, $path)
189
    {
190
        try {
191
            $reflectionClass = new ReflectionClass($object);
192
        } catch (ReflectionException $e) {
193
            return;
194
        }
195
        // Information on the class itself
196
        $className = $reflectionClass->getName();
197
        $docs = $reflectionClass->getDocComment();
198
        if ($docs) {
199
            $docblock = $factory->create($docs);
200
            if ($docblock) {
0 ignored issues
show
introduced by
$docblock is of type phpDocumentor\Reflection\DocBlock, thus it always evaluated to true.
Loading history...
201
                $summary = $docblock->getSummary();
202
                if (!empty($summary)) {
203
                    $docs = $summary;
204
                }
205
                $description = $docblock->getDescription()->render();
206
                if (!empty($description)) {
207
                    $docs = $description;
208
                }
209
            }
210
        }
211
        ArrayHelper::setValue($completionList, $path, [
212
            self::COMPLETION_KEY => [
213
                'detail' => "$className",
214
                'documentation' => $docs,
215
                'kind' => self::CompletionItemKind['Class'],
216
                'label' => $name,
217
                'insertText' => $name,
218
            ]
219
        ]);
220
    }
221
222
    /**
223
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
224
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
225
     * @param $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
226
     */
227
    protected static function getComponentCompletion(array &$completionList, $object, $path)
228
    {
229
        if ($object instanceof ServiceLocator) {
230
            foreach ($object->getComponents() as $key => $value) {
231
                $componentObject = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $componentObject is dead and can be removed.
Loading history...
232
                try {
233
                    $componentObject = $object->get($key);
234
                } catch (InvalidConfigException $e) {
235
                    // That's okay
236
                }
237
                if ($componentObject) {
238
                    self::parseObject($completionList, $key, $componentObject, $path);
239
                }
240
            }
241
        }
242
    }
243
244
    /**
245
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
246
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
247
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
248
     * @param string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
249
     */
250
    protected static function getPropertyCompletion(array &$completionList, $object, DocBlockFactory $factory, string $path)
251
    {
252
        try {
253
            $reflectionClass = new ReflectionClass($object);
254
        } catch (ReflectionException $e) {
255
            return;
256
        }
257
        $reflectionProperties = $reflectionClass->getProperties();
258
        $customField = false;
259
        if ($object instanceof Behavior) {
260
            $customField = true;
261
        }
262
        $sortPrefix = $customField ? '~' : '~~';
263
        foreach ($reflectionProperties as $reflectionProperty) {
264
            $propertyName = $reflectionProperty->getName();
265
            // Exclude some properties
266
            $propertyAllowed = true;
267
            foreach (self::EXCLUDED_PROPERTY_REGEXES as $excludePattern) {
268
                $pattern = '`' . $excludePattern . '`i';
269
                if (preg_match($pattern, $propertyName) === 1) {
270
                    $propertyAllowed = false;
271
                }
272
            }
273
            if (in_array($propertyName, self::EXCLUDED_PROPERTY_NAMES, true)) {
274
                $propertyAllowed = false;
275
            }
276
            if ($customField && in_array($propertyName, self::EXCLUDED_BEHAVIOR_NAMES, true)) {
277
                $propertyAllowed = false;
278
            }
279
            // Process the property
280
            if ($propertyAllowed && $reflectionProperty->isPublic()) {
281
                $detail = "Property";
282
                $docblock = null;
283
                $docs = $reflectionProperty->getDocComment();
284
                if ($docs) {
285
                    $docblock = $factory->create($docs);
286
                    $docs = '';
287
                    if ($docblock) {
288
                        $summary = $docblock->getSummary();
289
                        if (!empty($summary)) {
290
                            $docs = $summary;
291
                        }
292
                        $description = $docblock->getDescription()->render();
293
                        if (!empty($description)) {
294
                            $docs = $description;
295
                        }
296
                    }
297
                }
298
                // Figure out the type
299
                if ($docblock) {
300
                    $tag = $docblock->getTagsByName('var');
301
                    if ($tag && isset($tag[0])) {
302
                        $detail = strval($tag[0]);
303
                    }
304
                }
305
                if ($detail === "Property") {
306
                    if (preg_match('/@var\s+([^\s]+)/', $docs, $matches)) {
307
                        list(, $type) = $matches;
308
                        $detail = $type;
309
                    } else {
310
                        $detail = "Property";
311
                    }
312
                }
313
                if ($detail === "Property") {
314
                    if ((PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION >= 8)) {
315
                        if ($reflectionProperty->hasType()) {
316
                            $reflectionType = $reflectionProperty->getType();
317
                            if ($reflectionType instanceof ReflectionNamedType) {
318
                                $type = $reflectionType->getName();
319
                                $detail = $type;
320
                            }
321
                        }
322
                        if (PHP_MAJOR_VERSION >= 8) {
323
                            if ($reflectionProperty->hasDefaultValue()) {
324
                                $value = $reflectionProperty->getDefaultValue();
325
                                if (is_array($value)) {
326
                                    $value = json_encode($value);
327
                                }
328
                                if (!empty($value)) {
329
                                    $detail = "$value";
330
                                }
331
                            }
332
                        }
333
                    }
334
                }
335
                $thisPath = trim(implode('.', [$path, $propertyName]), '.');
336
                $label = $propertyName;
337
                ArrayHelper::setValue($completionList, $thisPath, [
338
                    self::COMPLETION_KEY => [
339
                        'detail' => $detail,
340
                        'documentation' => $docs,
341
                        'kind' => $customField ? self::CompletionItemKind['Field'] : self::CompletionItemKind['Property'],
342
                        'label' => $label,
343
                        'insertText' => $label,
344
                        'sortText' => $sortPrefix . $label,
345
                    ]
346
                ]);
347
                // Recurse through if this is an object
348
                if (isset($object->$propertyName) && is_object($object->$propertyName)) {
349
                    if (!$customField && !in_array($propertyName, self::EXCLUDED_PROPERTY_NAMES, true)) {
350
                        self::parseObject($completionList, $propertyName, $object->$propertyName, $path);
351
                    }
352
                }
353
            }
354
        }
355
    }
356
357
    /**
358
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
359
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
360
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
361
     * @param string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
362
     */
363
    protected static function getMethodCompletion(array &$completionList, $object, DocBlockFactory $factory, string $path)
364
    {
365
        try {
366
            $reflectionClass = new ReflectionClass($object);
367
        } catch (ReflectionException $e) {
368
            return;
369
        }
370
        $reflectionMethods = $reflectionClass->getMethods();
371
        foreach ($reflectionMethods as $reflectionMethod) {
372
            $methodName = $reflectionMethod->getName();
373
            // Exclude some properties
374
            $methodAllowed = true;
375
            foreach (self::EXCLUDED_METHOD_REGEXES as $excludePattern) {
376
                $pattern = '`' . $excludePattern . '`i';
377
                if (preg_match($pattern, $methodName) === 1) {
378
                    $methodAllowed = false;
379
                }
380
            }
381
            // Process the method
382
            if ($methodAllowed && $reflectionMethod->isPublic()) {
383
                $docblock = null;
384
                $docs = $reflectionMethod->getDocComment();
385
                if ($docs) {
386
                    $docblock = $factory->create($docs);
387
                    if ($docblock) {
388
                        $summary = $docblock->getSummary();
389
                        if (!empty($summary)) {
390
                            $docs = $summary;
391
                        }
392
                        $description = $docblock->getDescription()->render();
393
                        if (!empty($description)) {
394
                            $docs = $description;
395
                        }
396
                    }
397
                }
398
                $detail = $methodName . '(';
399
                $params = $reflectionMethod->getParameters();
400
                $paramList = [];
401
                foreach ($params as $param) {
402
                    if ($param->hasType()) {
403
                        $reflectionType = $param->getType();
404
                        if ($reflectionType instanceof ReflectionUnionType) {
405
                            $unionTypes = $reflectionType->getTypes();
406
                            $typeName = '';
407
                            foreach ($unionTypes as $unionType) {
408
                                $typeName .= '|' . $unionType->getName();
409
                            }
410
                            $typeName = trim($typeName, '|');
411
                            $paramList[] = $typeName . ': ' . '$' . $param->getName();
412
                        } else {
413
                            $paramList[] = $param->getType()->getName() . ': ' . '$' . $param->getName();
0 ignored issues
show
Bug introduced by
The method getName() does not exist on ReflectionType. It seems like you code against a sub-type of ReflectionType such as ReflectionNamedType. ( Ignorable by Annotation )

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

413
                            $paramList[] = $param->getType()->/** @scrutinizer ignore-call */ getName() . ': ' . '$' . $param->getName();
Loading history...
414
                        }
415
                    } else {
416
                        $paramList[] = '$' . $param->getName();
417
                    }
418
                }
419
                $detail .= implode(', ', $paramList) . ')';
420
                $thisPath = trim(implode('.', [$path, $methodName]), '.');
421
                $label = $methodName . '()';
422
                $docsPreamble = '';
423
                // Figure out the type
424
                if ($docblock) {
425
                    $tags = $docblock->getTagsByName('param');
426
                    if ($tags) {
427
                        $docsPreamble = "Parameters:\n\n";
428
                        foreach ($tags as $tag) {
429
                            $docsPreamble .= $tag . "\n";
430
                        }
431
                        $docsPreamble .= "\n";
432
                    }
433
                }
434
                ArrayHelper::setValue($completionList, $thisPath, [
435
                    self::COMPLETION_KEY => [
436
                        'detail' => $detail,
437
                        'documentation' => $docsPreamble . $docs,
438
                        'kind' => self::CompletionItemKind['Method'],
439
                        'label' => $label,
440
                        'insertText' => $label,
441
                        'sortText' => '~~~' . $label,
442
                    ]
443
                ]);
444
            }
445
        }
446
    }
447
448
    /**
449
     * @param array $completionList
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
450
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
451
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
452
     * @param string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
453
     */
454
    protected static function getBehaviorCompletion(array &$completionList, $object, DocBlockFactory $factory, string $path)
455
    {
456
        if ($object instanceof Element) {
457
            $behaviorClass = $object->getBehavior('customFields');
458
            if ($behaviorClass) {
459
                self::getPropertyCompletion($completionList, $behaviorClass, $factory, $path);
460
            }
461
        }
462
    }
463
464
    // Private Static Methods
465
    // =========================================================================
466
467
    /**
468
     * Add in the element types that could be injected as route variables
469
     *
470
     * @return array
471
     */
472
    private static function elementRouteVariables(): array
0 ignored issues
show
Coding Style introduced by
Private method name "Autocomplete::elementRouteVariables" must be prefixed with an underscore
Loading history...
473
    {
474
        $routeVariables = [];
475
        $elementTypes = Craft::$app->elements->getAllElementTypes();
0 ignored issues
show
Bug introduced by
The method getAllElementTypes() does not exist on null. ( Ignorable by Annotation )

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

475
        /** @scrutinizer ignore-call */ 
476
        $elementTypes = Craft::$app->elements->getAllElementTypes();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
476
        foreach ($elementTypes as $elementType) {
477
            /* @var Element $elementType */
478
            $key = $elementType::refHandle();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $key is correct as $elementType::refHandle() targeting craft\base\Element::refHandle() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
479
            if (!empty($key) && !in_array($key, static::ELEMENT_ROUTE_EXCLUDES)) {
480
                $routeVariables[$key] = new $elementType();
481
            }
482
        }
483
484
        return $routeVariables;
485
    }
486
487
    /**
488
     * Override certain values that we always want hard-coded
489
     *
490
     * @return array
491
     */
492
    private static function overrideValues(): array
0 ignored issues
show
Coding Style introduced by
Private method name "Autocomplete::overrideValues" must be prefixed with an underscore
Loading history...
493
    {
494
        return [
495
            // Set the nonce to a blank string, as it changes on every request
496
            'nonce' => '',
497
        ];
498
    }
499
}
500