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 ( 84f915...15625b )
by Hong
03:10
created

Factory   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 235
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 8
Bugs 1 Features 1
Metric Value
wmc 32
c 8
b 1
f 1
lcom 1
cbo 6
dl 0
loc 235
rs 9.6

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A createInstance() 0 20 3
A executeCallable() 0 15 3
A executeMethodBatch() 0 6 2
A executeMethod() 0 14 4
A afterCreation() 0 13 4
A getCommonMethods() 0 9 1
A mergeMethods() 0 14 4
A getObjectMethod() 0 13 4
A getDefinition() 0 19 4
A getObjectByClass() 0 11 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\Factory;
16
17
use Phossa2\Di\Message\Message;
18
use Phossa2\Di\Resolver\ObjectResolver;
19
use Phossa2\Shared\Base\ObjectAbstract;
20
use Phossa2\Di\Exception\LogicException;
21
use Phossa2\Di\Traits\ResolverAwareTrait;
22
use Phossa2\Di\Interfaces\FactoryInterface;
23
use Phossa2\Di\Interfaces\ResolverInterface;
24
25
/**
26
 * Factory
27
 *
28
 * Wrapper of factorying methods for container
29
 *
30
 * @package Phossa2\Di
31
 * @author  Hong Zhang <[email protected]>
32
 * @see     FactoryInterface
33
 * @version 2.0.0
34
 * @since   2.0.0 added
35
 */
