AutoDetection   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 25
dl 0
loc 81
rs 10
c 2
b 0
f 0
wmc 16

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A detect() 0 23 6
A isAutowire() 0 3 4
A isArrayDefinition() 0 14 3
A isClosure() 0 3 2
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