Passed
Branch master (b57df4)
by refat
04:17
created

Route::notFound()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 8
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 $groupMiddleware = [];
22
23
  public function __construct(Application $app)
24
  {
25
    $this->app = $app;
26
  }
27
28
  public function add($url, $action, $requestMethos = 'GET', $middleware = [])
29
  {
30
    $url = $this->setPrefix($url);
31
32
    $action = $this->setAction($action);
33
34
    $middleware = $this->setMiddleware($middleware);
35
36
    $routes = [
37
      'url'         => $url,
38
      'pattern'     => $this->generatePattern($url),
39
      'action'      => $this->getAction($action),
40
      'method'      => $requestMethos,
41
      'middleware'  => $middleware
42
    ];
43
    $this->routes[] = $routes;
44
45
    return $this;
46
  }
47
48
  private function setPrefix($url)
49
  {
50
    if ($this->prefix && $this->prefix !== '/') {
51
      $url = $this->prefix . $url;
52
      $url = rtrim($url, '/');
53
    }
54
    return $url;
55
  }
56
57
  private function setAction($action)
58
  {
59
    if ($this->basController) $action = $this->basController . '/' . $action;
60
61
    return $action;
62
  }
63
64
  private function setMiddleware($middleware)
65
  {
66
    if (!is_array($middleware)) $middleware = [$middleware];
67
    $middleware = array_merge($this->groupMiddleware, $middleware);
68
    return $middleware;
69
  }
70
71
  public function group($groupOptions, callable $callback)
72
  {
73
    $prefix = $groupOptions['prefix'];
74
    $controller = $groupOptions['controller'];
75
    $middleware = $groupOptions['middleware'];
76
77
    $url = $this->app->request->url();
78
79
    if (($this->prefix && $prefix !== $this->prefix) || ($prefix && strpos($url, $prefix) !== 0)) {
80
      return $this;
81
    }
82
    $this->prefix = $prefix;
83
    $this->basController = $controller;
84
    $this->groupMiddleware = $middleware;
85
86
    $callback($this);
87
88
    return $this;
89
  }
90
91
  public function package($url, $controller, $middlewares = [])
92
  {
93
    $this->add($url, $controller);
94
95
    $row = isset($middlewares['row']) ? $middlewares['row'] : [];
96
    $this->add("$url/:id", "$controller@row", 'GET', $row);
97
98
    $new = isset($middlewares['new']) ? $middlewares['new'] : [];
99
    $this->add("$url/new", "$controller@new", 'GET', $new);
100
101
    $add = isset($middlewares['add']) ? $middlewares['add'] : [];
102
    $this->add("$url/add", "$controller@add", 'POST', $add);
103
104
    $update = isset($middlewares['update']) ? $middlewares['update'] : [];
105
    $this->add("$url/update/:id", "$controller@update", 'POST', $update);
106
107
    $delete = isset($middlewares['delete']) ? $middlewares['delete'] : [];
108
    $this->add("$url/delete/:id", "$controller@delete", 'POST', $delete);
109
110
    return $this;
111
  }
112
113
  public function generatePattern($url)
114
  {
115
    $pattern = '#^';
116
    $pattern .= str_replace([':text', ':id'], ['([a-zA-Z0-9-]+)', '(\d+)'], strtolower($url));
117
    $pattern .= '$#';
118
    return $pattern;
119
  }
120
121
  public function getAction($action)
122
  {
123
    $action = str_replace('/', '\\', $action);
124
    $action = (strpos($action, '@') != 0) ? $action : $action . '@index';
125
    $action = explode('@', $action);
126
    return $action;
127
  }
128
129
  public function getProperRoute()
130
  {
131
    foreach ($this->routes as $route) {
132
      if ($this->fullMatch($route['pattern'], $route['method'])) {
133
        $this->current = $route;
134
135
        $continue = $this->continue($route['middleware']);
136
137
        if ($continue == static::NEXT) {
138
          list($controller, $method) = $route['action'];
139
140
          $arguments = $this->getArgumentsFor($route['pattern']);
141
142
          return (string) $this->app->load->action($controller, $method, $arguments);
143
        }
144
        break;
145
      }
146
    }
147
    return $this->notFound();
148
  }
149
150
  private function notFound()
151
  {
152
    $notfound = 'Website\Notfound';
153
154
    if ($this->app->request->isRequestToAdminManagement() && $this->app->load->model('Login')->isLogged()) {
155
      $notfound = 'Admin\Notfound';
156
    }
157
    return (string) $this->app->load->action($notfound, 'index', []);
158
  }
159
160
  private function fullMatch($pattern, $method)
161
  {
162
    return $this->isMatchingPattern($pattern) && $this->isMatchingRequestMethod($method);
163
  }
164
165
  private function isMatchingPattern($pattern)
166
  {
167
    $url = $this->app->request->url();
168
    $url = strtolower($url);
169
170
    return preg_match($pattern, $url);
171
  }
172
173
  private function isMatchingRequestMethod($method)
174
  {
175
    $allowMethods = ['GET', 'POST'];
176
177
    if ($method == 'BOTH') {
178
      return $this->checkRequestMethodsBoth($allowMethods);
179
    }
180
181
    if (is_array($method)) {
182
      return $this->checkRequestMethodsArray($method, $allowMethods);
183
    }
184
    return $this->app->request->method() == $method;
185
  }
186
187
  private function checkRequestMethodsArray($methods = null, $allowMethods)
188
  {
189
    if (count($methods) == 1) {
190
      return $this->app->request->method() == $methods[0];
191
    } else {
192
      if (array_equal($methods, $allowMethods)) {
193
        return true;
194
      }
195
      return false;
196
    }
197
  }
198
199
  private function checkRequestMethodsBoth($allowMethods)
200
  {
201
    if (in_array($this->app->request->method(), $allowMethods)) {
202
      return true;
203
    }
204
    return false;
205
  }
206
207
  public function getArgumentsFor($pattern)
208
  {
209
    $url = $this->app->request->url();
210
211
    preg_match($pattern, $url, $matches);
212
213
    array_shift($matches);
214
215
    return $matches;
216
  }
217
218
  public function getCurrent($key)
219
  {
220
    return $this->current[$key];
221
  }
222
223
  private function middleware($middleware)
224
  {
225
    $middlewareInterface = 'App\Middlewares\MiddlewareIntrerface\MiddlewaresInterface';
226
227
    $middlewares = $this->app->file->call('config/alias.php')['middlewares'];
228
229
    $middlewareClass = $middlewares[$middleware];
230
231
    if (!in_array($middlewareInterface, class_implements($middlewareClass))) {
232
      throw new Exception("$middlewareClass not Implement");
233
    }
234
    $middlewareObject = new $middlewareClass;
235
236
    return $middlewareObject->handle($this->app, static::NEXT);
237
  }
238
239
  private function continue($middlewares)
240
  {
241
    if (!empty($middlewares)) {
242
      foreach ($middlewares as $middleware) {
243
        $output = $this->middleware($middleware);
244
245
        if ($output !== static::NEXT) {
246
          return $output;
247
        }
248
      }
249
    }
250
    return static::NEXT;
251
  }
252
}
253