Passed
Branch master (93b6ae)
by refat
12:48
created

Route::getProperRoute()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 10
c 2
b 0
f 0
nc 4
nop 0
dl 0
loc 21
rs 9.9332
1
<?php
2
3
namespace System;
4
5
class Route
6
{
7
  private $app;
8
9
  private $routes = [];
10
11
  public $current = [];
12
13
  private $prefix;
14
15
  private $basController;
16
17
  private $groupMiddleware = [];
18
19
  public function __construct(Application $app)
20
  {
21
    $this->app = $app;
22
  }
23
24
  public function add($url, $action, $requestMethods = ['GET'], $middleware = [])
25
  {
26
    $url = $this->setPrefix($url);
27
    $action = $this->setAction($action);
28
    $middleware = $this->setMiddleware($middleware);
29
    $routes = [
30
      'url' => $url,
31
      'pattern' => $this->generatePattern($url),
32
      'action' => $this->getAction($action),
33
      'method' => $requestMethods,
34
      'middleware' => $middleware
35
    ];
36
37
    $this->routes[] = $routes;
38
39
    return $this;
40
  }
41
42
  private function setPrefix($url)
43
  {
44
    if ($this->prefix && $this->prefix !== '/') {
45
46
      $url = $this->prefix . $url;
47
      $url = rtrim($url, '/');
48
    }
49
50
    return $url;
51
  }
52
53
  private function setAction($action)
54
  {
55
    if ($this->basController) {
56
57
      $action = $this->basController . '/' . $action;
58
    }
59
    return $action;
60
  }
61
62
  private function setMiddleware($middleware)
63
  {
64
    if (!is_array($middleware)) {
65
66
      $middleware = [$middleware];
67
    }
68
69
    $middleware = array_merge($this->groupMiddleware, $middleware);
70
71
    return $middleware;
72
  }
73
74
  private function getAction($action)
75
  {
76
    $action = str_replace('/', '\\', $action);
77
    $action = (strpos($action, '@') != 0) ? $action : $action . '@index';
78
    $action = explode('@', $action);
79
80
    return $action;
81
  }
82
83
  private function generatePattern($url)
84
  {
85
    $pattern = '#^';
86
    $pattern .= str_replace([':text', ':id'], ['([a-zA-Z0-9-]+)', '(\d+)'], strtolower($url));
87
    $pattern .= '$#';
88
89
    return $pattern;
90
  }
91
92
  public function group($groupOptions, callable $callback)
93
  {
94
    $prefix = $groupOptions['prefix'];
95
    $controller = $groupOptions['controller'];
96
    $middleware = $groupOptions['middleware'];
97
    $url = $this->app->request->url();
98
99
    if (($this->prefix && $prefix !== $this->prefix) || ($prefix && strpos($url, $prefix) !== 0)) {
100
101
      return $this;
102
    }
103
104
    $this->prefix = $prefix;
105
106
    $this->basController = $controller;
107
108
    $this->groupMiddleware = $middleware;
109
110
    $callback($this);
111
112
    return $this;
113
  }
114
115
  public function package($url, $controller, $middlewares = [])
116
  {
117
    $this->add($url, $controller);
118
    $row = isset($middlewares['row']) ? $middlewares['row'] : [];
119
120
    $this->add("$url/:id", "$controller@row", 'GET', $row);
121
    $new = isset($middlewares['new']) ? $middlewares['new'] : [];
122
123
    $this->add("$url/new", "$controller@new", 'GET', $new);
124
    $add = isset($middlewares['add']) ? $middlewares['add'] : [];
125
126
    $this->add("$url/add", "$controller@add", 'POST', $add);
127
    $update = isset($middlewares['update']) ? $middlewares['update'] : [];
128
129
    $this->add("$url/update/:id", "$controller@update", 'POST', $update);
130
    $delete = isset($middlewares['delete']) ? $middlewares['delete'] : [];
131
132
    $this->add("$url/delete/:id", "$controller@delete", 'POST', $delete);
133
134
    return $this;
135
  }
136
137
  public function getProperRoute()
138
  {
139
    foreach ($this->routes as $route) {
140
141
      if ($this->fullMatch($route['pattern'], $route['method'])) {
142
143
        $this->current = $route;
144
145
        $continue = $this->app->request->canRequestContinue($route['middleware']);
146
147
        if ($continue) {
148
          list($controller, $method) = $route['action'];
149
150
          $arguments = $this->getArgumentsFor($route['pattern']);
151
152
          return (string) $this->app->load->action($controller, $method, $arguments);
153
        }
154
        break;
155
      }
156
    }
157
    return notFoundPage();
158
  }
159
160
  private function fullMatch($pattern, $methods)
161
  {
162
    return $this->isMatchingPattern($pattern) &&  $this->app->request->isMatchingRequestMethod($methods);
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 getArgumentsFor($pattern)
174
  {
175
    $url = $this->app->request->url();
176
177
    preg_match($pattern, $url, $matches);
178
179
    array_shift($matches);
180
181
    return $matches;
182
  }
183
184
  public function getCurrent($key)
185
  {
186
    return $this->current[$key];
187
  }
188
}
189