Passed
Push — v1 ( 59c81c...e467d4 )
by Andrew
11:29 queued 06:53
created

CraftApiAutocomplete::init()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 7
rs 10
1
<?php
2
/**
3
 * Twigfield for Craft CMS
4
 *
5
 * Provides a twig editor field with Twig & Craft API autocomplete
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2022 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\twigfield\autocompletes;
12
13
use Craft;
14
use craft\base\Element;
15
use nystudio107\twigfield\base\Autocomplete;
16
use nystudio107\twigfield\models\CompleteItem;
17
use nystudio107\twigfield\types\AutocompleteTypes;
18
use nystudio107\twigfield\types\CompleteItemKind;
19
use phpDocumentor\Reflection\DocBlockFactory;
20
use ReflectionClass;
21
use ReflectionException;
22
use ReflectionNamedType;
23
use ReflectionUnionType;
24
use yii\base\Behavior;
25
use yii\base\InvalidConfigException;
26
use yii\di\ServiceLocator;
27
28
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
29
 * @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...
Coding Style introduced by
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
30
 * @package   twigfield
0 ignored issues
show
Coding Style introduced by
Package name "twigfield" is not valid; consider "Twigfield" instead
Loading history...
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
31
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
32
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
33
class CraftApiAutocomplete extends Autocomplete
34
{
35
    // Constants
36
    // =========================================================================
37
38
    const EXCLUDED_PROPERTY_NAMES = [
39
        'controller',
40
        'Controller',
41
        'CraftEdition',
42
        'CraftSolo',
43
        'CraftPro',
44
    ];
45
    const EXCLUDED_BEHAVIOR_NAMES = [
46
        'fieldHandles',
47
        'hasMethods',
48
        'owner',
49
    ];
50
    const ELEMENT_ROUTE_EXCLUDES = [
51
        'matrixblock',
52
        'globalset'
53
    ];
54
    const EXCLUDED_PROPERTY_REGEXES = [
55
        '^_',
56
    ];
57
    const EXCLUDED_METHOD_REGEXES = [
58
        '^_',
59
    ];
60
    const RECURSION_DEPTH_LIMIT = 10;
61
62
    // Public Properties
63
    // =========================================================================
64
65
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
66
     * @var string The name of the autocomplete
67
     */
68
    public $name = 'CraftApiAutocomplete';
69
70
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
71
     * @var string The type of the autocomplete
72
     */
73
    public $type = AutocompleteTypes::TwigExpressionAutocomplete;
74
75
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
76
     * @var string Whether the autocomplete should be parsed with . -delimited nested sub-properties
77
     */
78
    public $hasSubProperties = true;
79
80
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
81
     * @var array A key-value array of the Twig global variables to parse. If left empty, it will
82
     * default to the current Twig context global variables
83
     */
84
    public $twigGlobals = [];
85
86
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
87
     * @var array A key-value array of the Element Route variables (the injected `entry`, etc.
88
     * variable). If left empty, it will default to the current Element Route variables
89
     */
90
    public $elementRouteGlobals = [];
91
92
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
93
     * @var array A key-value array of additional global variables to parse for completions
94
     */
95
    public $additionalGlobals = [];
96
97
    // Public Methods
98
    // =========================================================================
99
100
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
101
     * @inerhitDoc
102
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
103
    public function init(): void
104
    {
105
        if (empty($this->twigGlobals)) {
106
            $this->twigGlobals = Craft::$app->view->getTwig()->getGlobals();
107
        }
108
        if (empty($this->elementRouteGlobals)) {
109
            $this->elementRouteGlobals = $this->getElementRouteGlobals();
110
        }
111
    }
