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 ( 57b219...b1cdd5 )
by Hong
02:46
created

FactoryTrait::matchArguments()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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