Passed
Push — refactoring ( 68edd5...fe1438 )
by Sergei
02:32
created

DefinitionParser::checkMetaKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Di;
6
7
use Yiisoft\Factory\Definition\ArrayDefinition;
8
use Yiisoft\Factory\Exception\InvalidConfigException;
9
10
use function in_array;
11
use function is_array;
12
use function is_string;
13
14
/**
15
 * @internal Split metadata and definition
16
 *
17
 * Support configuration:
18
 *
19
 * 1) With a dedicated definition:
20
 *
21
 * ```php
22
 * Engine::class => [
23
 *     'definition' => [
24
 *         '__class' => BigEngine::class,
25
 *         'setNumber()' => [42],
26
 *     ],
27
 *     'tags' => ['a', 'b'],
28
 *     'reset' => function () {
29
 *         $this->number = 42;
30
 *      },
31
 * ]
32
 * ```
33
 *
34
 * 2) Mixed in array definition:
35
 *
36
 * ```php
37
 * Engine::class => [
38
 *     '__class' => BigEngine::class,
39
 *     'setNumber()' => [42],
40
 *     'tags' => ['a', 'b'],
41
 *     'reset' => function () {
42
 *         $this->number = 42;
43
 *      },
44
 * ]
45
 * ```
46
 */
47
final class DefinitionParser
48
{
49
    private const DEFINITION_META = 'definition';
50
51
    private array $allowedMeta;
52
53 99
    public function __construct(array $allowedMeta)
54
    {
55 99
        $this->allowedMeta = $allowedMeta;
56 99
    }
57
58
    /**
59
     * @param mixed $definition
60
     *
61
     * @throws InvalidConfigException
62
     */
63 99
    public function parse($definition): array
64
    {
65 99
        if (!is_array($definition)) {
66 93
            return [$definition, []];
67
        }
68
69
        // Dedicated definition
70 41
        if (isset($definition[self::DEFINITION_META])) {
71 3
            $newDefinition = $definition[self::DEFINITION_META];
72 3
            unset($definition[self::DEFINITION_META]);
73 3
            foreach ($definition as $key => $_value) {
74 3
                $this->checkMetaKey($key);
75
            }
76 3
            return [$newDefinition, $definition];
77
        }
78
79 38
        $meta = [];
80 38
        foreach ($definition as $key => $value) {
81
            // It is not array definition
82 38
            if (!is_string($key)) {
83 3
                break;
84
            }
85
86
            // Array definition keys
87
            if (
88 35
                $key === ArrayDefinition::CLASS_NAME ||
89 32
                $key === ArrayDefinition::CONSTRUCTOR ||
90 24
                substr($key, -2) === '()' ||
91 35
                strncmp($key, '$', 1) === 0
92
            ) {
93 35
                continue;
94
            }
95
96 16
            $this->checkMetaKey($key);
97
98 14
            $meta[$key] = $value;
99 14
            unset($definition[$key]);
100
        }
101
102 35
        return [$definition, $meta];
103
    }
104
105
    /**
106
     * @throws InvalidConfigException
107
     */
108 19
    private function checkMetaKey(string $key): void
109
    {
110 19
        if (!in_array($key, $this->allowedMeta, true)) {
111 3
            throw new InvalidConfigException(
112 3
                sprintf(
113 3
                    'Invalid definition: metadata "%s" is not allowed. Did you mean "%s()" or "$%s"?',
114
                    $key,
115
                    $key,
116
                    $key,
117
                )
118
            );
119
        }
120 17
    }
121
}
122