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

FactoryTrait::matchArguments()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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