Passed
Pull Request — master (#257)
by
unknown
02:39
created

RouteDispatcher::handle()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 32
rs 8.8333
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.5
13
 */
14
15
 namespace Quantum\Mvc;
16
17
 use Quantum\Handlers\ViewCacheHandler;
18
 use Quantum\Http\Request;
19
 use Quantum\Http\Response;
20
 use Quantum\Middleware\MiddlewareExecutor;
21
 use Quantum\Libraries\Csrf\Csrf;
22
 use Quantum\Loader\Loader;
23
 use Quantum\Di\Di;
24
 use Quantum\Exceptions\ControllerException;
25
 use Quantum\Di\Exceptions\DiException;
26
 use ReflectionException;
27
 use Quantum\Router\RouteController;
28
 
29
 class RouteDispatcher
30
 {
31
     public static function handle(Request $request, Response $response): void
32
     {
33
         // 1. Apply middleware
34
         [$request, $response] = (new MiddlewareExecutor())->execute($request, $response);
35
 
36
         // 2. Try serving from view cache
37
         $viewCacheHandler = new ViewCacheHandler();
38
         if ($viewCacheHandler->serveCachedView(route_uri(), $response)) {
39
             return;
40
         }
41
 
42
         // 3. Route callback or controller handling
43
         $callback = route_callback();
44
 
45
         if ($callback) {
46
             call_user_func_array($callback, self::getArgs($callback));
47
         } else {
48
             $controller = self::getController();
49
             $action = self::getAction($controller);
50
 
51
             if ($controller->csrfVerification && in_array($request->getMethod(), Csrf::METHODS)) {
52
                 csrf()->checkToken($request);
53
             }
54
 
55
             if (method_exists($controller, '__before')) {
56
                 call_user_func_array([$controller, '__before'], self::getArgs([$controller, '__before']));
57
             }
58
 
59
             call_user_func_array([$controller, $action], self::getArgs([$controller, $action]));
60
 
61
             if (method_exists($controller, '__after')) {
62
                 call_user_func_array([$controller, '__after'], self::getArgs([$controller, '__after']));
63
             }
64
         }
65
     }
66
 
67
     private static function getController(): RouteController
68
     {
69
         $controllerPath = modules_dir() . DS . current_module() . DS . 'Controllers' . DS . current_controller() . '.php';
70
 
71
         $loader = Di::get(Loader::class);
72
 
73
         return $loader->loadClassFromFile(
74
             $controllerPath,
75
             function () {
76
                 return ControllerException::controllerNotFound(current_controller());
77
             },
78
             function () {
79
                 return ControllerException::controllerNotDefined(current_controller());
80
             }
81
         );
82
     }
83
 
84
     private static function getAction(RouteController $controller): ?string
85
     {
86
         $action = current_action();
87
 
88
         if ($action && !method_exists($controller, $action)) {
89
             throw ControllerException::actionNotDefined($action);
90
         }
91
 
92
         return $action;
93
     }
94
 
95
     private static function getArgs(callable $callable): array
96
     {
97
         return Di::autowire($callable, self::routeParams());
98
     }
99
 
100
     private static function routeParams(): array
101
     {
102
         return array_map(function ($param) {
103
             return $param['value'];
104
         }, route_params());
105
     }
106
 }