AttributesInjection   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 27
c 3
b 0
f 0
dl 0
loc 67
rs 10
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getInjection() 0 18 4
A __construct() 0 4 1
A inject() 0 23 6
1
<?php
2
declare(strict_types=1);
3
4
namespace Habemus\Autowiring\Attributes;
5
6
use Habemus\Autowiring\Reflector;
7
use Habemus\Exception\ContainerException;
8
use Habemus\Exception\InjectionException;
9
use Psr\Container\ContainerInterface;
10
use ReflectionClass;
11
use ReflectionParameter;
12
use ReflectionProperty;
13
14
class AttributesInjection
15
{
16
    /**
17
     * @var ContainerInterface
18
     */
19
    protected $container;
20
21
    /**
22
     * @var Reflector
23
     */
24
    protected $reflector;
25
26
    public function __construct(ContainerInterface $container, Reflector $reflector)
27
    {
28
        $this->reflector = $reflector;
29
        $this->container = $container;
30
    }
31
32
    public function inject($object)
33
    {
34
        if (!is_object($object)) {
35
            throw InjectionException::notAnObject($object);
36
        }
37
38
        $reflectionClass = new ReflectionClass($object);
39
        foreach ($reflectionClass->getProperties() as $property) {
40
            $injection = $this->getInjection($property);
41
            if (empty($injection)) {
42
                continue;
43
            }
44
45
            if (!$property->isPublic()) {
46
                $property->setAccessible(true);
47
            }
48
49
            if (!$this->container->has($injection)) {
50
                throw InjectionException::unresolvablePropertyInjection($property, $object);
51
            }
52
53
            $value = $this->container->get($injection);
54
            $property->setValue($object, $value);
55
        }
56
    }
57
58
    /**
59
     * @param ReflectionProperty|ReflectionParameter $subject
60
     * @return string|null
61
     * @throws InjectionException|ContainerException
62
     */
63
    public function getInjection($subject): ?string
64
    {
65
        /** @var Inject|null $inject */
66
        $inject = $this->reflector->getFirstAttribute($subject, Inject::class);
67
        if (! $inject instanceof Inject) {
68
            return null;
69
        }
70
71
        if (!empty($inject->getId())) {
72
            return $inject->getId();
73
        }
74
75
        $typeHint = $this->reflector->getTypeHint($subject, false);
76
        if (empty($typeHint)) {
77
            throw InjectionException::invalidInjection($subject);
78
        }
79
80
        return $typeHint;
81
    }
82
}
83