Passed
Pull Request — master (#80)
by Arman
04:01
created

MvcManager::routeParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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