Completed
Push — master ( c29b50...e0dfe4 )
by Arman
19s queued 13s
created

MvcManager::handle()   B

Complexity

Conditions 7
Paths 19

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 2
b 0
f 0
nc 19
nop 2
dl 0
loc 30
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.8.0
13
 */
14
15
namespace Quantum\Mvc;
16
17
use Quantum\Exceptions\ControllerException;
18
use Quantum\Libraries\Storage\FileSystem;
19
use Quantum\Middleware\MiddlewareManager;
20
use Quantum\Libraries\Csrf\Csrf;
21
use Quantum\Http\Response;
22
use Quantum\Http\Request;
23
use Quantum\Di\Di;
24
25
/**
26
 * Class MvcManager
27
 * @package Quantum\Mvc
28
 */
29
class MvcManager
30
{
31
32
    /**
33
     * Handles the request
34
     * @param \Quantum\Http\Request $request
35
     * @param \Quantum\Http\Response $response
36
     * @return boolean|null
37
     * @throws \Quantum\Exceptions\ControllerException
38
     * @throws \Quantum\Exceptions\CsrfException
39
     * @throws \Quantum\Exceptions\DatabaseException
40
     * @throws \Quantum\Exceptions\DiException
41
     * @throws \Quantum\Exceptions\MiddlewareException
42
     * @throws \Quantum\Exceptions\SessionException
43
     * @throws \ReflectionException
44
     */
45
    public static function handle(Request $request, Response $response)
46
    {
47
        if ($request->getMethod() == 'OPTIONS') {
48
            return false;
49
        }
50
51
        if (current_middlewares()) {
52
            list($request, $response) = (new MiddlewareManager())->applyMiddlewares($request, $response);
53
        }
54
55
        $callback = route_callback();
56
57
        if ($callback) {
58
            call_user_func_array($callback, self::getArgs($callback));
59
        } else {
60
            $controller = self::getController();
61
            $action = self::getAction($controller);
62
63
            if ($controller->csrfVerification) {
64
                Csrf::checkToken($request, session());
65
            }
66
67
            if (method_exists($controller, '__before')) {
68
                call_user_func_array([$controller, '__before'], self::getArgs([$controller, '__before']));
69
            }
70
71
            call_user_func_array([$controller, $action], self::getArgs([$controller, $action]));
72
73
            if (method_exists($controller, '__after')) {
74
                call_user_func_array([$controller, '__after'], self::getArgs([$controller, '__after']));
75
            }
76
        }
77
    }
78
79
    /**
80
     * Get Controller
81
     * @return \Quantum\Mvc\QtController
82
     * @throws \Quantum\Exceptions\ControllerException
83
     * @throws \Quantum\Exceptions\DiException
84
     * @throws \ReflectionException
85
     */
86
    private static function getController(): QtController
87
    {
88
        $fs = Di::get(FileSystem::class);
89
90
        $controllerPath = modules_dir() . DS . current_module() . DS . 'Controllers' . DS . current_controller() . '.php';
91
92
        if (!$fs->exists($controllerPath)) {
93
            throw ControllerException::controllerNotFound(current_controller());
94
        }
95
96
        require_once $controllerPath;
97
98
        $controllerClass = '\\Modules\\' . current_module() . '\\Controllers\\' . current_controller();
99
100
        if (!class_exists($controllerClass, false)) {
101
            throw ControllerException::controllerNotDefined(current_controller());
102
        }
103
104
        return new $controllerClass();
105
    }
106
107
    /**
108
     * Get Action
109
     * @param \Quantum\Mvc\QtController $controller
110
     * @return string|null
111
     * @throws \Quantum\Exceptions\ControllerException
112
     */
113
    private static function getAction(QtController $controller): ?string
114
    {
115
        $action = current_action();
116
117
        if ($action && !method_exists($controller, $action)) {
118
            throw ControllerException::actionNotDefined($action);
119
        }
120
121
        return $action;
122
    }
123
124
    /**
125
     * Get arguments
126
     * @param callable $callable
127
     * @return array
128
     * @throws \Quantum\Exceptions\DiException
129
     * @throws \ReflectionException
130
     */
131
    private static function getArgs(callable $callable): array
132
    {
133
        return Di::autowire($callable, self::routeParams());
134
    }
135
136
    /**
137
     * Gets the route parameters
138
     * @return array
139
     */
140
    private static function routeParams(): array
141
    {
142
        return array_map(function ($param) {
143
            return $param['value'];
144
        }, route_params());
145
    }
146
147
}
148