Completed
Push — master ( 465cbd...e0d13e )
by Marco
06:44 queued 11s
created

Model::compose()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 57
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 9.2861

Importance

Changes 0
Metric Value
dl 0
loc 57
c 0
b 0
f 0
ccs 16
cts 25
cp 0.64
rs 7.6759
cc 7
eloc 24
nc 7
nop 1
crap 9.2861

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Comodojo\Dispatcher\Router;
2
3
use \Comodojo\Dispatcher\Traits\CacheTrait;
4
use \Comodojo\Foundation\Events\EventsTrait;
5
use \Comodojo\Dispatcher\Traits\RequestTrait;
6
use \Comodojo\Dispatcher\Traits\ResponseTrait;
7
use \Comodojo\Dispatcher\Traits\ExtraTrait;
8
use \Comodojo\Dispatcher\Components\AbstractModel;
9
use \Comodojo\Dispatcher\Request\Model as Request;
10
use \Comodojo\Dispatcher\Response\Model as Response;
11
use \Comodojo\Dispatcher\Extra\Model as Extra;
12
use \Comodojo\Foundation\Base\Configuration;
13
use \Comodojo\Foundation\Events\Manager as EventsManager;
14
use \Comodojo\SimpleCache\Manager as SimpleCacheManager;
15
use \Psr\Log\LoggerInterface;
16
use \Comodojo\Exception\DispatcherException;
17
use \Exception;
18
19
/**
20
 * @package     Comodojo Dispatcher
21
 * @author      Marco Giovinazzi <[email protected]>
22
 * @author      Marco Castiello <[email protected]>
23
 * @license     MIT
24
 *
25
 * LICENSE:
26
 *
27
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
 * THE SOFTWARE.
34
 */
35
36
class Model extends AbstractModel {
37
38
    use CacheTrait;
39
    use EventsTrait;
40
    use RequestTrait;
41
    use ResponseTrait;
42
    use ExtraTrait;
43
44
    protected $bypass_routing = false;
45
    protected $bypass_service = false;
46
    protected $table;
47
    protected $route;
48
49 1
    public function __construct(
50
        Configuration $configuration,
51
        LoggerInterface $logger,
52
        SimpleCacheManager $cache,
53
        EventsManager $events,
54
        Extra $extra
55
    ) {
56
57 1
        parent::__construct($configuration, $logger);
58
59 1
        $this->setCache($cache);
60 1
        $this->setExtra($extra);
61 1
        $this->setEvents($events);
62
63 1
        $this->setTable(new Table($configuration, $logger, $cache));
64
65 1
    }
66
67 1
    public function getTable() {
68
69 1
        return $this->table;
70
71
    }
72
73 1
    public function setTable(Table $table) {
74
75 1
        $this->table = $table;
76
77 1
    }
78
79 1
    public function bypassRouting(Route $route) {
80
81 1
        $this->bypass_routing = true;
82
83 1
        $this->route = $route;
84
85 1
        return $this;
86
87
    }
88
89
    public function bypassService() {
90
91
        $this->bypass_service = true;
92
93
        return $this;
94
95
    }
96
97
    public function getRoute() {
98
99
        return $this->route;
100
101
    }
102
103 2
    public function route(Request $request) {
104
105 2
        $method = (string) $request->getMethod();
106
107 2
        $methods = $this->configuration->get('allowed-http-methods');
108
109 2
        if (!empty($methods) && in_array($method, $methods) === false) {
110
111
            throw new DispatcherException("Method not allowed", 0, null, 405, array(
112
                "Allow" => implode(",", $methods)
113
            ));
114
115
        }
116
117 2
        $this->setRequest($request);
118
119 2
        if ($this->bypass_routing === false) {
120
121 1
            if (!$this->parse()) throw new DispatcherException("Unable to find a valid route for the specified uri", 0, null, 404);
122
123
        }
124
125 1
        return $this->route;
126
127
    }
128
129 1
    public function getServiceInstance() {
130
131 1
        $class = $this->route->getClassName();
132
133 1
        if (class_exists($class)) {
134
135
            // All the route parameters are also added to the query parameters
136 1
            foreach ($this->route->getRequestParameters() as $parameter => $value) {
137
                $this->getRequest()->getQuery()->set($parameter, $value);
138 1
            }
139
140 1
            return new $class(
141 1
                $this->getConfiguration(),
142 1
                $this->getLogger(),
143 1
                $this->getCache(),
144 1
                $this->getEvents(),
145 1
                $this->getRequest(),
146 1
                $this,
147 1
                $this->getResponse(),
148 1
                $this->getExtra()
149 1
            );
150
151
        }
152
153
        return null;
154
155
    }
156
157 1
    public function compose(Response $response) {
158
159 1
        $this->setResponse($response);
160
161 1
        if (is_null($this->route)) {
162
163
            throw new DispatcherException("Route has not been loaded!");
164
165
        }
166
167 1
        if ($this->bypass_service) {
168
169
            return;
170
171
        }
172
173 1
        $service = $this->getServiceInstance();
174
175 1
        if (!is_null($service)) {
176
177 1
            $result = "";
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
178
179 1
            $method = (string)$this->getRequest()->getMethod();
180
181 1
            $methods = $service->getImplementedMethods();
182
183 1
            if (in_array($method, $methods)) {
184
185 1
                $callable = $service->getMethod($method);
186
187
                try {
188
189 1
                    $result = call_user_func([$service, $callable]);
190
191 1
                } catch (DispatcherException $de) {
192
193
                    throw $de;
194
195
                } catch (Exception $e) {
196
197
                    throw new DispatcherException(sprintf("Service '%s' execution failed for method '%s': %s", $this->route->getClassName(), $method, $e->getMessage()), 0, $e, 500);
198
199
                }
200
201 1
            } else {
202
203
                throw new DispatcherException(sprintf("Service '%s' doesn't implement method '%s'", $this->route->getServiceName(), $method), 0, null, 501, array(
204
                    "Allow" => implode(",", $methods)
205
                ));
206
207
            }
208
209 1
            $this->getResponse()->getContent()->set($result);
210
211 1
        } else {
212
213
            throw new DispatcherException(sprintf("Unable to execute service '%s'", $this->route->getClassName()), 0, null, 500);
214
215
        }
216
217 1
    }
218
219 1
    private function parse() {
220
221 1
        $path = urldecode($this->getRequest()->route());
222
223 1
        foreach ($this->table->getRoutes() as $regex => $value) {
224
225
            // The current uri is checked against all the global regular expressions associated with the routes
226
            if (preg_match("/".$regex."/", $path, $matches)) {
227
228
                /* If a route is matched, all the bits of the route string are evalued in order to create
229
                 * new query parameters which will be available for the service class
230
                 */
231
                $this->route = $value->path($matches);
232
233
                return true;
234
235
            }
236
237 1
        }
238
239 1
        return false;
240
241
    }
242
243
}
244