Passed
Push — main ( 9cd52a...326916 )
by Moises
01:16
created

Route::execute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 15
rs 10
cc 3
nc 3
nop 0
1
<?php
2
3
namespace DevPontes\Route;
4
5
use DevPontes\Route\Exception\ErrorRoute;
6
7
/**
8
 * Description of Route
9
 *
10
 * @author Moises Pontes
11
 * @package DevPontes\Route
12
 */
13
class Route
14
{
15
    /** @var ErrorRoute */
16
    private $fail;
17
18
    /** @var string */
19
    private $param;
20
21
    /** @var array */
22
    private $routes;
23
24
    /** @var string */
25
    private $method;
26
27
    /** @var string */
28
    private $controller;
29
30
    /** @var string */
31
    private $namespace;
32
33
    /** @var array */
34
    private $url;
35
36
    /**
37
     * Route constructor.
38
     *
39
     * @param array $routes
40
     * @param array $error
41
     */
42
    public function __construct(array $routes)
43
    {
44
        $url = filter_input(INPUT_GET, 'url', FILTER_SANITIZE_SPECIAL_CHARS);
45
46
        $this->setUrl($url);
47
        $this->setRoutes($routes);
48
    }
49
50
    /**
51
     * @return ErrorRoute|null
52
     */
53
    public function fail(): ?ErrorRoute
54
    {
55
        return $this->fail;
56
    }
57
58
    /**
59
     * Set namespace app
60
     *
61
     * @param string $namespace
62
     * @return Route
63
     */
64
    public function namespace(string $namespace): Route
65
    {
66
        $this->namespace = $namespace;
67
        return $this;
68
    }
69
70
    /**
71
     * Separate the URL
72
     *
73
     * @param string|null $url
74
     * @return void
75
     */
76
    private function setUrl(?string $url): void
77
    {
78
        $url = "/" . $url;
79
        $this->url = explode('/', $url);
80
    }
81
82
    /**
83
     * Config the routes
84
     *
85
     * @param array $routes
86
     * @return void
87
     */
88
    private function setRoutes(array $routes): void
89
    {
90
        $this->routes = [];
91
92
        foreach ($routes as $route) {
93
            $dispatch = explode('@', $route[1]);
94
95
            $set = [
96
                "url"        => $route[0],
97
                "controller" => $dispatch[0],
98
                "method"     => $dispatch[1],
99
            ];
100
101
            array_push($this->routes, $set);
102
        }
103
    }
104
105
    /**
106
     * @param array $routeArr
107
     * @param string $route
108
     * @return void
109
     */
110
    private function setParam(array $routeArr, string &$route): void
111
    {
112
        foreach ($routeArr as $k => $v) {
113
            if (preg_match('/^\{.*\}$/', $v) && (count($this->url) == count($routeArr))) {
114
                $routeArr[$k] = $this->url[$k];
115
                $this->param  = $this->url[$k];
116
            }
117
118
            $route = implode('/', $routeArr);
119
        }
120
    }
121
122
    /**
123
     * Run the controller
124
     *
125
     * @return void
126
     */
127
    private function execute(): void
128
    {
129
        $controller = $this->namespace . "\\" . $this->controller;
130
131
        if (!class_exists($controller)) {
132
            $this->fail = new ErrorRoute("Class {$controller} not found", 501);
133
            return;
134
        }
135
136
        if (!method_exists($controller, $this->method)) {
137
            $this->fail = new ErrorRoute("Method {$this->method} not found", 405);
138
            return;
139
        }
140
141
        call_user_func([new $controller(), $this->method], $this->param);
142
    }
143
144
    /**
145
     * Run route
146
     *
147
     * @return void
148
     */
149
    public function run(): void
150
    {
151
        $url = implode('/', $this->url);
152
153
        foreach ($this->routes as $route) {
154
            $routeArray = explode('/', $route['url']);
155
            $this->setParam($routeArray, $route['url']);
156
157
            if ($route['url'] == $url) {
158
                $this->method = $route['method'];
159
                $this->controller = $route['controller'];
160
161
                $this->execute();
162
                return;
163
            }
164
        }
165
166
        $this->fail = new ErrorRoute("Page not found", 404);
167
    }
168
}
169