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 ( 6e4eb2...dda63a )
by Hong
02:42
created

FactoryTrait::getObjectMethod()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 13
rs 9.2
cc 4
eloc 9
nc 3
nop 2
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\Resolver\ObjectResolver;
20
use Phossa2\Di\Message\Message;
21
22
/**
23
 * FactoryTrait
24
 *
25
 * Create service instance here
26
 *
27
 * @package Phossa2\Di
28
 * @author  Hong Zhang <[email protected]>
29
 * @version 2.0.0
30
 * @since   2.0.0 added
31
 */
32
trait FactoryTrait
33
{
34
    /**
35
     * @var    Container
36
     * @access protected
37
     */
38
    protected $master;
39
40
    /**
41
     * Get service definition (and fix it)
42
     *
43
     * @param  string $rawId
44
     * @param  array $args
45
     * @return array
46
     * @access protected
47
     */
48
    protected function getDefinition(
49
        /*# string */ $rawId,
50
        array $args
51
    )/*# : array */ {
52
        // get the definition
53
        $def = $this->master->getResolver()->getService($rawId);
54
55
        // fix class
56
        if (!is_array($def) || !isset($def['class'])) {
57
            $def = ['class' => $def];
58
        }
59
60
        // add resolved arguments
61
        if (!empty($args)) {
62
            $this->master->resolve($args);
63
            $def['args'] = $args;
64
        }
65
66
        return (array) $def;
67
    }
68
69
    /**
70
     * Instantiate service object from classname
71
     *
72
     * @param  string $class
73
     * @param  array $args
74
     * @return object
75
     * @throws LogicException if something goes wrong
76
     * @access protected
77
     */
78
    protected function constructObject(/*# string */ $class, array $args)
79
    {
80
        $reflector = new \ReflectionClass($class);
81
        $constructor = $reflector->getConstructor();
82
83
        // not constructor defined
84
        if (is_null($constructor)) {
85
            $obj = $reflector->newInstanceWithoutConstructor();
86
87
        // normal class with constructor
88
        } else {
89
            $args = $this->matchArguments(
90
                $constructor->getParameters(),
91
                $args
92
            );
93
            $obj = $reflector->newInstanceArgs($args);
94
        }
95
96
        return $obj;
97
    }
98
99
    /**
100
     * Match provided arguments with a method/function's reflection parameters
101
     *
102
     * @param  \ReflectionParameter[] $reflectionParameters
103
     * @param  array $providedArguments
104
     * @return array the resolved arguments
105
     * @throws LogicException
106
     * @access protected
107
     */
108
    protected function matchArguments(
109
        array $reflectionParameters,
110
        array $providedArguments
111
    )/*# : array */ {
112
        // result
113
        $resolvedArguments = [];
114
        foreach ($reflectionParameters as $i => $param) {
115
            $class = $param->getClass();
116
117
            if ($this->isTypeMatched($class, $providedArguments)) {
118
                $resolvedArguments[$i] = array_shift($providedArguments);
119
120
            } elseif ($this->isRequiredClass($param, $providedArguments)) {
121
                $resolvedArguments[$i] = $this->getObjectByClass($class->getName());
122
            }
123
        }
124
        return array_merge($resolvedArguments, $providedArguments);
125
    }
126
127
    /**
128
     * Try best to guess parameter and argument are the same type
129
     *
130
     * @param  null|\ReflectionClass $class
131
     * @param  array $arguments
132
     * @return bool
133
     * @access protected
134
     */
135
    protected function isTypeMatched($class, array $arguments)/*# : bool */
136
    {
137
        if (empty($arguments)) {
138
            return false;
139
        } elseif (null !== $class) {
140
            return is_a($arguments[0], $class->getName());
141
        } else {
142
            return true;
143
        }
144
    }
145
146
    /**
147
     * Is $param required and is a class/interface
148
     *
149
     * @param  \ReflectionParameter $param
150
     * @param  array $arguments
151
     * @return bool
152
     * @throws LogicException if mismatched arguments
153
     * @access protected
154
     */
155
    protected function isRequiredClass(
156
        \ReflectionParameter $param,
157
        array $arguments
158
    )/*# : bool */ {
159
        $optional = $param->isOptional();
160
        if ($param->getClass()) {
161
            return !$optional || !empty($arguments);
162
        } else {
163
            return false;
164
        }
165
    }
166
167
    /**
168
     * Get an object base on provided classname or interface name
169
     *
170
     * @param  string $classname class or interface name
171
     * @return object
172
     * @throws \Exception if something goes wrong
173
     * @access protected
174
     */
175
    protected function getObjectByClass(/*# string */ $classname)
176
    {
177
        $mapped = $classname;
178
179
        // has mapping ?
180
        if ($this->master->getResolver()->hasMapping($classname)) {
181
            $mapped = $this->master->getResolver()->getMapping($classname);
182
        }
183
        $obj = $this->getObjectByType($mapped, $classname);
184
185
        if (is_a($obj, $classname, false)) {
186
            return $obj;
187
        } else {
188
            throw new LogicException(
189
                Message::get(Message::DI_CLASS_UNKNOWN, $classname),
190
                Message::DI_CLASS_UNKNOWN
191
            );
192
        }
193
    }
194
195
    /**
196
     * Get callable parameters
197
     *
198
     * @param  callable $callable
199
     * @return \ReflectionParameter[]
200
     * @throws LogicException if something goes wrong
201
     * @access protected
202
     */
203
    protected function getCallableParameters(callable $callable)/*# : array */
204
    {
205
        // array type
206
        if (is_array($callable)) {
207
            $reflector = new \ReflectionClass($callable[0]);
208
            $method = $reflector->getMethod($callable[1]);
209
210
        // object with __invoke() defined
211
        } elseif ($this->isInvocable($callable)) {
212
            $reflector = new \ReflectionClass($callable);
213
            $method = $reflector->getMethod('__invoke');
214
215
        // simple function
216
        } else {
217
            $method = new \ReflectionFunction($callable);
218
        }
219
220
        return $method->getParameters();
221
    }
222
223
    /**
224
     * Is $var a non-closure object with '__invoke()' defined ?
225
     *
226
     * @param  mixed $var
227
     * @return bool
228
     * @access protected
229
     */
230
    protected function isInvocable($var)/*# : bool */
231
    {
232
        return is_object($var) &&
233
            !$var instanceof \Closure &&
234
            method_exists($var, '__invoke');
235
    }
236
237
    /**
238
     * Returns [$object, $method] if it is a callable, otherwise returns $method
239
     *
240
     * @param  mixed $object
241
     * @param  mixed $method
242
     * @return bool
243
     * @access protected
244
     */
245
    protected function getObjectMethod($object, $method)/*# : bool */
246
    {
247
        if (is_string($method) && method_exists($object, $method)) {
248
            return [$object, $method];
249
        } elseif (is_callable($method)) {
250
            return $method;
251
        } else {
252
            throw new LogicException(
253
                Message::get(Message::DI_CALLABLE_BAD, $method),
254
                Message::DI_CALLABLE_BAD
255
            );
256
        }
257
    }
258
259
    /**
260
     * Get object by different mapped
261
     *
262
     * @param  mixed $mapped
263
     * @param  string $classname
264
     * @return object
265
     * @access protected
266
     */
267
    protected function getObjectByType($mapped, /*# string */ $classname)
268
    {
269
        // matched object
270
        if (is_a($mapped, $classname, false)) {
271
            return $mapped;
272
        }
273
274
        // callable
275
        if (is_callable($mapped)) {
276
            $mapped = call_user_func($mapped);
1 ignored issue
show
Coding Style introduced by
Consider using a different name than the parameter $mapped. This often makes code more readable.
Loading history...
277
        }
278
279
        // string
280
        if (is_string($mapped)) {
281
            $serviceId = ObjectResolver::getServiceId($mapped);
282
            $mapped = $this->master->getResolver()->get($serviceId);
1 ignored issue
show
Coding Style introduced by
Consider using a different name than the parameter $mapped. This often makes code more readable.
Loading history...
283
        }
284
285
        return $mapped;
286
    }
287
288
    /**
289
     * Merge different sections of a node
290
     *
291
     * convert
292
     *   `['section1' => [[1], [2]], 'section2' => [[3], [4]]]`
293
     *
294
     * to
295
     *   `[[1], [2], [3], [4]]`
296
     *
297
     * @param  array|null $nodeData
298
     * @return array
299
     * @access protected
300
     */
301
    protected function mergeMethods($nodeData)/*# : array */
302
    {
303
        // no merge
304
        if (empty($nodeData) || isset($nodeData[0])) {
305
            return (array) $nodeData;
306
        }
307
308
        // in sections
309
        $result = [];
310
        foreach ($nodeData as $data) {
311
            $result = array_merge($result, $data);
312
        }
313
        return $result;
314
    }
315
}
316