GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( e0bc31...383204 )
by Hong
03:51
created

FactoryTrait   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 247
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 17
Bugs 0 Features 1
Metric Value
wmc 32
c 17
b 0
f 1
lcom 1
cbo 0
dl 0
loc 247
rs 9.6

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefinition() 0 20 4
A constructObject() 0 20 2
A matchArguments() 0 16 4
A isTypeMatched() 0 10 3
A isRequiredClass() 0 11 3
A getObjectByClass() 0 11 3
A getCallableParameters() 0 19 3
A isInvocable() 0 4 2
A mergeMethods() 0 14 4
A executeCommonBatch() 0 18 4
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Di
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Di\Traits;
16
17
use Phossa2\Di\Container;
18
use Phossa2\Di\Exception\LogicException;
19
use Phossa2\Di\Message\Message;
20
21
/**
22
 * FactoryTrait
23
 *
24
 * Create service instance here
25
 *
26
 * @package Phossa2\Di
27
 * @author  Hong Zhang <[email protected]>
28
 * @version 2.0.0
29
 * @since   2.0.0 added
30
 */
31
trait FactoryTrait
32
{
33
    /**
34
     * @var    Container
35
     * @access protected
36
     */
37
    protected $master;
38
39
    /**
40
     * Get service definition (and fix it)
41
     *
42
     * @param  string $rawId
43
     * @param  array $args
44
     * @return array
45
     * @access protected
46
     */
47
    protected function getDefinition(
48
        /*# string */ $rawId,
49
        array $args
50
    )/*# : array */ {
51
        // get the definition
52
        $def = $this->master->getResolver()->getService($rawId);
53
54
        // fix class
55
        if (!is_array($def) || !isset($def['class'])) {
56
            $def = ['class' => $def];
57
        }
58
59
        // resolve arguments
60
        if (!empty($args)) {
61
            $this->master->resolve($args);
62
            $def['args'] = $args;
63
        }
64
65
        return (array) $def;
66
    }
67
68
    /**
69
     * Instantiate service object from classname
70
     *
71
     * @param  string $class
72
     * @param  array $args
73
     * @return object
74
     * @throws LogicException if something goes wrong
75
     * @access protected
76
     */
77
    protected function constructObject(/*# string */ $class, array $args)
78
    {
79
        $reflector = new \ReflectionClass($class);
80
        $constructor = $reflector->getConstructor();
81
82
        // not constructor defined
83
        if (is_null($constructor)) {
84
            $obj = $reflector->newInstanceWithoutConstructor();
85
86
        // normal class with constructor
87
        } else {
88
            $args = $this->matchArguments(
89
                $constructor->getParameters(),
90
                $args
91
            );
92
            $obj = $reflector->newInstanceArgs($args);
93
        }
94
95
        return $obj;
96
    }
97
98
    /**
99
     * Match provided arguments with a method/function's reflection parameters
100
     *
101
     * @param  \ReflectionParameter[] $reflectionParameters
102
     * @param  array $providedArguments
103
     * @return array the resolved arguments
104
     * @throws LogicException
105
     * @access protected
106
     */
107
    protected function matchArguments(
108
        array $reflectionParameters,
109
        array $providedArguments
110
    )/*# : array */ {
111
        // result
112
        $resolvedArguments = [];
113
        foreach ($reflectionParameters as $i => $param) {
114
            $class = $param->getClass();
115
            if ($this->isTypeMatched($class, $providedArguments)) {
116
                $resolvedArguments[$i] = array_shift($providedArguments);
117
            } elseif ($this->isRequiredClass($param, $providedArguments)) {
118
                $resolvedArguments[$i] = $this->getObjectByClass($class->getName());
119
            }
120
        }
121
        return array_merge($resolvedArguments, $providedArguments);
122
    }
123
124
    /**
125
     * Try best to guess parameter and argument are the same type
126
     *
127
     * @param  null|\ReflectionClass $class
128
     * @param  array $arguments
129
     * @return bool
130
     * @access protected
131
     */
132
    protected function isTypeMatched($class, array $arguments)/*# : bool */
133
    {
134
        if (empty($arguments)) {
135
            return false;
136
        } elseif (null !== $class) {
137
            return is_a($arguments[0], $class->getName());
138
        } else {
139
            return true;
140
        }
141
    }
142
143
    /**
144
     * Is $param required and is a class/interface
145
     *
146
     * @param  \ReflectionParameter $param
147
     * @param  array $arguments
148
     * @return bool
149
     * @throws LogicException if mismatched arguments
150
     * @access protected
151
     */
152
    protected function isRequiredClass(
153
        \ReflectionParameter $param,
154
        array $arguments
155
    )/*# : bool */ {
156
        $optional = $param->isOptional();
157
        if ($param->getClass()) {
158
            return !$optional || !empty($arguments);
159
        } else {
160
            return false;
161
        }
162
    }
163
164
    /**
165
     * Get an object base on provided classname or interface name
166
     *
167
     * @param  string $classname class or interface name
168
     * @return object
169
     * @throws \Exception if something goes wrong
170
     * @access protected
171
     */
172
    protected function getObjectByClass(/*# string */ $classname)
173
    {
174
        // mapping exists
175
        if ($this->master->getResolver()->hasMapping($classname)) {
176
            $classname = $this->master->getResolver()->getMapping($classname);
177
            if (is_object($classname)) {
178
                return $classname;
179
            }
180
        }
181
        return $this->master->getResolver()->get($classname);
182
    }
183
184
    /**
185
     * Get callable parameters
186
     *
187
     * @param  callable $callable
188
     * @return \ReflectionParameter[]
189
     * @throws LogicException if something goes wrong
190
     * @access protected
191
     */
192
    protected function getCallableParameters(callable $callable)/*# : array */
193
    {
194
        // array type
195
        if (is_array($callable)) {
196
            $reflector = new \ReflectionClass($callable[0]);
197
            $method = $reflector->getMethod($callable[1]);
198
199
        // object with __invoke() defined
200
        } elseif ($this->isInvocable($callable)) {
201
            $reflector = new \ReflectionClass($callable);
202
            $method = $reflector->getMethod('__invoke');
203
204
        // simple function
205
        } else {
206
            $method = new \ReflectionFunction($callable);
207
        }
208
209
        return $method->getParameters();
210
    }
211
212
    /**
213
     * Is $var an object with '__invoke()' defined ?
214
     *
215
     * @param  mixed $var
216
     * @return bool
217
     * @access protected
218
     */
219
    protected function isInvocable($var)/*# : bool */
220
    {
221
        return is_object($var) && method_exists($var, '__invoke');
222
    }
223
224
    /**
225
     * Merge different sections of a node
226
     *
227
     * convert
228
     *   `['section1' => [[1], [2]], 'section2' => [[3], [4]]]`
229
     *
230
     * to
231
     *   `[[1], [2], [3], [4]]`
232
     *
233
     * @param  array $nodeData
234
     * @return array
235
     * @access protected
236
     */
237
    protected function mergeMethods(array $nodeData)/*# : array */
238
    {
239
        // no merge
240
        if (empty($nodeData) || isset($nodeData[0])) {
241
            return $nodeData;
242
        }
243
244
        // in sections
245
        $result = [];
246
        foreach ($nodeData as $data) {
247
            $result = array_merge($result, $data);
248
        }
249
        return $result;
250
    }
251
252
    /**
253
     * Execute common methods defined in 'di.common' for all objects
254
     *
255
     * @param  object $object
256
     * @return $this
257
     * @access protected
258
     */
259
    protected function executeCommonBatch($object)
260
    {
261
        $methods = [];
262
263
        // get from 'di.common'
264
        if ($this->master->getResolver()->hasInSection('', 'common')) {
265
            $methods = $this->mergeMethods(
266
                $this->master->getResolver()->getInSection('', 'common')
267
            );
268
        }
269
270
        foreach ($methods as $method) {
271
            if (call_user_func($method[0], $object, $this->master)) {
272
                call_user_func($method[1], $object, $this->master);
273
            }
274
        }
275
        return $this;
276
    }
277
}
278