Passed
Push — master ( a7647a...8305c3 )
by refat
03:28
created

Route::group()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 2
eloc 14
c 3
b 0
f 0
nc 2
nop 2
dl 0
loc 23
rs 9.7998
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
    $methods = ['GET', 'POST'];
219
220
    if (($method == 'both') && in_array($this->app->request->method(), $methods)) {
221
222
      return true;
223
    }
224
225
    if (is_array($method)) {
226
227
      if (count($method) == 1) {
228
229
        $method = $method[0];
230
231
      } else if (count($method) == 2) {
232
233
        if (in_array($method[0], $methods) && in_array($method[1], $methods)) {
234
235
          return true;
236
        }
237
238
      } else {
239
240
        return false;
241
      }
242
    }
243
244
    return $this->app->request->method() == $method;
245
  }
246
247
  public function getArgumentsFor($pattern)
248
  {
249
    $url = $this->app->request->url();
250
251
    preg_match($pattern, $url, $matches);
252
253
    array_shift($matches);
254
255
    return $matches;
256
  }
257
258
  public function getCurrent($key)
259
  {
260
    return $this->current[$key];
261
  }
262
263
  private function middleware($middleware, $from = 'admin')
264
  {
265
    $middlewareInterface = 'App\\Middleware\\MiddlewaresInterface';
266
267
    $middlewares = $this->app->alias['middlewares'][$from];
268
269
    $middlewareClass = $middlewares[$middleware];
270
271
    if (!in_array($middlewareInterface, class_implements($middlewareClass))) {
272
273
      throw new Exception("$middlewareClass not Implement");
274
    }
275
276
    $middlewareObject = new $middlewareClass;
277
278
    $output = $middlewareObject->handle($this->app, static::NEXT);
279
280
    if ($output && $output === static::NEXT) {
281
282
      $output = '';
283
    }
284
285
    return $output;
286
  }
287
}