Issues (14)

src/RouterTrait.php (2 issues)

1
<?php
2
3
namespace SimpSyst\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
                if (!empty($route_item["name"]) && $route_item["name"] == $name) {
26
                    return $this->treat($route_item, $data);
27
                }
28
            }
29
        }
30
        return null;
31
    }
32
33
    /**
34
     * @param string $route
35
     * @param array|null $data
36
     */
37
    public function redirect(string $route, array $data = null): void
38
    {
39
        if ($name = $this->route($route, $data)) {
40
            header("Location: {$name}");
41
            exit;
42
        }
43
44
        if (filter_var($route, FILTER_VALIDATE_URL)) {
45
            header("Location: {$route}");
46
            exit;
47
        }
48
49
        $route = (substr($route, 0, 1) == "/" ? $route : "/{$route}");
50
        header("Location: {$this->projectUrl}{$route}");
51
        exit;
52
    }
53
54
    /**
55
     * @param string $method
56
     * @param string $route
57
     * @param string|callable $handler
58
     * @param null|string
59
     */
60
    protected function addRoute(string $method, string $route, $handler, string $name = null): void
61
    {
62
        if ($route == "/") {
63
            $this->addRoute($method, "", $handler, $name);
64
        }
65
66
        preg_match_all("~\{\s* ([a-zA-Z_][a-zA-Z0-9_-]*) \}~x", $route, $keys, PREG_SET_ORDER);
67
        $routeDiff = array_values(array_diff(explode("/", $this->patch), explode("/", $route)));
68
69
        $this->formSpoofing();
0 ignored issues
show
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

69
        $this->/** @scrutinizer ignore-call */ 
70
               formSpoofing();
Loading history...
70
        $offset = ($this->group ? 1 : 0);
71
        foreach ($keys as $key) {
72
            $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...
73
        }
74
75
        $route = (!$this->group ? $route : "/{$this->group}{$route}");
76
        $data = $this->data;
77
        $namespace = $this->namespace;
78
        $router = function () use ($method, $handler, $data, $route, $name, $namespace) {
79
            return [
80
                "route" => $route,
81
                "name" => $name,
82
                "method" => $method,
83
                "handler" => $this->handler($handler, $namespace),
84
                "action" => $this->action($handler),
85
                "data" => $data
86
            ];
87
        };
88
89
        $route = preg_replace('~{([^}]*)}~', "([^/]+)", $route);
90
        $this->routes[$method][$route] = $router();
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 array $route_item
114
     * @param array|null $data
115
     * @return string|null
116
     */
117
    private function treat(array $route_item, array $data = null): ?string
118
    {
119
        $route = $route_item["route"];
120
        if (!empty($data)) {
121
            $arguments = [];
122
            $params = [];
123
            foreach ($data as $key => $value) {
124
                if (!strstr($route, "{{$key}}")) {
125
                    $params[$key] = $value;
126
                }
127
                $arguments["{{$key}}"] = $value;
128
            }
129
            $route = $this->process($route, $arguments, $params);
130
        }
131
132
        return "{$this->projectUrl}{$route}";
133
    }
134
135
    /**
136
     * @param string $route
137
     * @param array $arguments
138
     * @param array|null $params
139
     * @return string
140
     */
141
    private function process(string $route, array $arguments, array $params = null): string
142
    {
143
        $params = (!empty($params) ? "?" . http_build_query($params) : null);
144
        return str_replace(array_keys($arguments), array_values($arguments), $route) . "{$params}";
145
    }
146
}