1
|
|
|
<?php namespace Comodojo\Dispatcher\Router; |
2
|
|
|
|
3
|
|
|
use \Comodojo\Components\Model as DispatcherClassModel; |
4
|
|
|
use \Comodojo\Dispatcher\Routes\RoutingTable; |
5
|
|
|
use \Comodojo\Dispatcher\Components\Timestamp as TimestampTrait; |
6
|
|
|
use \Comodojo\Dispatcher\Request\Model as Request; |
7
|
|
|
use \Comodojo\Dispatcher\Response\Model as Response; |
8
|
|
|
use \Comodojo\Dispatcher\Extra\Model as Extra; |
9
|
|
|
use \Comodojo\Dispatcher\Components\Configuration; |
10
|
|
|
use \Comodojo\Cache\CacheManager; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* @package Comodojo Dispatcher |
14
|
|
|
* @author Marco Giovinazzi <[email protected]> |
15
|
|
|
* @author Marco Castiello <[email protected]> |
16
|
|
|
* @license GPL-3.0+ |
17
|
|
|
* |
18
|
|
|
* LICENSE: |
19
|
|
|
* |
20
|
|
|
* This program is free software: you can redistribute it and/or modify |
21
|
|
|
* it under the terms of the GNU Affero General Public License as |
22
|
|
|
* published by the Free Software Foundation, either version 3 of the |
23
|
|
|
* License, or (at your option) any later version. |
24
|
|
|
* |
25
|
|
|
* This program is distributed in the hope that it will be useful, |
26
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
27
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28
|
|
|
* GNU Affero General Public License for more details. |
29
|
|
|
* |
30
|
|
|
* You should have received a copy of the GNU Affero General Public License |
31
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
32
|
|
|
*/ |
33
|
|
|
|
34
|
|
|
class Collector extends DispatcherClassModel { |
35
|
|
|
|
36
|
|
|
use TimestampTrait; |
37
|
|
|
|
38
|
|
|
private $bypass = false; |
39
|
|
|
|
40
|
|
|
private $classname = ""; |
41
|
|
|
|
42
|
|
|
private $type = ""; |
43
|
|
|
|
44
|
|
|
private $service = ""; |
45
|
|
|
|
46
|
|
|
private $cache; |
47
|
|
|
|
48
|
|
|
private $request; |
49
|
|
|
|
50
|
|
|
private $response; |
51
|
|
|
|
52
|
|
|
private $table; |
53
|
|
|
|
54
|
|
|
public function __construct( |
55
|
|
|
Configuration $configuration, |
56
|
|
|
Logger $logger, |
57
|
|
|
CacheManager $cache, |
58
|
|
|
Extra $extra = null |
59
|
|
|
) { |
60
|
|
|
|
61
|
|
|
parent::__construct($configuration, $logger); |
62
|
|
|
|
63
|
|
|
$this->table = new RoutingTable($logger); |
64
|
|
|
|
65
|
|
|
$this->cache = $cache; |
66
|
|
|
|
67
|
|
|
$this->extra = $extra; |
68
|
|
|
|
69
|
|
|
$this->setTimestamp(); |
70
|
|
|
|
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
public function getType() { |
74
|
|
|
|
75
|
|
|
return $this->type; |
76
|
|
|
|
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
public function getService() { |
80
|
|
|
|
81
|
|
|
return $this->service; |
82
|
|
|
|
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function getParameters() { |
86
|
|
|
|
87
|
|
|
return $this->parameters; |
88
|
|
|
|
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public function getClassName() { |
92
|
|
|
|
93
|
|
|
return $this->classname; |
94
|
|
|
|
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
public function getInstance() { |
98
|
|
|
|
99
|
|
|
$class = $this->classname; |
100
|
|
|
|
101
|
|
|
if (class_exists($class)) { |
102
|
|
|
|
103
|
|
|
return new $class( |
104
|
|
|
$this->configuration, |
105
|
|
|
$this->logger, |
106
|
|
|
$this->request, |
107
|
|
|
$this, |
108
|
|
|
$this->response, |
109
|
|
|
$this->extra |
110
|
|
|
); |
111
|
|
|
|
112
|
|
|
} |
113
|
|
|
else return null; |
114
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
public function add($route, $type, $class, $parameters = array()) { |
118
|
|
|
|
119
|
|
|
$routeData = $this->get($route); |
120
|
|
|
|
121
|
|
|
if (is_null($routeData)) { |
122
|
|
|
|
123
|
|
|
$this->table->put($route, $type, $class, $parameters); |
124
|
|
|
|
125
|
|
|
} else { |
126
|
|
|
|
127
|
|
|
$this->table->set($route, $type, $class, $parameters); |
128
|
|
|
|
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
public function get($route) { |
134
|
|
|
|
135
|
|
|
return $this->table->get($route); |
136
|
|
|
|
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
public function remove($route) { |
140
|
|
|
|
141
|
|
|
return $this->table->remove($route); |
142
|
|
|
|
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
public function bypass($mode = true) { |
146
|
|
|
|
147
|
|
|
$this->bypass = filter_var($mode, FILTER_VALIDATE_BOOLEAN); |
148
|
|
|
|
149
|
|
|
return $this; |
150
|
|
|
|
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
public function route(Request $request) { |
154
|
|
|
|
155
|
|
|
$this->request = $request; |
156
|
|
|
|
157
|
|
|
if (!$this->parse()) { |
158
|
|
|
|
159
|
|
|
throw new DispatcherException("Unable to find a valid route for the specified uri", 1, null, 404); |
160
|
|
|
|
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
|
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
public function compose(Response $response) { |
167
|
|
|
|
168
|
|
|
$this->response = $response; |
169
|
|
|
|
170
|
|
|
$service = $this->getInstance(); |
171
|
|
|
|
172
|
|
|
if (!is_null($service)) { |
173
|
|
|
|
174
|
|
|
$result = ""; |
175
|
|
|
|
176
|
|
|
$method = $this->request->method()->get(); |
177
|
|
|
|
178
|
|
|
if (in_array($method, $service->getImplementedMethods())) { |
179
|
|
|
|
180
|
|
|
$callable = $service->getMethod($method); |
181
|
|
|
|
182
|
|
|
try { |
183
|
|
|
|
184
|
|
|
$result = call_user_func(array($service, $callable)); |
185
|
|
|
|
186
|
|
|
} catch (DispatcherException $de) { |
|
|
|
|
187
|
|
|
|
188
|
|
|
throw new DispatcherException(sprintf("Service '%s' exception for method '%s': %s", $this->service, $method, $de->getMessage()), 1, $de, 500); |
189
|
|
|
|
190
|
|
|
} catch (Exception $e) { |
|
|
|
|
191
|
|
|
|
192
|
|
|
throw new DispatcherException(sprintf("Service '%s' execution failed for method '%s': %s", $this->service, $method, $e->getMessage()), 1, $e, 500); |
193
|
|
|
|
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
} else { |
197
|
|
|
|
198
|
|
|
throw new DispatcherException(sprintf("Service '%s' doesn't implement method '%s'", $this->service, $method), 1, null, 500); |
199
|
|
|
|
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
$this->response->content()->set($result); |
203
|
|
|
|
204
|
|
|
} else { |
205
|
|
|
|
206
|
|
|
throw new DispatcherException(sprintf("Unable to execute service '%s'", $this->service), 1, null, 500); |
207
|
|
|
|
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
|
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
private function parse() { |
214
|
|
|
|
215
|
|
|
$path = $this->request->uri()->getPath(); |
216
|
|
|
|
217
|
|
|
foreach ($this->table->routes() as $regex => $value) { |
218
|
|
|
|
219
|
|
|
if (preg_match("/" . $regex . "/", $path, $matches)) { |
220
|
|
|
|
221
|
|
|
$this->evalUri($value['query'], $matches); |
222
|
|
|
|
223
|
|
|
foreach ($value['parameters'] as $parameter => $value) { |
224
|
|
|
|
225
|
|
|
$this->request->query()->set($parameter, $value); |
226
|
|
|
|
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
$this->classname = $value['class']; |
230
|
|
|
$this->type = $value['type']; |
231
|
|
|
$this->service = implode('.', $value['service']); |
232
|
|
|
$this->service = empty($this->service)?"default":$this->service; |
233
|
|
|
|
234
|
|
|
return true; |
235
|
|
|
|
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
return false; |
241
|
|
|
|
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
private function evalUri($parameters, $bits) { |
245
|
|
|
|
246
|
|
|
$count = 0; |
|
|
|
|
247
|
|
|
|
248
|
|
|
foreach ($parameters as $key => $value) { |
249
|
|
|
|
250
|
|
|
if (isset($bits[$key])) { |
251
|
|
|
|
252
|
|
|
if (preg_match('/^' . $value['regex'] . '$/', $bits[$key], $matches)) { |
253
|
|
|
|
254
|
|
|
if (count($matches) == 1) $matches = $matches[0]; |
255
|
|
|
|
256
|
|
|
$this->request->query()->set($key, $matches); |
257
|
|
|
|
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
} elseif ($value['required']) { |
261
|
|
|
|
262
|
|
|
throw new DispatcherException(sprintf("Required parameter '%s' not specified.", $key), 1, null, 500); |
263
|
|
|
|
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
} |
271
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.