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

BaseRouter::parsePath()   C

Complexity

Conditions 7
Paths 10

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 32
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 19
nc 10
nop 1
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