Test Failed
Push — master ( 2cec8a...dd5709 )
by Jay
02:09
created

Framework::getParameterMatching()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 2
cts 2
cp 1
rs 9.4285
cc 3
eloc 7
nc 3
nop 2
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Nano;
5
6
/**
7
 * Class Framework
8
 * @package Nano
9
 */
10
final class Framework
11
{
12
    private $projectNamespace = '\Project';
13
    private $controllerPackage = '\Controller';
14
    private $controllerActionSuffix = 'Action';
15
    private $withParameterMatching = false;
16
17
    /**
18
     * Dispatch the request
19
     * @throws \Exception
20
     * @return mixed
21 10
     */
22
    public function dispatch()
23 10
    {
24 10
        list($controllerName, $action) = $this->getControllerAndAction();
25 10
        $controller = $this->getControllerFromName($controllerName);
26 3
        $finalAction = $this->getVerbFromRequest() . ucfirst($action) . $this->controllerActionSuffix;
27
        if (is_callable(array($controller, $finalAction))) {
28 7
            return call_user_func_array(array($controller, $action), $this->getParameterMatching($controller, $action));
29 7
        }
30 7
        $finalAction = $action . $this->controllerActionSuffix;
31 1
        if (!is_callable(array($controller, $finalAction))) {
32
            throw new \Exception('action ' . $finalAction . ' not found in controller ' . $controllerName);
33 6
        }
34 6
        return call_user_func_array(array($controller, $action), $this->getParameterMatching($controller, $action));
35 1
    }
36
37 5
    /**
38
     * @param \object $controller
39
     * @param string $action
40
     * @return array
41
     */
42
    private function getParameterMatching(\object $controller, string $action) : array
43
    {
44 7
        $parameters = [];
45
        $reflection = new \ReflectionMethod($controller, $action);
46 7
        foreach ($reflection->getParameters() as $param) {
47
            if (isset($_REQUEST[$param->name])) {
48
                $parameters[$param->name] = $_REQUEST[$param->name];
49
            }
50
        }
51
        return $parameters;
52
    }
53 10
54
    /**
55 10
     * Return Controller instance from a controller name
56 10
     * @param string $controllerName
57 10
     * @return object
58
     * @throws \Exception
59
     */
60
    private function getControllerFromName(string $controllerName)
61
    {
62
        $controller = $this->projectNamespace . $this->controllerPackage . '\\' . ucfirst($controllerName);
63
        if (!class_exists($controller)) {
64 10
            throw new \Exception('controller ' . $controllerName . ' not found');
65
        }
66 10
        return new $controller;
67 10
    }
68 10
69 10
    /**
70
     * Return HTTP Method for request
71
     * @return string
72
     */
73
    private function getVerbFromRequest() : string
74
    {
75
        return isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'get';
76
    }
77 4
78
    /**
79 4
     * Returns Request uri without query string
80 4
     * @return string
81
     */
82
    private function getQuery() : string
83
    {
84
        $requestUri = $_SERVER['REQUEST_URI'];
85
        $appendUri = strpos($requestUri, '?');
86
        return substr($requestUri, 0, $appendUri === false ? strlen($requestUri) : $appendUri);
87
    }
88 5
89
    /**
90 5
     * Determine controller and action from Request Uri
91 2
     * @return array
92 3
     */
93 5
    private function getControllerAndAction() : array
94
    {
95
        $parts = explode('/', preg_replace('~^' . Basepath::get() . '~', '', $this->getQuery()));
96
        $action = count($parts) >= 2 ? array_pop($parts) : 'index';
97
        $controllerName = isset($parts[0]) && $parts[0] ? implode($parts, '\\') : 'index';
98
        return [$controllerName, $action ?: 'index'];
99
    }
100
101 3
    /**
102
     * Redefine personal namespace
103 3
     * @param string $namespace
104 3
     * @return Framework
105
     */
106
    public function setNamespace(string $namespace = '\Project') : Framework
107
    {
108
        $this->projectNamespace = strlen($namespace) && $namespace{0} != '\\' ? '\\' . $namespace : $namespace;
109
        return $this;
110
    }
111
112
    /**
113
     * Redefine controller subpackage
114
     * @param string $controllerPackage
115
     * @return Framework
116
     */
117
    public function setControllerPackage(string $controllerPackage = '\Controller') : Framework
118
    {
119
        $this->controllerPackage = strlen($controllerPackage) && $controllerPackage{0} != '\\'
120
            ? '\\' . $controllerPackage
121
            : $controllerPackage;
122
        return $this;
123
    }
124
125
    /**
126
     * Redefine controller action suffix
127
     * @param string $suffix
128
     * @return Framework
129
     */
130
    public function setControllerActionSuffix(string $suffix = 'Action') : Framework
131
    {
132
        $this->controllerActionSuffix = (string)$suffix;
133
        return $this;
134
    }
135
136
    /**
137
     * Tells if we should use parameter matching for controllers
138
     * @param bool $active
139
     * @return Framework
140
     */
141
    public function setParameterMatching($active = true) : Framework
142
    {
143
        $this->withParameterMatching = (bool) $active;
144
        return $this;
145
    }
146
}
147