Completed
Push — master ( 0b6473...8155cd )
by Edson
01:55
created

BaseRouter   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 28
dl 0
loc 122
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A handle() 0 9 4
A checkVerb() 0 7 2
A getById() 0 3 1
A add() 0 7 2
A getByName() 0 9 3
C parsePath() 0 32 7
A parseBrowserPath() 0 7 1
B checkPath() 0 19 6
1
<?php
2
3
namespace Router;
4
5
class BaseRouter
6
{
7
    private $path;
8
    private $verb;
9
    private $routes = [];
10
11
    public function __construct()
12
    {
13
        $this->verb = strtolower($_SERVER['REQUEST_METHOD']);
14
        $this->path = $this->parseBrowserPath($_SERVER['REQUEST_URI']);
15
        if (count($this->path) == 0) {
16
            $this->path[] = 'index';
17
        }
18
    }
19
20
    public function add(array $route): void
21
    {
22
        if ($route['uri'] == '/') {
23
            $route['uri'] = '/index';
24
        }
25
26
        $this->routes[] = new BaseRoute($route);
27
    }
28
29
    public function handle(): ?BaseRoute
30
    {
31
        foreach ($this->routes as $route) {
32
            if ($this->checkVerb($route) && $this->checkPath($route)) {
33
                return $route;
34
            }
35
        }
36
37
        die('<h1>ERROR 404: NOT FOUND</h1>');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
38
    }
39
40
    private function checkVerb(BaseRoute $route): bool
41
    {
42
        if ($this->verb != $route->getMethod()) {
43
            return false;
44
        }
45
46
        return true;
47
    }
48
49
    private function checkPath(BaseRoute $route): bool
50
    {
51
        if (!$this->parsePath($route)) {
52
            return false;
53
        }
54
55
        $routePath = $this->parseBrowserPath($route->getUri());
56
57
        if (count($routePath) != count($this->path)) {
58
            return false;
59
        }
60
61
        for ($i = 0; $i < count($routePath) && count($this->path); $i++) {
62
            if ($routePath[$i] != $this->path[$i]) {
63
                return false;
64
            }
65
        }
66
67
        return true;
68
    }
69
70
    private function parseBrowserPath(string $path): array
71
    {
72
        $path = explode('/', $path);
73
        $path = array_filter($path);
74
        $path = array_values($path);
75
76
        return $path;
77
    }
78
79
    private function parsePath(BaseRoute $route): bool
80
    {
81
        $path = $this->path;
82
        $routePath = $this->parseBrowserPath($route->getUri());
83
84
        for ($i = 0; $i < count($routePath); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
85
            $path[$i] = preg_replace('/\@.*/', $this->path[$i], $routePath[$i]);
86
            if ($path[$i] != $routePath[$i]) {
87
                // Regular expression matching
88
                if (preg_match('/\@([\w]+):(.*)/', $routePath[$i], $match)) {
89
                    if (preg_match('/'.$match[2].'/', $path[$i], $match[2])) {
90
                        if ($path[$i] != $match[2][0]) {
91
                            return false;
92
                        }
93
                        $route->setArg($match[1], $match[2][0]);
94
                    } else {
95
                        return false;
96
                    }
97
                } else {
98
                    $route->setArg(str_replace(':', '', $routePath[$i]), $path[$i]);
99
                }
100
            }
101
        }
102
103
        foreach ($_POST as $key => $value) {
104
            $route->setArg($key, $value);
105
        }
106
            
107
        $path = implode('/', $path);
108
        $route->setUri($path);
109
110
        return true;
111
    }
112
113
    public function getById($id): ?BaseRoute
114
    {
115
        return $this->routes[$id] ?? null;
116
    }
117
118
    public function getByName($name): ?BaseRoute
119
    {
120
        foreach ($this->routes as $route) {
121
            if ($route->getName() == $name) {
122
                return $route;
123
            }
124
        }
125
126
        return null;
127
    }
128
}
129