Passed
Push — master ( d64c31...f94732 )
by Oleg
03:59
created

Injector::buildParams()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
rs 8.8571
cc 5
eloc 8
nc 4
nop 1
1
<?php /** MicroInjector */
2
3
namespace Micro\Base;
4
5
6
/**
7
 * Class Injector
8
 *
9
 * @author Oleg Lunegov <[email protected]>
10
 * @link https://github.com/linpax/microphp-framework
11
 * @copyright Copyright &copy; 2013 Oleg Lunegov
12
 * @license /LICENSE
13
 * @package Micro
14
 * @subpackage Base
15
 * @version 1.0
16
 * @since 1.0
17
 */
18
class Injector
19
{
20
    /** @var array $CONFIG Config data for components */
21
    private static $CONFIG;
22
23
24
    /**
25
     * Injector constructor.
26
     *
27
     * @access public
28
     * @param array $config
29
     * @result void
30
     */
31
    public function __construct(array $config)
32
    {
33
        self::$CONFIG = $config;
34
    }
35
36
    /**
37
     * Build object with injector
38
     *
39
     * class LogInject extends Injector {
40
     *  public function build() {
41
     *   return $this->get('logger');
42
     *  }
43
     * }
44
     * $log = (new LogInject())->build();
45
     *
46
     * @access private
47
     * @param string $name
48
     * @return bool
49
     */
50
    private function get($name)
51
    {
52
        if (!empty(self::$CONFIG[$name])) {
53
            return $this->loadComponent(self::$CONFIG[$name]);
54
        }
55
56
        return false;
57
    }
58
59
    /**
60
     * Load component
61
     *
62
     * @access public
63
     *
64
     * @param array $options component configs
65
     *
66
     * @return bool
67
     */
68
    private function loadComponent($options)
69
    {
70
        if (empty($options['class']) || !class_exists($options['class'])) {
71
            return false;
72
        }
73
74
        $className = $options['class'];
75
        $object = null;
0 ignored issues
show
Unused Code introduced by
$object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
76
77
        $options['arguments'] = !empty($options['arguments']) ? $this->buildParams($options['arguments']) : null;
78
        $options['property'] = !empty($options['property']) ? $this->buildParams($options['property']) : null;
79
        $options['calls'] = !empty($options['calls']) ? $this->buildCalls($options['calls']) : null;
80
81
        $object = $this->makeObject($className, $options['arguments']);
82
        if (!$object) {
83
            return false;
84
        }
85
86
        if (!empty($options['property'])) { // load properties
87
            foreach ($options['property'] as $property => $value) {
88
                if (property_exists($object, $property)) {
89
                    $object->$property = $value;
90
                }
91
            }
92
        }
93
94
        if (!empty($options['calls'])) { // run methods
95
            foreach ($options['calls'] as $method => $arguments) {
96
                if (method_exists($object, $method)) {
97
                    $reflectionMethod = new \ReflectionMethod($className, $method);
98
                    if ($reflectionMethod->getNumberOfParameters() === 0) {
99
                        $object->$method();
100
                    } else {
101
                        call_user_func_array([$object, $method], $arguments);
102
                    }
103
                }
104
            }
105
        }
106
107
        return true;
108
    }
109
110
    /**
111
     * Build params from array
112
     *
113
     * @access private
114
     * @param array $params
115
     * @return array
116
     */
117
    private function buildParams(array $params)
118
    {
119
        /** @noinspection AlterInForeachInspection */
120
        foreach ($params AS $key => &$val) { // IoC Constructor
121
            if (is_string($params[$key]) && (0 === strpos($val, '@'))) {
122
                if ($val === '@this') {
123
                    $val = $this;
124
                } else {
125
                    $val = $this->get(substr($val, 1));
126
                }
127
            }
128
        }
129
130
        return $params;
131
    }
132
133
    /**
134
     * Build calls arguments
135
     *
136
     * @access private
137
     * @param array $params
138
     * @return array
139
     */
140 View Code Duplication
    private function buildCalls(array $params)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
    {
142
        $callers = [];
143
144
        if (!is_array($params[0])) {
145
            $params = [
146
                $params
147
            ];
148
        }
149
150
        foreach ($params as $arguments) {
151
            if (is_string($arguments[0])) {
152
                if (!empty($arguments[1]) && is_array($arguments[1])) {
153
                    $callers[$arguments[0]] = $this->buildParams($arguments[1]);
154
                } else {
155
                    $callers[$arguments[0]] = null;
156
                }
157
            }
158
        }
159
160
        return $callers;
161
    }
162
163
    /**
164
     * Make object with arguments
165
     *
166
     * @access private
167
     *
168
     * @param string $className
169
     * @param array $arguments
170
     *
171
     * @return mixed
172
     */
173 View Code Duplication
    private function makeObject($className, array $arguments = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
174
    {
175
        try {
176
            $reflection = new \ReflectionClass($className);
177
            $reflectionMethod = new \ReflectionMethod($className, '__construct');
178
179
            if ($reflectionMethod->getNumberOfParameters() === 0) {
180
                return new $className;
181
            } else {
182
                return $reflection->newInstanceArgs($arguments);
183
            }
184
        } catch (Exception $e) {
185
            return false;
186
        }
187
    }
188
}