112
113
    /**
114
     * Core function that generates the autocomplete array
115
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
116
    public function generateCompleteItems(): void
117
    {
118
        // Gather up all of the globals to parse
119
        $globals = array_merge(
120
            $this->twigGlobals,
121
            $this->elementRouteGlobals,
122
            $this->additionalGlobals,
123
            $this->overrideValues(),
124
        );
125
        foreach ($globals as $key => $value) {
126
            if (!in_array($key, self::EXCLUDED_PROPERTY_NAMES, true)) {
127
                $type = gettype($value);
128
                switch ($type) {
129
                    case 'object':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
130
                        $this->parseObject($key, $value, 0);
131
                        break;
132
133
                    case 'array':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
134
                    case 'boolean':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
135
                    case 'double':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
136
                    case 'integer':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
137
                    case 'string':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
138
                        $kind = CompleteItemKind::VariableKind;
139
                        $path = $key;
140
                        $normalizedKey = preg_replace("/[^A-Za-z]/", '', $key);
141
                        if (ctype_upper($normalizedKey)) {
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
142
                            $kind = CompleteItemKind::ConstantKind;
143
                        }
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 20 spaces, found 24
Loading history...
144
                        $this->addCompleteItem(new CompleteItem([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
145
                            'detail' => $value,
146
                            'kind' => $kind,
147
                            'label' => $key,
148
                            'insertText' => $key,
149
                        ]), $path);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
150
                        break;
151
                }
152
            }
153
        }
154
    }
155
156
    // Protected Methods
157
    // =========================================================================
158
159
    /**
160
     * Parse the object passed in, including any properties or methods
161
     *
162
     * @param string $name
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
163
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
164
     * @param int $recursionDepth
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
165
     * @param string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
166
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
167
    protected function parseObject(string $name, $object, int $recursionDepth, string $path = ''): void
168
    {
169
        // Only recurse `RECURSION_DEPTH_LIMIT` deep
170
        if ($recursionDepth > self::RECURSION_DEPTH_LIMIT) {
171
            return;
172
        }
173
        $recursionDepth++;
174
        // Create the docblock factory
175
        $factory = DocBlockFactory::createInstance();
176
177
        $path = trim(implode('.', [$path, $name]), '.');
178
        // The class itself
179
        $this->getClassCompletion($object, $factory, $name, $path);
180
        // ServiceLocator Components
181
        $this->getComponentCompletion($object, $recursionDepth, $path);
182
        // Class properties
183
        $this->getPropertyCompletion($object, $factory, $recursionDepth, $path);
184
        // Class methods
185
        $this->getMethodCompletion($object, $factory, $path);
186
        // Behavior properties
187
        $this->getBehaviorCompletion($object, $factory, $recursionDepth, $path);
188
    }
189
190
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
191
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
192
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
193
     * @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...
194
     * @param $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
195
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
196
    protected function getClassCompletion($object, DocBlockFactory $factory, string $name, $path): void
197
    {
198
        try {
199
            $reflectionClass = new ReflectionClass($object);
200
        } catch (ReflectionException $e) {
201
            return;
202
        }
203
        // Information on the class itself
204
        $className = $reflectionClass->getName();
205
        $docs = $reflectionClass->getDocComment();
206
        if ($docs) {
207
            $docblock = $factory->create($docs);
208
            if ($docblock) {
0 ignored issues
show
introduced by
$docblock is of type phpDocumentor\Reflection\DocBlock, thus it always evaluated to true.
Loading history...
209
                $summary = $docblock->getSummary();
210
                if (!empty($summary)) {
211
                    $docs = $summary;
212
                }
213
                $description = $docblock->getDescription()->render();
214
                if (!empty($description)) {
215
                    $docs = $description;
216
                }
217
            }
218
        }
219
        $this->addCompleteItem(new CompleteItem([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
220
            'detail' => $className,
221
            'documentation' => $docs,
222
            'kind' => CompleteItemKind::ClassKind,
223
            'label' => $name,
224
            'insertText' => $name,
225
        ]), $path);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
226
    }
227
228
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
229
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
230
     * @param $recursionDepth
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
231
     * @param $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
232
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
233
    protected function getComponentCompletion($object, $recursionDepth, $path): void
234
    {
235
        if ($object instanceof ServiceLocator) {
236
            foreach ($object->getComponents() as $key => $value) {
237
                $componentObject = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $componentObject is dead and can be removed.
Loading history...
238
                try {
239
                    $componentObject = $object->get($key);
240
                } catch (InvalidConfigException $e) {
241
                    // That's okay
242
                }
243
                if ($componentObject) {
244
                    $this->parseObject($key, $componentObject, $recursionDepth, $path);
245
                }
246
            }
247
        }
248
    }
249
250
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
251
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
252
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
253
     * @param $recursionDepth
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
254
     * @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...
255
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
256
    protected function getPropertyCompletion($object, DocBlockFactory $factory, $recursionDepth, string $path): void
257
    {
258
        try {
259
            $reflectionClass = new ReflectionClass($object);
260
        } catch (ReflectionException $e) {
261
            return;
262
        }
263
        $reflectionProperties = $reflectionClass->getProperties();
264
        $customField = false;
265
        if ($object instanceof Behavior) {
266
            $customField = true;
267
        }
268
        $sortPrefix = $customField ? '~' : '~~';
269
        foreach ($reflectionProperties as $reflectionProperty) {
270
            $propertyName = $reflectionProperty->getName();
271
            // Exclude some properties
272
            $propertyAllowed = true;
273
            foreach (self::EXCLUDED_PROPERTY_REGEXES as $excludePattern) {
274
                $pattern = '`' . $excludePattern . '`i';
275
                if (preg_match($pattern, $propertyName) === 1) {
276
                    $propertyAllowed = false;
277
                }
278
            }
279
            if (in_array($propertyName, self::EXCLUDED_PROPERTY_NAMES, true)) {
280
                $propertyAllowed = false;
281
            }
282
            if ($customField && in_array($propertyName, self::EXCLUDED_BEHAVIOR_NAMES, true)) {
283
                $propertyAllowed = false;
284
            }
285
            // Process the property
286
            if ($propertyAllowed && $reflectionProperty->isPublic()) {
287
                $detail = "Property";
288
                $docblock = null;
289
                $docs = $reflectionProperty->getDocComment();
290
                if ($docs) {
291
                    $docblock = $factory->create($docs);
292
                    $docs = '';
293
                    if ($docblock) {
294
                        $summary = $docblock->getSummary();
295
                        if (!empty($summary)) {
296
                            $docs = $summary;
297
                        }
298
                        $description = $docblock->getDescription()->render();
299
                        if (!empty($description)) {
300
                            $docs = $description;
301
                        }
302
                    }
303
                }
304
                // Figure out the type
305
                if ($docblock) {
306
                    $tag = $docblock->getTagsByName('var');
307
                    if ($tag && isset($tag[0])) {
308
                        $detail = $tag[0];
309
                    }
310
                }
311
                if ($detail === "Property") {
312
                    if (preg_match('/@var\s+([^\s]+)/', $docs, $matches)) {
313
                        list(, $type) = $matches;
314
                        $detail = $type;
315
                    } else {
316
                        $detail = "Property";
317
                    }
318
                }
319
                if ($detail === "Property") {
320
                    if ((PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 4) || (PHP_MAJOR_VERSION >= 8)) {
321
                        if ($reflectionProperty->hasType()) {
322
                            $reflectionType = $reflectionProperty->getType();
323
                            if ($reflectionType instanceof ReflectionNamedType) {
324
                                $type = $reflectionType->getName();
325
                                $detail = $type;
326
                            }
327
                        }
328
                        if (PHP_MAJOR_VERSION >= 8) {
329
                            if ($reflectionProperty->hasDefaultValue()) {
330
                                $value = $reflectionProperty->getDefaultValue();
331
                                if (is_array($value)) {
332
                                    $value = json_encode($value);
333
                                }
334
                                if (!empty($value)) {
335
                                    $detail = "$value";
336
                                }
337
                            }
338
                        }
339
                    }
340
                }
341
                $thisPath = trim(implode('.', [$path, $propertyName]), '.');
342
                $label = $propertyName;
343
                $this->addCompleteItem(new CompleteItem([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
344
                    'detail' => $detail,
345
                    'documentation' => $docs,
346
                    'kind' => $customField ? CompleteItemKind::FieldKind : CompleteItemKind::PropertyKind,
347
                    'label' => $label,
348
                    'insertText' => $label,
349
                    'sortText' => $sortPrefix . $label,
350
                ]), $thisPath);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
351
                // Recurse through if this is an object
352
                if (isset($object->$propertyName) && is_object($object->$propertyName)) {
353
                    if (!$customField && !in_array($propertyName, self::EXCLUDED_PROPERTY_NAMES, true)) {
354
                        $this->parseObject($propertyName, $object->$propertyName, $recursionDepth, $path);
355
                    }
356
                }
357
            }
358
        }
359
    }
360
361
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
362
     * @param $object
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
363
     * @param DocBlockFactory $factory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
364
     * @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...
365
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
366
    protected function getMethodCompletion($object, DocBlockFactory $factory, string $path): void
367
    {
368
        try {
369
            $reflectionClass = new ReflectionClass($object);
370
        } catch (ReflectionException $e) {
371
            return;
372
        }
373
        $reflectionMethods = $reflectionClass->getMethods();
374
        foreach ($reflectionMethods as $reflectionMethod) {
375
            $methodName = $reflectionMethod->getName();
376
            // Exclude some properties
377
            $methodAllowed = true;
378
            foreach (self::EXCLUDED_METHOD_REGEXES as $excludePattern) {
379
                $pattern = '`' . $excludePattern . '`i';
380
                if (preg_match($pattern, $methodName) === 1) {
381
                    $methodAllowed = false;
382
                }
383
            }
384
            // Process the method
385
            if ($methodAllowed && $reflectionMethod->isPublic()) {
386
                $docblock = null;
387
                $docs = $reflectionMethod->getDocComment();
388
                if ($docs) {
389
                    $docblock = $factory->create($docs);
390
                    if ($docblock) {
391
                        $summary = $docblock->getSummary();
392
                        if (!empty($summary)) {
393
                            $docs = $summary;
394
                        }
395
                        $description = $docblock->getDescription()->render();
396
                        if (!empty($description)) {
397
                            $docs = $description;
398
                        }
399
                    }
400
                }
401
                $detail = $methodName . '(';
402
                $params = $reflectionMethod->getParameters();
403
                $paramList = [];
404
                foreach ($params as $param) {
405
                    if ($param->hasType()) {
406
                        $reflectionType = $param->getType();
407
                        if ($reflectionType instanceof ReflectionUnionType) {
408
                            $unionTypes = $reflectionType->getTypes();
409
                            $typeName = '';
410
                            foreach ($unionTypes as $unionType) {
411
                                $typeName .= '|' . $unionType->getName();
412
                            }
413
                            $typeName = trim($typeName, '|');
414
                            $paramList[] = $typeName . ': ' . '$' . $param->getName();
415
                        } else {
416
                            $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

416
                            $paramList[] = $param->getType()->/** @scrutinizer ignore-call */ getName() . ': ' . '$' . $param->getName();
