Completed
Push — master ( 1d0b60...66f8c9 )
by Alex
07:16
created

Router::hasParam()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
namespace Mezon\Router;
3
4
// TODO add custom types
5
// TODO PSR-7 compliant
6
7
/**
8
 * Class Router
9
 *
10
 * @package Mezon
11
 * @subpackage Router
12
 * @author Dodonov A.A.
13
 * @version v.1.0 (2019/08/15)
14
 * @copyright Copyright (c) 2019, aeon.org
15
 */
16
17
/**
18
 * Router class
19
 */
20
class Router
21
{
22
23
    use \Mezon\Router\RoutesSet;
24
25
    use \Mezon\Router\UrlParser;
26
27
    /**
28
     * Method wich handles invalid route error
29
     *
30
     * @var callable
31
     */
32
    private $invalidRouteErrorHandler;
33
34
    /**
35
     * Method returns request method
36
     *
37
     * @return string Request method
38
     */
39
    protected function getRequestMethod(): string
40
    {
41
        return $_SERVER['REQUEST_METHOD'] ?? 'GET';
42
    }
43
44
    /**
45
     * Constructor
46
     */
47
    public function __construct()
48
    {
49
        $_SERVER['REQUEST_METHOD'] = $this->getRequestMethod();
50
51
        $this->invalidRouteErrorHandler = [
52
            $this,
53
            'noProcessorFoundErrorHandler'
54
        ];
55
56
        $this->initDefaultTypes();
57
    }
58
59
    /**
60
     * Method fetches actions from the objects and creates GetRoutes for them
61
     *
62
     * @param object $object
63
     *            Object to be processed
64
     */
65
    public function fetchActions(object $object): void
66
    {
67
        $methods = get_class_methods($object);
68
69
        foreach ($methods as $method) {
70
            if (strpos($method, 'action') === 0) {
71
                $route = \Mezon\Router\Utils::convertMethodNameToRoute($method);
72
                $this->addGetRoute($route, $object, $method);
73
                $this->addPostRoute($route, $object, $method);
74
            }
75
        }
76
    }
77
78
    /**
79
     * Method adds route and it's handler
80
     *
81
     * $callback function may have two parameters - $route and $parameters. Where $route is a called route,
82
     * and $parameters is associative array (parameter name => parameter value) with URL parameters
83
     *
84
     * @param string $route
85
     *            Route
86
     * @param mixed $callback
87
     *            Collback wich will be processing route call.
88
     * @param string|array $requestMethod
89
     *            Request type
90
     */
91
    public function addRoute(string $route, $callback, $requestMethod = 'GET'): void
92
    {
93
        $route = '/' . trim($route, '/') . '/';
94
95
        if (is_array($requestMethod)) {
96
            foreach ($requestMethod as $r) {
97
                $this->addRoute($route, $callback, $r);
98
            }
99
        } else {
100
            $routes = &$this->getRoutesForMethod($requestMethod);
101
            // this 'if' is for backward compatibility
102
            // remove it on 02-04-2021
103
            if (is_array($callback) && isset($callback[1]) && is_array($callback[1])) {
104
                $callback = $callback[1];
105
            }
106
            $routes[$route] = $callback;
107
        }
108
    }
109
110
    /**
111
     * Method processes no processor found error
112
     *
113
     * @param string $route
114
     *            Route
115
     */
116
    public function noProcessorFoundErrorHandler(string $route)
117
    {
118
        throw (new \Exception(
119
            'The processor was not found for the route ' . $route . ' in ' . $this->getAllRoutesTrace()));
120
    }
121
122
    /**
123
     * Method sets InvalidRouteErrorHandler function
124
     *
125
     * @param callable $function
126
     *            Error handler
127
     */
128
    public function setNoProcessorFoundErrorHandler(callable $function)
129
    {
130
        $oldErrorHandler = $this->invalidRouteErrorHandler;
131
132
        $this->invalidRouteErrorHandler = $function;
133
134
        return $oldErrorHandler;
135
    }
136
137
    /**
138
     * Processing specified router
139
     *
140
     * @param mixed $route
141
     *            Route
142
     */
143
    public function callRoute($route)
144
    {
145
        $route = \Mezon\Router\Utils::prepareRoute($route);
146
        $requestMethod = $this->getRequestMethod();
147
148
        if (($result = $this->findStaticRouteProcessor($this->getRoutesForMethod($requestMethod), $route)) !== false) {
149
            return $result;
150
        }
151
152
        if (($result = $this->findDynamicRouteProcessor($this->getRoutesForMethod($requestMethod), $route)) !== false) {
153
            return $result;
154
        }
155
156
        call_user_func($this->invalidRouteErrorHandler, $route);
157
    }
158
}
159