Passed
Push — master ( b9a9b1...3110e0 )
by Robson
01:44
created

RouterTrait::handler()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace CoffeeCode\Router;
4
5
trait RouterTrait
6
{
7
    /** @var array */
8
    protected $routes;
9
10
    /** @var string */
11
    protected $patch;
12
13
    /** @var string */
14
    protected $httpMethod;
15
16
    /**
17
     * @param string $name
18
     * @param array|null $data
19
     * @return string|null
20
     */
21
    public function route(string $name, array $data = null): ?string
22
    {
23
        foreach ($this->routes as $http_verb) {
24
            foreach ($http_verb as $route_item) {
25
                return $this->treat($name, $route_item, $data);
26
            }
27
        }
28
        return null;
29
    }
30
31
    /**
32
     * @param string $route
33
     * @param array|null $data
34
     */
35
    public function redirect(string $route, array $data = null): void
36
    {
37
        if ($name = $this->route($route, $data)) {
38
            header("Location: {$name}");
39
            exit;
40
        }
41
42
        if (filter_var($route, FILTER_VALIDATE_URL)) {
43
            header("Location: {$route}");
44
            exit;
45
        }
46
47
        $route = (substr($route, 0, 1) == "/" ? $route : "/{$route}");
48
        header("Location: {$this->projectUrl}{$route}");
49
        exit;
50
    }
51
52
    /**
53
     * @param string $method
54
     * @param string $route
55
     * @param string|callable $handler
56
     * @param null|string
57
     * @return Dispatch
58
     */
59
    protected function addRoute(string $method, string $route, $handler, string $name = null): RouterTrait
60
    {
61
        if ($route == "/") {
62
            $this->addRoute($method, "", $handler, $name);
63
        }
64
65
        preg_match_all("~\{\s* ([a-zA-Z_][a-zA-Z0-9_-]*) \}~x", $route, $keys, PREG_SET_ORDER);
66
        $routeDiff = array_values(array_diff(explode("/", $this->patch), explode("/", $route)));
67
68
        $this->formSpoofing();
0 ignored issues
show
Bug introduced by
It seems like formSpoofing() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
        $this->/** @scrutinizer ignore-call */ 
69
               formSpoofing();
Loading history...
69
        $offset = ($this->group ? 1 : 0);
70
        foreach ($keys as $key) {
71
            $this->data[$key[1]] = ($routeDiff[$offset++] ?? null);
0 ignored issues
show
Bug Best Practice introduced by
The property data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
72
        }
73
74
        $route = (!$this->group ? $route : "/{$this->group}{$route}");
75
        $data = $this->data;
76
        $namespace = $this->namespace;
77
        $router = function () use ($method, $handler, $data, $route, $name, $namespace) {
78
            return [
79
                "route" => $route,
80
                "name" => $name,
81
                "method" => $method,
82
                "handler" => $this->handler($handler, $namespace),
83
                "action" => $this->action($handler),
84
                "data" => $data
85
            ];
86
        };
87
88
        $route = preg_replace('~{([^}]*)}~', "([^/]+)", $route);
89
        $this->routes[$method][$route] = $router();
90
        return $this;
91
    }
92
93
    /**
94
     * @param $handler
95
     * @param $namespace
96
     * @return string|callable
97
     */
98
    private function handler($handler, $namespace)
99
    {
100
        return (!is_string($handler) ? $handler : "{$namespace}\\" . explode($this->separator, $handler)[0]);
101
    }
102
103
    /**
104
     * @param $handler
105
     * @return null|string
106
     */
107
    private function action($handler): ?string
108
    {
109
        return (!is_string($handler) ?: (explode($this->separator, $handler)[1] ?? null));
110
    }
111
112
    /**
113
     * @param string $name
114
     * @param array $route_item
115
     * @param array|null $data
116
     * @return string|null
117
     */
118
    private function treat(string $name, array $route_item, array $data = null): ?string
119
    {
120
        if (!empty($route_item["name"]) && $route_item["name"] == $name) {
121
            $route = $route_item["route"];
122
            if (!empty($data)) {
123
                $arguments = [];
124
                $params = [];
125
                foreach ($data as $key => $value) {
126
                    if (!strstr($route, "{{$key}}")) {
127
                        $params[$key] = $value;
128
                    }
129
                    $arguments["{{$key}}"] = $value;
130
                }
131
                $route = $this->process($route, $arguments, $params);
132
            }
133
            return "{$this->projectUrl}{$route}";
134
        }
135
        return null;
136
    }
137
138
    /**
139
     * @param string $route
140
     * @param array $arguments
141
     * @param array|null $params
142
     * @return string
143
     */
144
    private function process(string $route, array $arguments, array $params = null): string
145
    {
146
        $params = (!empty($params) ? "?" . http_build_query($params) : null);
147
        return str_replace(array_keys($arguments), array_values($arguments), $route) . "{$params}";
148
    }
149
}