Loading history...
417
                        }
418
                    } else {
419
                        $paramList[] = '$' . $param->getName();
420
                    }
421
                }
422
                $detail .= implode(', ', $paramList) . ')';
423
                $thisPath = trim(implode('.', [$path, $methodName]), '.');
424
                $label = $methodName . '()';
425
                $docsPreamble = '';
426
                // Figure out the type
427
                if ($docblock) {
428
                    $tags = $docblock->getTagsByName('param');
429
                    if ($tags) {
430
                        $docsPreamble = "Parameters:\n\n";
431
                        foreach ($tags as $tag) {
432
                            $docsPreamble .= $tag . "\n";
433
                        }
434
                        $docsPreamble .= "\n";
435
                    }
436
                }
437
                $this->addCompleteItem(new CompleteItem([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
438
                    'detail' => $detail,
439
                    'documentation' => $docsPreamble . $docs,
440
                    'kind' => CompleteItemKind::MethodKind,
441
                    'label' => $label,
442
                    'insertText' => $label,
443
                    'sortText' => '~~~' . $label,
444
                ]), $thisPath);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
445
            }
446
        }
447
    }
448
449
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
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 $recursionDepth
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
453
     * @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...
454
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
455
    protected function getBehaviorCompletion($object, DocBlockFactory $factory, $recursionDepth, string $path): void
456
    {
457
        if ($object instanceof Element) {
458
            $behaviorClass = $object->getBehavior('customFields');
459
            if ($behaviorClass) {
460
                $this->getPropertyCompletion($behaviorClass, $factory, $recursionDepth, $path);
461
            }
462
        }
463
    }
464
465
    // Private Methods
466
    // =========================================================================
467
468
    /**
469
     * Add in the element types that could be injected as route variables
470
     *
471
     * @return array
472
     */
473
    private function getElementRouteGlobals(): array
0 ignored issues
show
Coding Style introduced by
Private method name "CraftApiAutocomplete::getElementRouteGlobals" must be prefixed with an underscore
Loading history...
474
    {
475
        $routeVariables = [];
476
        $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

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