Passed
Push — master ( e8f5c9...c45c7a )
by refat
06:21 queued 02:17
created

Route::package()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 10
rs 10
1
<?php
2
3
namespace System;
4
5
use Exception;
6
7
class Route
8
{
9
  const NEXT = '_NEXT_';
10
11
  private $app;
12
13
  private $routes = [];
14
15
  public $current = [];
16
17
  private $prefix;
18
19
  private $basController;
20
21
  private $middlewareFrom;
22
23
  private $groupMiddleware = [];
24
25
  public function __construct(Application $app)
26
  {
27
    $this->app = $app;
28
  }
29
30
  public function add($url, $action, $requestMethos = 'GET', $middleware = [])
31
  {
32
    $url = $this->setPrefix($url);
33
34
    $action = $this->setAction($action);
35
36
    $middleware = $this->setMiddleware($middleware);
37
38
    $routes = [
39
      'url'         => $url,
40
      'pattern'     => $this->generatePattern($url),
41
      'action'      => $this->getAction($action),
42
      'method'      => $requestMethos,
43
      'middleware'  => $middleware
44
    ];
45
46
    $this->routes[] = $routes;
47
48
    return $this;
49
  }
50
51
  private function setPrefix($url)
52
  {
53
    if ($this->prefix) {
54
55
      if ($this->prefix !== '/') {
56
57
        $url = $this->prefix . $url;
58
59
        $url = rtrim($url, '/');
60
      }
61
    }
62
63
    return $url;
64
  }
65
66
  private function setAction($action)
67
  {
68
    if ($this->basController) {
69
70
      $action = $this->basController . '/' . $action;
71
    }
72
73
    return $action;
74
  }
75
76
  private function setMiddleware($middleware)
77
  {
78
    if (!empty($this->groupMiddleware)) {
79
80
      if (is_array($middleware)) {
81
82
        $middleware = array_merge($this->groupMiddleware[0], $middleware);
83
84
      } else {
85
86
        array_push($this->groupMiddleware[0], $middleware);
87
88
        $middleware = $this->groupMiddleware[0];
89
      }
90
    }
91
92
    return $middleware;
93
  }
94
95
  public function group($groupOptions, callable $callback)
96
  {
97
    $prefix = $groupOptions['prefix'];
98
    $controller = $groupOptions['controller'];
99
    $middlewareFrom = array_shift($groupOptions['middleware']);
100
    $middleware = $groupOptions['middleware'];
101
102
    $url = ltrim($this->app->request->url(), '/');
103
    $check = '/' . explode('/', $url)[0];
104
105
    if ($check !== $prefix) {
106
107
      return $this;
108
    }
109
110
    $this->prefix = $prefix;
111
    $this->basController = $controller;
112
    $this->middlewareFrom = $middlewareFrom;
113
    $this->groupMiddleware = $middleware;
114
115
    $callback($this);
116
117
    return $this;
118
  }
119
120
  public function package($url, $controller)
121
  {
122
    $this->add("$url", "$controller");
123
    $this->add("$url/add", "$controller@add", "POST");
124
    $this->add("$url/submit", "$controller@submit", "POST");
125
    $this->add("$url/edit/:id", "$controller@edit", "POST");
126
    $this->add("$url/save/:id", "$controller@save", "POST");
127
    $this->add("$url/delete/:id", "$controller@delete", "POST");
128
129
    return $this;
130
  }
131
132
  public function generatePattern($url)
133
  {
134
    $pattern = '#^';
135
    $pattern .= str_replace([':text', ':id'], ['([a-zA-Z0-9-]+)', '(\d+)'], strtolower($url));
136
    $pattern .= '$#';
137
138
    return $pattern;
139
  }
140
141
  public function getAction($action)
142
  {
143
    $action = str_replace('/', '\\', $action);
144
145
    $action = (strpos($action, '@') != 0) ? $action : $action . '@index';
146
147
    $action = explode('@', $action);
148
149
    return $action;
150
  }
151
152
  public function getProperRoute()
153
  {
154
    foreach ($this->routes as $route) {
155
156
      if ($this->isMatching($route['pattern']) && $this->isMatchingRequestMethod($route['method'])) {
157
158
        $this->current = $route;
159
160
        $output = '';
161
162
        if ($route['middleware']) {
163
164
          if (is_array($route['middleware'])) {
165
166
            foreach ($route['middleware'] as $middleware) {
167
168
              $output = $this->middleware($middleware);
169
170
              if ($output != '') {
171
172
                break;
173
              }
174
            }
175
176
          } else {
177
178
            $output = $this->middleware($route['middleware']);
179
180
            if ($output != '') {
181
182
              break;
183
            }
184
          }
185
        }
186
187
        if ($output == '') {
188
189
          list($controller, $method) = $route['action'];
190
191
          $arguments = $this->getArgumentsFor($route['pattern']);
192
193
          $output = (string) $this->app->load->action($controller, $method, $arguments);
194
195
          return $output;
196
        }
197
198
        break;
199
      }
200
    }
201
202
    $output = (string) $this->app->load->action('notFound', 'index', []);
203
204
    return $output;
205
  }
206
207
  public function isMatching($pattern)
208
  {
209
    $url = $this->app->request->url();
210
211
    $url = strtolower($url);
212
213
    return preg_match($pattern, $url);
214
  }
215
216
  private function isMatchingRequestMethod($method)
217
  {
218
    $allowMethods = ['GET', 'POST'];
219
220
    if ($method == 'BOTH') {
221
222
      return $this->checkRequestMethodsBoth($allowMethods);
223
    }
224
225
    if (is_array($method)) {
226
227
      return $this->checkRequestMethodsArray($method, $allowMethods);
228
    }
229
230
    return $this->app->request->method() == $method;
231
  }
232
233
  private function checkRequestMethodsArray($methods = null, $allowMethods)
234
  {
235
    if (count($methods) == 1) {
236
237
      return $this->app->request->method() == $methods[0];
238
239
    } else {
240
241
      if (array_equal($methods, $allowMethods)) {
242
243
        return true;
244
      }
245
246
      return false;
247
    }
248
  }
249
250
  private function checkRequestMethodsBoth($allowMethods)
251
  {
252
    if (in_array($this->app->request->method(), $allowMethods)) {
253
254
      return true;
255
    }
256
257
    return false;
258
  }
259
260
  public function getArgumentsFor($pattern)
261
  {
262
    $url = $this->app->request->url();
263
264
    preg_match($pattern, $url, $matches);
265
266
    array_shift($matches);
267
268
    return $matches;
269
  }
270
271
  public function getCurrent($key)
272
  {
273
    return $this->current[$key];
274
  }
275
276
  private function middleware($middleware)
277
  {
278
    $middlewareInterface = 'App\\Middleware\\MiddlewaresInterface';
279
280
    $middlewares = $this->app->alias['middlewares'];
281
282
    $middlewareClass = $middlewares[$middleware];
283
284
    if (!in_array($middlewareInterface, class_implements($middlewareClass))) {
285
286
      throw new Exception("$middlewareClass not Implement");
287
    }
288
289
    $middlewareObject = new $middlewareClass;
290
291
    $output = $middlewareObject->handle($this->app, static::NEXT);
292
293
    if ($output && $output === static::NEXT) {
294
295
      $output = '';
296
    }
297
298
    return $output;
299
  }
300
}