Passed
Push — master ( db49f9...b5d0c3 )
by Alexander
01:42
created

ClassDefinition   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 46.88%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
dl 0
loc 75
ccs 15
cts 32
cp 0.4688
rs 10
c 1
b 0
f 0
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getType() 0 3 1
A resolveUnionType() 0 23 5
A resolve() 0 19 5
A isUnionType() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Factory\Definitions;
6
7
use Psr\Container\ContainerInterface;
8
use Yiisoft\Factory\Exceptions\InvalidConfigException;
9
10
/**
11
 * Reference points to a class name in the container
12
 */
13
class ClassDefinition implements DefinitionInterface
14
{
15
    private string $class;
16
    private bool $optional;
17
18
    /**
19
     * Constructor.
20
     * @param string $class the class name
21
     * @param bool $optional if null should be returned instead of throwing an exception
22
     */
23 7
    public function __construct(string $class, bool $optional)
24
    {
25 7
        $this->class = $class;
26 7
        $this->optional = $optional;
27 7
    }
28
29
    public function getType(): string
30
    {
31
        return $this->class;
32
    }
33
34 9
    public function resolve(ContainerInterface $container)
35
    {
36 9
        if ($this->isUnionType()) {
37
            return $this->resolveUnionType($container);
38
        }
39
40
        try {
41 9
            $result = $container->get($this->class);
42 5
        } catch (\Throwable $t) {
43 5
            if ($this->optional) {
44 4
                return null;
45
            }
46 3
            throw $t;
47
        }
48
49 4
        if (!$result instanceof $this->class) {
50
            throw new InvalidConfigException('Container returned incorrect type for service ' . $this->class);
51
        }
52 4
        return $result;
53
    }
54
55
    /**
56
     * @param ContainerInterface $container
57
     * @return mixed
58
     * @throws \Throwable
59
     */
60
    private function resolveUnionType(ContainerInterface $container)
61
    {
62
        $types = explode('|', $this->class);
63
64
        $error = null;
65
66
        foreach ($types as $type) {
67
            try {
68
                $result = $container->get($type);
69
                if (!$result instanceof $type) {
70
                    throw new InvalidConfigException('Container returned incorrect type for service ' . $type);
71
                }
72
                return $result;
73
            } catch (\Throwable $t) {
74
                $error = $t;
75
            }
76
        }
77
78
        if ($this->optional) {
79
            return null;
80
        }
81
82
        throw $error;
83
    }
84
85 9
    private function isUnionType(): bool
86
    {
87 9
        return strpos($this->class, '|') !== false;
88
    }
89
}
90