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 ( 8c3ee0...d7f4ea )
by Hong
04:46
created

FactoryTrait::mergeMethods()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
rs 9.2
cc 4
eloc 7
nc 3
nop 1
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\Message\Message;
19
use Phossa2\Di\Exception\LogicException;
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
     * @throws NotFoundException
106
     * @access protected
107
     */
108
    protected function matchArguments(
109
        array $reflectionParameters,
110
        array $providedArguments
111
    )/*# : array */ {
112
        // result
113
        $resolvedArguments = [];
114
115
        // go thru each predefined parameter
116
        foreach ($reflectionParameters as $i => $param) {
117
            // arg to match with
118
            $argument = isset($providedArguments[0]) ? $providedArguments[0] : null;
119
120
            // check the class
121
            $class = $param->getClass();
122
123
            if ($this->isTypeMatched($param, $argument, $class)) {
124
                // type matched
125
                $resolvedArguments[$i] = array_shift($providedArguments);
126
127
            } elseif (null !== $class) {
128
                // not matched, but $param is an interface or class
129
                $resolvedArguments[$i] = $this->getObjectByClass($class->getName());
130
131
            } elseif ($param->isOptional()) {
132
                // $param is optional, $arg is null
133
                break;
134
            } else {
135
                throw new LogicException(
136
                    Message::get(Message::DI_PARAMETER_NOTFOUND, $param->getName()),
137
                    Message::DI_PARAMETER_NOTFOUND
138
                );
139
            }
140
        }
141
142
        // append remained arguments if any
143
        if (!empty($providedArguments)) {
144
            $resolvedArguments = array_merge($resolvedArguments, $providedArguments);
145
        }
146
147
        return $resolvedArguments;
148
    }
149
150
    /**
151
     * Is $parameter same type as the $argument ?
152
     *
153
     * @param  \ReflectionParameter $parameter
154
     * @param  mixed $argument
155
     * @param  null|string $class
156
     * @return bool
157
     * @access protected
158
     */
159
    protected function isTypeMatched(
160
        \ReflectionParameter $parameter,
161
        $argument,
162
        $class
163
    )/*# : bool */ {
164
        if (null === $argument) {
165
            return false;
166
        } elseif (null !== $class) {
167
            return is_a($argument, $parameter->getClass()->getName());
168
        } else {
169
            return true;
170
        }
171
    }
172
173
    /**
174
     * Get an object base on provided classname or interface name
175
     *
176
     * @param  string $classname class or interface name
177
     * @return object
178
     * @throws \Exception if something goes wrong
179
     * @access protected
180
     */
181
    protected function getObjectByClass(/*# string */ $classname)
182
    {
183
        // mapping exists
184
        if ($this->master->getResolver()->hasMapping($classname)) {
185
            $classname = $this->master->getResolver()->getMapping($classname);
186
            if (is_object($classname)) {
187
                return $classname;
188
            }
189
        }
190
        return $this->master->getResolver()->get($classname);
191
    }
192
193
    /**
194
     * Get callable parameters
195
     *
196
     * @param  callable $callable
197
     * @return \ReflectionParameter[]
198
     * @throws LogicException if something goes wrong
199
     * @access protected
200
     */
201
    protected function getCallableParameters(callable $callable)/*# : array */
202
    {
203
        // array type
204
        if (is_array($callable)) {
205
            $reflector = new \ReflectionClass($callable[0]);
206
            $method = $reflector->getMethod($callable[1]);
207
208
        // object with __invoke() defined
209
        } elseif ($this->isInvocable($callable)) {
210
            $reflector = new \ReflectionClass($callable);
211
            $method = $reflector->getMethod('__invoke');
212
213
        // simple function
214
        } else {
215
            $method = new \ReflectionFunction($callable);
216
        }
217
218
        return $method->getParameters();
219
    }
220
221
    /**
222
     * Is $var an object with '__invoke()' defined ?
223
     *
224
     * @param  mixed $var
225
     * @return bool
226
     * @access protected
227
     */
228
    protected function isInvocable($var)/*# : bool */
229
    {
230
        return is_object($var) && method_exists($var, '__invoke');
231
    }
232
233
    /**
234
     * Merge different sections of a node
235
     *
236
     * convert
237
     *   `['section1' => [[1], [2]], 'section2' => [[3], [4]]]`
238
     *
239
     * to
240
     *   `[[1], [2], [3], [4]]`
241
     *
242
     * @param  array $nodeData
243
     * @return array
244
     * @access protected
245
     */
246
    protected function mergeMethods(array $nodeData)/*# : array */
247
    {
248
        // no merge
249
        if (empty($nodeData) || isset($nodeData[0])) {
250
            return $nodeData;
251
        }
252
253
        // in sections
254
        $result = [];
255
        foreach ($nodeData as $data) {
256
            $result = array_merge($result, $data);
257
        }
258
        return $result;
259
    }
260
261
    /**
262
     * Execute common methods defined in 'di.common' for all objects
263
     *
264
     * @param  object $object
265
     * @return $this
266
     * @access protected
267
     */
268
    protected function executeCommonBatch($object)
269
    {
270
        $methods = [];
271
272
        // get from 'di.common'
273
        if ($this->master->getResolver()->hasInSection('', 'common')) {
274
            $methods = $this->mergeMethods(
275
                $this->master->getResolver()->getInSection('', 'common')
276
            );
277
        }
278
279
        foreach ($methods as $method) {
280
            if (call_user_func($method[0], $object, $this->master)) {
281
                call_user_func($method[1], $object, $this->master);
282
            }
283
        }
284
        return $this;
285
    }
286
}
287