AutoDetection::isAutowire()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 1
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 3
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Habemus\Definition;
5
6
use Closure;
7
use Habemus\Autowiring\ClassResolver;
8
use Habemus\Container;
9
use Habemus\Definition\Build\ArrayDefinition;
10
use Habemus\Definition\Build\ReferenceDefinition;
11
use Habemus\Definition\Build\ClassDefinition;
12
use Habemus\Definition\Build\FnDefinition;
13
use Habemus\Definition\Build\RawDefinition;
14
15
class AutoDetection implements DefinitionDetection
16
{
17
    /**
18
     * @var Container
19
     */
20
    protected $container;
21
22
    /**
23
     * @var ClassResolver
24
     */
25
    protected $classResolver;
26
27
    public function __construct(Container $container, ClassResolver $classResolver)
28
    {
29
        $this->container = $container;
30
        $this->classResolver = $classResolver;
31
    }
32
33
    public function detect($value): Definition
34
    {
35
        if ($value instanceof Definition) {
36
            return $value;
37
        }
38
39
        if (is_null($value)) {
40
            return new RawDefinition($value);
41
        }
42
43
        if ($this->isClosure($value)) {
44
            return new FnDefinition($value);
45
        }
46
47
        if ($this->isAutowire($value)) {
48
            return (new ClassDefinition($value))->setClassResolver($this->classResolver);
49
        }
50
51
        if ($this->isArrayDefinition($value)) {
52
            return new ArrayDefinition($value, true);
53
        }
54
55
        return new RawDefinition($value);
56
    }
57
58
    /**
59
     * Accepts anonymous functions only.
60
     * Objects that implement the "__invoke" method are not accepted as a closure definition
61
     * @param mixed $value
62
     * @return bool
63
     */
64
    protected function isClosure($value): bool
65
    {
66
        return is_object($value) && get_class($value) === Closure::class;
67
    }
68
69
    /**
70
     * @param mixed $value
71
     * @return bool
72
     */
73
    protected function isAutowire($value): bool
74
    {
75
        return $this->container->autowireEnabled() && !is_object($value) && is_string($value) && class_exists($value);
76
    }
77
78
    /**
79
     * @param mixed $value
80
     * @return bool
81
     */
82
    protected function isArrayDefinition($value): bool
83
    {
84
        if (!is_array($value)) {
85
            return false;
86
        }
87
88
        $hasDefinitionInside = false;
89
        array_walk_recursive($value, function ($item) use (&$hasDefinitionInside) {
90
            if ($item instanceof ReferenceDefinition) {
91
                $hasDefinitionInside = true;
92
            }
93
        });
94
95
        return $hasDefinitionInside;
96
    }
97
}
98