PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.12
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.12
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / vendor / wpfluent / framework / src / WPFluent / Http / Router.php

Router.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.12, at vendor/wpfluent/framework/src/WPFluent/Http/Router.php

547 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\Framework\Http;
4
5 use Closure;
6
7 class Router
8 {
9 /**
10 * Application Instance
11 * @var \FluentForm\Framework\Foundation\Application
12 */
13 protected $app = null;
14
15 /**
16 * Name for the route.
17 * @var array
18 */
19 protected $name = [];
20
21 /**
22 * Mapping of named routes.
23 * @var array
24 */
25 protected $namedRoutes = [];
26
27 /**
28 * Prefix for the route
29 * @var array
30 */
31 protected $prefix = [];
32
33 /**
34 * Controller/Handler namespace
35 * @var array
36 */
37 protected $namespace = [];
38
39 /**
40 * Registered routes collection
41 * @var array
42 */
43 protected $routes = [];
44
45 /**
46 * Route policy handler to pass to the route
47 * @var array
48 */
49 protected $policyHandler = [];
50
51 /**
52 * Route middleware to pass to the route
53 * @var array
54 */
55 protected $middleware = [
56 'before' => [],
57 'after' => []
58 ];
59
60 /**
61 * Whether routes created by this router should override existing ones.
62 * @var bool
63 */
64 protected $shouldOverride = false;
65
66 /**
67 * Keep the track of number of group calls
68 * @var integer
69 */
70 protected $groupCount = 0;
71
72 /**
73 * Weak references to groups pending execution.
74 * @var array
75 */
76 protected $pendingGroups = [];
77
78 /**
79 * Construct the routet instance
80 * @param \FluentForm\Framework\Foundation\Application $app
81 */
82 public function __construct($app)
83 {
84 $this->app = $app;
85 }
86
87 /**
88 * Create a route group
89 * @param array $attributes
90 * @param Closure|null $callback
91 * @return null
92 */
93 public function group($attributes = [], ?Closure $callback = null)
94 {
95 $this->groupCount += 1;
96
97 if ($attributes instanceof Closure) {
98 $callback = $attributes;
99 $attributes = [];
100 }
101
102 if (isset($attributes['name'])) {
103 $this->name($attributes['name']);
104 }
105
106 if (isset($attributes['prefix'])) {
107 $this->prefix($attributes['prefix']);
108 }
109
110 if (isset($attributes['namespace'])) {
111 $this->namespace($attributes['namespace']);
112 }
113
114 if (isset($attributes['policy'])) {
115 $this->withPolicy($attributes['policy']);
116 }
117
118 if (isset($attributes['middleware'])) {
119 $middleware = $attributes['middleware'];
120 if (isset($middleware['before'])) {
121 $this->middleware('before', $middleware['before']);
122 } elseif ($middleware['after']) {
123 $this->middleware('after', $middleware['after']);
124 }
125 }
126
127 // If the current group doesn't have a policy handler
128 // but the parent group has then bring it in this group.
129 if (!isset($this->policyHandler[$this->groupCount])) {
130 if (isset($this->policyHandler[$this->groupCount - 1])) {
131 if ($policyHandler = $this->policyHandler[$this->groupCount - 1]) {
132 $this->policyHandler[] = $policyHandler;
133 }
134 }
135 }
136
137 // If the current group doesn't have a before middleware
138 // but the parent group has then bring it in this group.
139 if (!isset($this->middleware['before'][$this->groupCount])) {
140 if (isset($this->middleware['before'][$this->groupCount - 1])) {
141 if ($beforeMiddleware = $this->middleware['before'][$this->groupCount - 1]) {
142 $this->middleware['before'][] = $beforeMiddleware;
143 }
144 }
145 }
146
147 // If the current group doesn't have an after middleware
148 // but the parent group has then bring it in this group.
149 if (!isset($this->middleware['after'][$this->groupCount])) {
150 if (isset($this->middleware['after'][$this->groupCount - 1])) {
151 if ($afterMiddleware = $this->middleware['after'][$this->groupCount - 1]) {
152 $this->middleware['after'][] = $afterMiddleware;
153 }
154 }
155 }
156
157 return new Group($this, $callback);
158 }
159
160 /**
161 * Set the route name
162 *
163 * @param string $name
164 * @return self
165 */
166 public function name($name)
167 {
168 $this->name[] = $name;
169
170 return $this;
171 }
172
173 /**
174 * Set the route prefix
175 *
176 * @param string $prefix
177 * @return self
178 */
179 public function prefix($prefix)
180 {
181 $this->prefix[] = $prefix;
182
183 return $this;
184 }
185
186 /**
187 * Set the namespace for the action/controller
188 *
189 * @param string $ns
190 * @return self
191 */
192 public function namespace($ns)
193 {
194 $this->namespace[] = $ns;
195
196 return $this;
197 }
198
199 /**
200 * Set the default route policy.
201 *
202 * @return self
203 */
204 public function withDefaultPolicy()
205 {
206 return $this->withPolicy(
207 // @phpstan-ignore-next-line
208 $this->app->__namespace__.'\\App\\Http\\Policies\\Policy'
209 );
210 }
211
212 /**
213 * Set the route policy
214 *
215 * @param mixed $handler
216 * @param string|null $method
217 * @return self
218 */
219 public function withPolicy($handler, $method = null)
220 {
221 if (is_array($handler = $method ? func_get_args() : $handler)) {
222 $handler = implode('@', $handler);
223 }
224
225 $this->policyHandler[] = $handler;
226
227 return $this;
228 }
229
230 /**
231 * Set the route before middleware
232 *
233 * @param array|string $middleware
234 * @return self
235 */
236 public function before(...$middleware)
237 {
238 return $this->middleware('before', ...$middleware);
239 }
240
241 /**
242 * Set the route after middleware
243 *
244 * @param array|string $middleware
245 * @return self
246 */
247 public function after(...$middleware)
248 {
249 return $this->middleware('after', ...$middleware);
250 }
251
252 /**
253 * Set the route middleware
254 *
255 * @param array|string $middleware
256 * @return self
257 */
258 public function middleware($type = 'before', ...$middleware)
259 {
260 if (is_array($middleware[0])) {
261 $middleware = reset($middleware);
262 }
263
264 $this->middleware[$type] = array_merge(
265 $this->middleware[$type], $middleware
266 );
267
268 return $this;
269 }
270
271 /**
272 * Track a group so any instance kept alive past its statement
273 * can still be executed before routes are registered. A weak
274 * reference keeps the destructor firing at end of statement.
275 *
276 * @param Group $group
277 * @return null
278 */
279 public function trackGroup(Group $group)
280 {
281 if (class_exists(\WeakReference::class)) {
282 $this->pendingGroups[] = \WeakReference::create($group);
283 }
284 }
285
286 /**
287 * Execute any groups still pending execution because a
288 * reference to them was held beyond their statement.
289 *
290 * @return null
291 */
292 protected function executePendingGroups()
293 {
294 while ($this->pendingGroups) {
295 $reference = array_shift($this->pendingGroups);
296
297 if ($group = $reference->get()) {
298 $group->execute();
299 }
300 }
301 }
302
303 /**
304 * Execute the route group callback
305 *
306 * @param Closure $callback
307 * @return null
308 */
309 public function executeGroupCallback($callback)
310 {
311 $callback($this);
312 $this->groupCount -= 1;
313 array_pop($this->name);
314 array_pop($this->prefix);
315 array_pop($this->namespace);
316 array_pop($this->middleware['before']);
317 array_pop($this->middleware['after']);
318 array_pop($this->policyHandler);
319 }
320
321 /**
322 * Declare a GET route endpoint
323 * @param string $uri
324 * @param array|string|Closure $handler
325 * @return \FluentForm\Framework\Http\Route
326 */
327 public function get($uri, $handler)
328 {
329 $this->routes[] = $route = $this->newRoute(
330 $uri, $handler, 'GET'
331 );
332
333 return $route;
334 }
335
336 /**
337 * Declare a POST route endpoint
338 * @param string $uri
339 * @param array|string|Closure $handler
340 * @return \FluentForm\Framework\Http\Route
341 */
342 public function post($uri, $handler)
343 {
344 $this->routes[] = $route = $this->newRoute(
345 $uri, $handler, 'POST'
346 );
347
348 return $route;
349 }
350
351 /**
352 * Declare a PUT route endpoint
353 * @param string $uri
354 * @param array|string|Closure $handler
355 * @return \FluentForm\Framework\Http\Route
356 */
357 public function put($uri, $handler)
358 {
359 $this->routes[] = $route = $this->newRoute(
360 $uri, $handler, 'PUT'
361 );
362
363 return $route;
364 }
365
366 /**
367 * Declare a PATCH route endpoint
368 * @param string $uri
369 * @param array|string|Closure $handler
370 * @return \FluentForm\Framework\Http\Route
371 */
372 public function patch($uri, $handler)
373 {
374 $this->routes[] = $route = $this->newRoute(
375 $uri, $handler, 'PATCH'
376 );
377
378 return $route;
379 }
380
381 /**
382 * Declare a DELETE route endpoint
383 * @param string $uri
384 * @param array|string|Closure $handler
385 * @return \FluentForm\Framework\Http\Route
386 */
387 public function delete($uri, $handler)
388 {
389 $this->routes[] = $route = $this->newRoute(
390 $uri, $handler, 'DELETE'
391 );
392
393 return $route;
394 }
395
396 /**
397 * Declare a route endpoint that matches any HTTP Verb/Method
398 * @param string $uri
399 * @param array|string|Closure $handler
400 * @return \FluentForm\Framework\Http\Route
401 */
402 public function any($uri, $handler)
403 {
404 $this->routes[] = $route = $this->newRoute(
405 $uri, $handler, \WP_REST_Server::ALLMETHODS
406 );
407
408 return $route;
409 }
410
411 /**
412 * Create a new route instance
413 * @param string $uri
414 * @param string|Closure $handler
415 * @param string $method HTTP Method
416 * @return \FluentForm\Framework\Http\Route
417 */
418 protected function newRoute($uri, $handler, $method)
419 {
420 $route = Route::create(
421 $this->app,
422 $this->getRestNamespace(),
423 $this->buildUriWithPrefix($uri),
424 $handler,
425 $method
426 );
427
428 if ($this->name) {
429 $route->withName($this->name);
430 }
431
432 if ($this->namespace) {
433 $route->withNamespace($this->namespace);
434 }
435
436 if ($this->policyHandler) {
437 $route->withPolicy(end($this->policyHandler));
438 }
439
440 if ($this->middleware['before']) {
441 $route->before($this->middleware['before']);
442 }
443
444 if ($this->middleware['after']) {
445 $route->after($this->middleware['after']);
446 }
447
448 if ($this->shouldOverride) {
449 $route->override();
450 }
451
452 return $route->preparefrontendHandlers();
453 }
454
455 /**
456 * Resolve the rest namespace for the plugin
457 *
458 * @return string
459 */
460 protected function getRestNamespace()
461 {
462 $version = $this->app->config->get('app.rest_version');
463
464 $namespace = trim(
465 $this->app->config->get('app.rest_namespace', ''), '/'
466 );
467
468 return "{$namespace}/{$version}";
469 }
470
471 /**
472 * Build the URI with the prefix
473 *
474 * @param string $uri
475 * @return string The URI
476 */
477 protected function buildUriWithPrefix($uri)
478 {
479 $uri = trim($uri, '/');
480
481 $prefix = array_map(function($prefix) {
482 return trim($prefix, '/');
483 }, $this->prefix);
484
485 $prefix = implode('/', $prefix);
486
487 return trim($prefix, '/') . '/' . trim($uri, '/');
488 }
489
490 /**
491 * Mark all routes created by this router to override existing ones.
492 *
493 * @return $this
494 */
495 public function overrideExisting()
496 {
497 $this->shouldOverride = true;
498
499 return $this;
500 }
501
502 /**
503 * Register all the routse in WordPress Rest Engine
504 *
505 * @return null
506 */
507 public function registerRoutes()
508 {
509 $this->executePendingGroups();
510
511 foreach ($this->routes as $route) $route->register();
512 }
513
514 /**
515 * Get all ther registered routes
516 * @return array
517 */
518 public function getRoutes()
519 {
520 return $this->routes;
521 }
522
523 /**
524 * Set a named route in the router.
525 *
526 * @param string $name
527 * @param Route $route
528 */
529 public function setNamedRoute($name, Route $route)
530 {
531 $this->namedRoutes[$name] = $route;
532
533 return $route;
534 }
535
536 /**
537 * Get a route by name.
538 *
539 * @param string $name
540 * @return Route|null
541 */
542 public function getByName($name)
543 {
544 return $this->namedRoutes[$name] ?? null;
545 }
546 }
547