Passed
Pull Request — master (#124)
by Arman
06:03 queued 02:57
created

MvcManager::handle()   B

Complexity

Conditions 7
Paths 18

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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