36
class Factory extends ObjectAbstract implements FactoryInterface
37
{
38
    use ResolverAwareTrait, FactoryHelperTrait;
39
40
    /**
41
     * @param  ResolverInterface
42
     * @access public
43
     */
44
    public function __construct(ResolverInterface $resolver)
45
    {
46
        $this->setResolver($resolver);
47
    }
48
49
    /**
50
     * {@inheritDoc}
51
     */
52
    public function createInstance(/*# string */ $rawId, array $arguments)
53
    {
54
        // get service definition
55
        $def = $this->getDefinition($rawId, $arguments);
56
57
        // arguments
58
        $args = isset($def['args']) ? $def['args'] : [];
59
60
        if (is_string($def['class'])) {
61
            $obj = $this->constructObject($def['class'], $args);
62
63
        } else {
64
            $obj = $this->executeCallable($def['class'], $args);
65
        }
66
67
        // execute after-creation methods
68
        $this->afterCreation($obj, $def);
69
70
        return $obj;
71
    }
72
73
    /**
74
     * {@inheritDoc}
75
     */
76
    public function executeCallable($callable, array $arguments = [])
77
    {
78
        // not callable
79
        if (!is_callable($callable)) {
80
            return $callable;
81
        }
82
83
        if (!empty($arguments)) {
84
            $params = $this->getCallableParameters($callable);
85
            $args = $this->matchArguments($params, $arguments);
86
            return call_user_func_array($callable, $args);
87
        } else {
88
            return call_user_func($callable);
89
        }
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function executeMethodBatch(array $methods, $object = null)
96
    {
97
        foreach ($this->mergeMethods($methods) as $method) {
98
            $this->executeMethod($method, $object);
99
        }
100
    }
101
102
    /**
103
     * if $object provided, build callable like [$object, $method] and execute it.
104
     *
105
     * method:
106
     *
107
     * - callable
108
     *
109
     * - array ['function', [ arguments...]]
110
     *
111
     * - array [callable, [ arguments ...]]
112
     *
113
     * - array ['method', [ arguments ...]]
114
     *   will be converted to [[$object, 'method'], [ ... ]]
115
     *
116
     * @param  array|callable method
117
     * @param  object|null $object to construct callable
118
     * @throws LogicException if something goes wrong
119
     * @access protected
120
     */
121
    protected function executeMethod($method, $object = null)
122
    {
123
        // is callable
124
        if (is_callable($method)) {
125
            return $this->executeCallable($method);
126
127
        // is [ method, arguments ]
128
        } elseif (isset($method[0])) {
129
            return $this->executeCallable(
130
                $this->getObjectMethod($object, $method[0]), // callable
131
                isset($method[1]) ? $method[1] : [] // arguments
132
            );
133
        }
134
    }
135
136
    /**
137
     * Things to do after an object created.
138
     *
139
     * @param  object $object
140
     * @param  array $definition service definition for $object
141
     * @access protected
142
     */
143
    protected function afterCreation($object, array $definition)
144
    {
145
        // execute methods of THIS object
146
        if (isset($definition['methods'])) {
147
            $this->executeMethodBatch($definition['methods'], $object);
148
        }
149
150
        // execute common methods for all objects
151
        if (!isset($definition['skip']) || !$definition['skip']) {
152
            $methods = $this->getCommonMethods();
153
            $this->executeMethodBatch($methods, $object);
154
        }
155
    }
156
157
    /**
158
     * Get common methods
159
     *
160
     * @return array
161
     * @access protected
162
     */
163
    protected function getCommonMethods()/*# : array */
164
    {
165
        // di.common node
166
        $commNode = $this->getResolver()->getSectionId('', 'common');
167
168
        return $this->mergeMethods(
169
            $this->getResolver()->get($commNode)
170
        );
171
    }
172
173
    /**
174
     * Merge different sections of a node
175
     *
176
     * convert
177
     *   `['section1' => [[1], [2]], 'section2' => [[3], [4]]]`
178
     *
179
     * to
180
     *   `[[1], [2], [3], [4]]`
181
     *
182
     * @param  array|null $nodeData
183
     * @return array
184
     * @access protected
185
     */
186
    protected function mergeMethods($nodeData)/*# : array */
187
    {
188
        // no merge
189
        if (empty($nodeData) || isset($nodeData[0])) {
190
            return (array) $nodeData;
191
        }
192
193
        // in sections
194
        $result = [];
195
        foreach ($nodeData as $data) {
196
            $result = array_merge($result, $data);
197
        }
198
        return $result;
199
    }
200
201
    /**
202
     * Returns [$object, $method] if it is a callable, otherwise returns $method
203
     *
204
     * @param  mixed $object
205
     * @param  mixed $method
206
     * @return bool
207
     * @access protected
208
     */
209
    protected function getObjectMethod($object, $method)/*# : bool */
210
    {
211
        if (is_string($method) && method_exists($object, $method)) {
212
            return [$object, $method];
213
        } elseif (is_callable($method)) {
214
            return $method;
215
        } else {
216
            throw new LogicException(
217
                Message::get(Message::DI_CALLABLE_BAD, $method),
218
                Message::DI_CALLABLE_BAD
219
            );
220
        }
221
    }
222
223
    /**
224
     * Get service definition
225
     *
226
     * @param  string $rawId
227
     * @param  array $args
228
     * @return array
229
     * @access protected
230
     */
231
    protected function getDefinition(
232
        /*# string */ $rawId,
233
        array $args
234
    )/*# : array */ {
235
        // get the definition
236
        $def = $this->getResolver()->getService($rawId);
237
238
        // fix class
239
        if (!is_array($def) || !isset($def['class'])) {
240
            $def = ['class' => $def];
241
        }
242
243
        // add arguments
244
        if (!empty($args)) {
245
            $def['args'] = $args;
246
        }
247
248
        return (array) $def;
249
    }
250
251
    /**
252
     * Get an object base on provided classname or interface name
253
     *
254
     * @param  string $classname class or interface name
255
     * @return object
256
     * @throws \Exception if something goes wrong
257
     * @access protected
258
     */
259
    protected function getObjectByClass(/*# string */ $classname)
260
    {
261
        if ($this->getResolver()->hasService($classname)) {
262
            $serviceId = ObjectResolver::getServiceId($classname);
263
            return $this->getResolver()->get($serviceId);
264
        }
265
        throw new LogicException(
266
            Message::get(Message::DI_CLASS_UNKNOWN, $classname),
267
            Message::DI_CLASS_UNKNOWN
268
            );
269
    }
270
}
271