Instantiator::injectProperties()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 0
loc 17
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 7
nc 3
nop 2
crap 3
1
<?php
2
namespace mxdiModule\Service;
3
4
use mxdiModule\Annotation\Inject;
5
use Zend\ServiceManager\ServiceLocatorInterface;
6
7
class Instantiator implements InstantiatorInterface
8
{
9
    /** @var ServiceLocatorInterface */
10
    protected $serviceLocator;
11
12
    /**
13
     * Create object.
14
     *
15
     * @param ServiceLocatorInterface $sm
16
     * @param ChangeSet $changeSet
17
     * @return object
18
     */
19 6
    public function create(ServiceLocatorInterface $sm, ChangeSet $changeSet)
20
    {
21 6
        $this->serviceLocator = $sm;
22
23 6
        $object = $this->createObject($changeSet);
24 6
        $this->injectMethods($object, $changeSet);
25 6
        $this->injectProperties($object, $changeSet);
26
27 6
        return $object;
28
    }
29
30
    /**
31
     * @param object $object
32
     * @param ChangeSet $changeSet
33
     */
34 6
    protected function injectProperties($object, ChangeSet $changeSet)
35
    {
36
        /**
37
         * @var string $propertyName
38
         * @var Inject $injection
39
         */
40 6
        foreach ($changeSet->getPropertiesInjections() as $propertyName => $injection) {
41 2
            $value = $injection->getValue($this->serviceLocator);
42
43 2
            if ($changeSet->isPropertyPublic($propertyName)) {
44 1
                $object->$propertyName = $value;
45 1
                continue;
46
            }
47
48 1
            $this->setPropertyValue($changeSet->getFqcn(), $object, $propertyName, $value);
49 6
        }
50 6
    }
51
52
    /**
53
     * @param object $object
54
     * @param ChangeSet $changeSet
55
     */
56 6
    protected function injectMethods($object, ChangeSet $changeSet)
57
    {
58
        /**
59
         * @var string $propertyName
60
         * @var Inject $injection
61
         * @var array $value
62
         */
63 6
        foreach ($changeSet->getMethodsInjections() as $methodName => $injection) {
64 2
            $value = $injection->getValue($this->serviceLocator);
65
66 2
            if ($changeSet->isMethodPublic($methodName)) {
67 1
                call_user_func_array([$object, $methodName], (array)$value);
68 1
                continue;
69
            }
70
71 1
            $this->invokeMethod($changeSet->getFqcn(), $object, $methodName, $value);
72 6
        }
73 6
    }
74
75
    /**
76
     * @param ChangeSet $changeSet
77
     * @return object
78
     */
79 6
    protected function createObject(ChangeSet $changeSet)
80
    {
81 6
        $fqcn = $changeSet->getFqcn();
82
83 6
        if ($changeSet->hasSimpleConstructor()) {
84 5
            return new $fqcn;
85
        }
86
87 1
        $reflection = new \ReflectionClass($fqcn);
88 1
        return $reflection->newInstanceArgs(
89 1
            (array)$changeSet->getConstructorInjections()->getValue($this->serviceLocator)
90 1
        );
91
    }
92
93
    /**
94
     * Set property value with reflection.
95
     *
96
     * @param string $fqcn
97
     * @param object $object
98
     * @param string $property
99
     * @param mixed $value
100
     */
101 1
    protected function setPropertyValue($fqcn, $object, $property, $value)
102
    {
103 1
        $reflection = new \ReflectionProperty($fqcn, $property);
104 1
        $reflection->setAccessible(true);
105 1
        $reflection->setValue($object, $value);
106 1
        $reflection->setAccessible(false);
107 1
    }
108
109
    /**
110
     * Call method with reflection.
111
     *
112
     * @param string $fqcn
113
     * @param object $object
114
     * @param string $method
115
     * @param mixed $value
116
     */
117 1
    protected function invokeMethod($fqcn, $object, $method, $value)
118
    {
119 1
        $reflection = new \ReflectionMethod($fqcn, $method);
120 1
        $reflection->setAccessible(true);
121 1
        $reflection->invokeArgs($object, $value);
122 1
        $reflection->setAccessible(false);
123 1
    }
124
}
125