Passed
Pull Request — master (#42)
by
unknown
01:50
created

Dispatch::group()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace CoffeeCode\Router;
4
5
/**
6
 * Class CoffeeCode Dispatch
7
 *
8
 * @author Robson V. Leite <https://github.com/robsonvleite>
9
 * @package CoffeeCode\Router
10
 */
11
abstract class Dispatch
12
{
13
    use RouterTrait;
14
15
    /** @var null|array */
16
    protected $route;
17
18
    /** @var bool|string */
19
    protected $projectUrl;
20
21
    /** @var string */
22
    protected $separator;
23
24
    /** @var null|string */
25
    protected $namespace;
26
27
    /** @var null|string */
28
    protected $group;
29
30
    /** @var null|array */
31
    protected $data;
32
33
    /** @var int */
34
    protected $error;
35
36
    /** @const int Bad Request */
37
    public const BAD_REQUEST = 400;
38
39
    /** @const int Not Found */
40
    public const NOT_FOUND = 404;
41
42
    /** @const int Method Not Allowed */
43
    public const METHOD_NOT_ALLOWED = 405;
44
45
    /** @const int Not Implemented */
46
    public const NOT_IMPLEMENTED = 501;
47
48
    /**
49
     * Dispatch constructor.
50
     *
51
     * @param string $projectUrl
52
     * @param null|string $separator
53
     */
54
    public function __construct(string $projectUrl, ?string $separator = ":")
55
    {
56
        $this->projectUrl = (substr($projectUrl, "-1") == "/" ? substr($projectUrl, 0, -1) : $projectUrl);
57
        $this->patch = (filter_input(INPUT_GET, "route", FILTER_DEFAULT) ?? "/");
58
        $this->separator = ($separator ?? ":");
59
        $this->httpMethod = $_SERVER['REQUEST_METHOD'];
60
    }
61
62
    /**
63
     * @return array
64
     */
65
    public function __debugInfo()
66
    {
67
        return $this->routes;
68
    }
69
70
    /**
71
     * @param null|string $namespace
72
     * @return Dispatch
73
     */
74
    public function namespace(?string $namespace): Dispatch
75
    {
76
        $this->namespace = ($namespace ? ucwords($namespace) : null);
77
        return $this;
78
    }
79
80
    /**
81
     * @param null|string $group
82
     * @return Dispatch
83
     */
84
    public function group(?string $group): Dispatch
85
    {
86
        $this->group = ($group ? str_replace("/", "", $group) : null);
87
        return $this;
88
    }
89
90
    /**
91
     * @return null|array
92
     */
93
    public function request(): ?array
94
    {
95
        return $this->route;
96
    }
97
98
    /**
99
     * @return null|array
100
     */
101
    public function data(): ?array
102
    {
103
        return $this->data;
104
    }
105
106
    /**
107
     * @return null|int
108
     */
109
    public function error(): ?int
110
    {
111
        return $this->error;
112
    }
113
114
    /**
115
     * @return bool
116
     */
117
    public function dispatch(): bool
118
    {
119
        if (empty($this->routes) || empty($this->routes[$this->httpMethod])) {
120
            $this->error = self::NOT_IMPLEMENTED;
121
            return false;
122
        }
123
124
        $this->route = null;
125
        foreach ($this->routes[$this->httpMethod] as $key => $route) {
126
            if (preg_match("~^" . $key . "$~", $this->patch, $found)) {
127
                $this->route = $route;
128
            }
129
        }
130
131
        return $this->execute();
132
    }
133
134
    /**
135
     * @return bool
136
     */
137
    private function execute()
138
    {
139
        if ($this->route) {
140
            if (is_callable($this->route['handler'])) {
141
                call_user_func($this->route['handler'], ($this->route['data'] ?? []));
142
                return true;
143
            }
144
145
            $controller = $this->route['handler'];
146
            $method = $this->route['action'];
147
148
            if (class_exists($controller)) {
149
                $newController = new $controller($this->route);
150
                if (method_exists($controller, $method)) {
151
                    $newController->$method(($this->route['data'] ?? []));
152
                    return true;
153
                }
154
155
                $this->error = self::METHOD_NOT_ALLOWED;
156
                return false;
157
            }
158
159
            $this->error = self::BAD_REQUEST;
160
            return false;
161
        }
162
163
        $this->error = self::NOT_FOUND;
164
        return false;
165
    }
166
167
    /**
168
     * httpMethod form spoofing
169
     */
170
    protected function formSpoofing(): void
171
    {
172
        $post = filter_input_array(INPUT_POST, FILTER_DEFAULT);
173
174
        if (!empty($post['_method']) && in_array($post['_method'], ["PUT", "PATCH", "DELETE"])) {
175
            $this->httpMethod = $post['_method'];
176
            $this->data = $post;
177
178
            unset($this->data["_method"]);
179
            return;
180
        }
181
182
        if ($this->httpMethod == "POST") {
183
            $this->data = filter_input_array(INPUT_POST, FILTER_DEFAULT);
184
185
            unset($this->data["_method"]);
186
            return;
187
        }
188
189
        if (in_array($this->httpMethod, ["PUT", "PATCH", "DELETE"]) && !empty($_SERVER['CONTENT_LENGTH'])) {
190
            parse_str(file_get_contents('php://input', false, null, 0, $_SERVER['CONTENT_LENGTH']), $putPatch);
191
            $this->data = $putPatch;
192
193
            unset($this->data["_method"]);
194
            return;
195
        }
196
197
        /* added by Beto Campoy */
198
        if ($this->httpMethod == "GET") {
199
            $queryString = filter_var(str_replace('?', "", strstr($_SERVER['REQUEST_URI'], "?")), FILTER_SANITIZE_STRIPPED);
200
            parse_str($queryString, $data);
201
202
            $this->data = $data;
203
204
            unset($this->data["_method"]);
205
            return;
206
        }
207
        /* added by Beto Campoy */
208
209
        $this->data = [];
210
        return;
211
    }
212
}