Passed
Pull Request — master (#78)
by Dmitriy
07:47
created

Normalizer::normalize()   B

Complexity

Conditions 11
Paths 9

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 13.8217

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 20
nc 9
nop 3
dl 0
loc 38
ccs 15
cts 21
cp 0.7143
crap 13.8217
rs 7.3166
c 2
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Factory\Definitions;
6
7
use Yiisoft\Factory\Exceptions\InvalidConfigException;
8
9
use function array_key_exists;
10
use function is_array;
11
use function is_callable;
12
use function is_object;
13
use function is_string;
14
15
/**
16
 * Class Definition represents a definition in a container
17
 */
18
class Normalizer
19
{
20
    public const TAGS = '__tags';
21
    public const DEFINITION = '__definition';
22
23
    /**
24
     * Definition may be defined multiple ways.
25
     * Interface name as string:
26
     *
27
     * ```php
28
     * $container->set('interface_name', EngineInterface::class);
29
     * ```
30
     *
31
     * A closure:
32
     *
33
     * ```php
34
     * $container->set('closure', function($container) {
35
     *     return new MyClass($container->get('db'));
36
     * });
37
     * ```
38
     *
39
     * A callable array:
40
     *
41
     * ```php
42
     * $container->set('static_call', [MyClass::class, 'create']);
43
     * ```
44
     *
45
     * A definition array:
46
     *
47
     * ```php
48
     * $container->set('full_definition', [
49
     *     '__class' => EngineMarkOne::class,
50
     *     '__construct()' => [42],
51
     *     'argName' => 'value',
52
     *     'setX()' => [42],
53
     * ]);
54
     * ```
55
     *
56
     * @param mixed $definition
57
     *
58
     * @throws InvalidConfigException
59
     */
60 12
    public static function normalize($definition, string $id = null, array $params = []): DefinitionInterface
61
    {
62 12
        if ($definition instanceof DefinitionInterface) {
63
            return $definition;
64
        }
65
66 12
        if (is_string($definition)) {
67 8
            if (empty($definition)) {
68
                throw new InvalidConfigException('Invalid definition: empty string.');
69
            }
70 8
            if ($id === $definition || (!empty($params) && class_exists($definition))) {
71
                /** @psalm-var class-string $definition */
72 1
                return new ArrayDefinition([
73 1
                    ArrayDefinition::CLASS_NAME => $definition,
74 1
                    ArrayDefinition::CONSTRUCTOR => $params,
75
                ]);
76
            }
77 7
            return Reference::to($definition);
78
        }
79
80 7
        if (is_callable($definition, true)) {
81 3
            return new CallableDefinition($definition);
82
        }
83
84 4
        if (is_array($definition)) {
85 4
            $config = $definition;
86 4
            if (!array_key_exists(ArrayDefinition::CLASS_NAME, $config)) {
87
                $config[ArrayDefinition::CLASS_NAME] = $id;
88
            }
89
            /** @psalm-suppress ArgumentTypeCoercion */
90 4
            return new ArrayDefinition($config);
91
        }
92
93
        if (is_object($definition)) {
94
            return new ValueDefinition($definition);
95
        }
96
97
        throw new InvalidConfigException('Invalid definition:' . var_export($definition, true));
98
    }
99
100
    /**
101
     * @param mixed $definition
102
     */
103
    public static function parse($definition): array
104
    {
105
        if (!is_array($definition)) {
106
            return [$definition, []];
107
        }
108
        $tags = (array)($definition[self::TAGS] ?? []);
109
        unset($definition[self::TAGS]);
110
111
        return [$definition[self::DEFINITION] ?? $definition, $tags];
112
    }
113
114
    /**
115
     * Validates defintion for corectness.
116
     *
117
     * @param mixed $definition {@see normalize()}
118
     *
119
     * @throws InvalidConfigException
120
     */
121
    public static function validate($definition, bool $throw = true): bool
122
    {
123
        if ($definition instanceof DefinitionInterface) {
124
            return true;
125
        }
126
127
        if (is_string($definition) && !empty($definition)) {
128
            return true;
129
        }
130
131
        if (is_callable($definition)) {
132
            return true;
133
        }
134
135
        if (is_array($definition)) {
136
            return true;
137
        }
138
139
        if (is_object($definition)) {
140
            return true;
141
        }
142
143
        if ($throw) {
144
            throw new InvalidConfigException('Invalid definition:' . var_export($definition, true));
145
        }
146
147
        return false;
148
    }
149
}
150