Router   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 53
dl 0
loc 182
rs 10
c 0
b 0
f 0
wmc 20

10 Methods

Rating   Name   Duplication   Size   Complexity  
A post() 0 3 1
A delete() 0 3 1
A get() 0 3 1
A addRoute() 0 21 4
A put() 0 3 1
A setPrefix() 0 5 1
A run() 0 20 4
A getUri() 0 7 2
A __construct() 0 5 1
A getRoute() 0 22 4
1
<?php
2
3
namespace MarcolaMr\Router;
4
5
use \Closure;
0 ignored issues
show
Bug introduced by
The type \Closure was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use \Exception;
0 ignored issues
show
Bug introduced by
The type \Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Reflection;
8
use \ReflectionFunction;
0 ignored issues
show
Bug introduced by
The type \ReflectionFunction was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
class Router
11
{
12
    /** @var string */
13
    private string $url = "";
14
15
    /** @var string */
16
    private string $prefix = "";
17
18
    /** @var array */
19
    private array $routes = [];
20
21
    /** @var Request */
22
    private Request $request;
23
24
    /**
25
     * Construtor da classe
26
     *
27
     * @param string $url
28
     */
29
    public function __construct(string $url)
30
    {
31
        $this->request = new Request();
32
        $this->url = $url;
33
        $this->setPrefix();
34
    }
35
36
    /**
37
     * Método responsável por definir uma rota de GET
38
     *
39
     * @param string $route
40
     * @param array $params
41
     */
42
    public function get(string $route, array $params = [])
43
    {
44
        return $this->addRoute("GET", $route, $params);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->addRoute('GET', $route, $params) targeting MarcolaMr\Router\Router::addRoute() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
45
    }
46
47
    /**
48
     * Método responsável por definir uma rota de POST
49
     *
50
     * @param string $route
51
     * @param array $params
52
     */
53
    public function post(string $route, array $params = [])
54
    {
55
        return $this->addRoute("POST", $route, $params);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->addRoute('POST', $route, $params) targeting MarcolaMr\Router\Router::addRoute() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
56
    }
57
58
    /**
59
     * Método responsável por definir uma rota de PUT
60
     *
61
     * @param string $route
62
     * @param array $params
63
     */
64
    public function put(string $route, array $params = [])
65
    {
66
        return $this->addRoute("PUT", $route, $params);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->addRoute('PUT', $route, $params) targeting MarcolaMr\Router\Router::addRoute() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
67
    }
68
69
    /**
70
     * Método responsável por definir uma rota de DELETE
71
     *
72
     * @param string $route
73
     * @param array $params
74
     */
75
    public function delete(string $route, array $params = [])
76
    {
77
        return $this->addRoute("DELETE", $route, $params);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->addRoute('DELETE', $route, $params) targeting MarcolaMr\Router\Router::addRoute() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
78
    }
79
80
    /**
81
     * Método responsável por executar a rota atual
82
     *
83
     * @return Response
84
     */
85
    public function run(): Response
86
    {
87
        try {
88
            $route = $this->getRoute();
89
            
90
            if (!isset($route["controller"])) {
91
                throw new Exception("A url não pôde ser processada", 500);
92
            }
93
94
            $args = [];
95
96
            $reflection = new ReflectionFunction($route["controller"]);
97
            foreach ($reflection->getParameters() as $parameter) {
98
                $name = $parameter->getName();
99
                $args[$name] = $route["variables"][$name] ?? "";
100
            }
101
            
102
            return call_user_func_array($route["controller"], $args);
103
        } catch (Exception $e) {
104
            return new Response($e->getCode(), $e->getMessage());
105
        }
106
    }
107
108
    /**
109
     * Método responsável por retornar os dados da rota atual
110
     *
111
     * @return
112
     */
113
    private function getRoute()
114
    {
115
        $uri = $this->getUri();
116
        $httpMethod = $this->request->getHttpMethod();
117
        
118
        foreach ($this->routes as $patternRoute => $methods) {
119
            if (preg_match($patternRoute, $uri, $matches)) {
120
                if (isset($methods[$httpMethod])) {
121
                    unset($matches[0]);
122
123
                    $keys = $methods[$httpMethod]["variables"];
124
                    $methods[$httpMethod]["variables"] = array_combine($keys, $matches);
125
                    $methods[$httpMethod]["variables"]["request"] = $this->request;
126
127
                    return $methods[$httpMethod];
128
                }
129
130
                throw new Exception("Método não implementado", 405);
131
            }
132
        }
133
134
        throw new Exception("Url não encontrada", 404);
135
    }
136
137
    /**
138
     * Método responsável por retornar a URI desconsiderando o prefixo
139
     *
140
     * @return string
141
     */
142
    private function getUri(): string
143
    {
144
        $uri = $this->request->getUri();
145
        
146
        $xUri = strlen($this->prefix) ? explode($this->prefix, $uri) : [$uri];
147
148
        return end($xUri);
149
    }
150
151
    /**
152
     * Método responsável por adicionar uma rota na classe
153
     *
154
     * @param string $method
155
     * @param string $route
156
     * @param array $params
157
     * @return void
158
     */
159
    private function addRoute(string $method, string $route, array $params = []): void
160
    {
161
        foreach ($params as $key => $value) {
162
            if ($value instanceof Closure) {
163
                $params["controller"] = $value;
164
                unset($params[$key]);
165
                continue;
166
            }
167
        }
168
169
        //Variáveis da Rota
170
        $params["variables"] = [];
171
        $patternVariable = "/{(.*?)}/";
172
        if (preg_match_all($patternVariable, $route, $matches)) {
173
            $route = preg_replace($patternVariable, "(.*?)", $route);
174
            $params["variables"] = $matches[1];
175
        }
176
177
        $patternRoute = "/^" . str_replace("/", "\/", $route) . "$/";
178
179
        $this->routes[$patternRoute][$method] = $params;
180
    }
181
182
    /**
183
     * Método responsável por definir o prefixo das rotas
184
     *
185
     * @return void
186
     */
187
    private function setPrefix(): void
188
    {
189
        $parseUrl = parse_url($this->url);
190
        
191
        $this->prefix = $parseUrl["path"] ?? "";
192
    }
193
}
194