Completed
Push — master ( f2e2ec...42a45d )
by Damien
02:44
created

DispatcherLayer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Test Coverage

Coverage 47.22%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 10
c 2
b 0
f 0
lcom 0
cbo 3
dl 0
loc 74
ccs 17
cts 36
cp 0.4722
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B in() 0 56 9
1
<?php
2
/**
3
 * Veto.
4
 * PHP Microframework.
5
 *
6
 * @author Damien Walsh <[email protected]>
7
 * @copyright Damien Walsh 2013-2014
8
 * @version 0.1
9
 * @package veto
10
 */
11
namespace Veto\Layer\Dispatcher;
12
13
use Veto\DI\AbstractContainerAccessor;
14
use Veto\DI\Container;
15
use Veto\HTTP\Request;
16
use Veto\HTTP\Response;
17
use Veto\Layer\InboundLayerInterface;
18
19
/**
20
 * DispatcherLayer
21
 *
22
 * Dispatches a Request to a controller, obtaining a Response.
23
 */
24
class DispatcherLayer extends AbstractContainerAccessor implements InboundLayerInterface
25
{
26
    /**
27
     * Set the service container.
28
     *
29
     * @param Container $container
30
     */
31 2
    public function __construct(Container $container)
32
    {
33 2
        $this->container = $container;
34 2
    }
35
36
    /**
37
     * @param Request $request
38
     * @return mixed
39
     * @throws \RuntimeException
40
     */
41 2
    public function in(Request $request)
42
    {
43
        // Get the controller
44 2
        $controllerSpec = $request->getParameter('_controller');
45
46 2
        if (!$controllerSpec) {
47 1
            throw new \RuntimeException('The request was not tagged by a router.', 500);
48
        }
49
50 1
        $controller = $this->container->get($controllerSpec['class']);
51
52 1
        if (!method_exists($controller, $controllerSpec['method'])) {
53
            throw new \RuntimeException(
54
                'The controller action "' . $controllerSpec['method'] .
55
                '" does not exist for controller "' .
56
                $controllerSpec['class'] . '".'
57
            );
58
        }
59
60
        // Prepare to run the action method
61 1
        $actionMethod = new \ReflectionMethod($controller, $controllerSpec['method']);
62 1
        $parameters = $actionMethod->getParameters();
63 1
        $passedArgs = array();
64
65 1
        foreach ($parameters as $parameter) {
66
67
            $hintedClass = $parameter->getClass();
68
            $parameterName = $parameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
69
70
            if ($hintedClass) {
71
                $hintedClass = $hintedClass->getName();
0 ignored issues
show
Bug introduced by
Consider using $hintedClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
72
            }
73
74
            // Special case - should the Request object be passed here?
75
            if ($parameterName == 'request' && $hintedClass == 'Veto\HTTP\Request') {
76
                $passedArgs[] = $request;
77
            }
78
79
            // Should a request parameter be passed here?
80
            if ($request->hasParameter($parameterName)) {
81
                $passedArgs[] = $request->getParameter($parameterName);
82
            }
83 1
        }
84
85 1
        $response = $actionMethod->invokeArgs($controller, $passedArgs);
86
87
        // By the end of the inbound layer list, a response should have been obtained
88 1
        if (!$response instanceof Response) {
89
            throw new \RuntimeException(
90
                'The controller action method must return a Response type. ' .
91
                'The controller returned ' . gettype($response) . '.'
92
            );
93
        }
94
95 1
        return $response;
96
    }
97
}
98