Route::delete()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Bonfim\Router;
4
5
use ReflectionException;
6
use ReflectionFunction;
7
8
/**
9
 * Class Route
10
 * @package Router
11
 */
12
/**
13
 * Class Route
14
 * @package Router
15
 */
16
/**
17
 * Class Route
18
 * @package Router
19
 */
20
class Route
21
{
22
    /**
23
     * @var Router
24
     */
25
    private $router;
26
27
    /**
28
     * @var bool
29
     */
30
    private $status = false;
0 ignored issues
show
introduced by
The private property $status is not used, and could be removed.
Loading history...
31
32
    /**
33
     * @var
34
     */
35
    private static $route;
36
37
    /**
38
     * @var null
39
     */
40
    private static $match = null;
41
42
43
    /**
44
     * Route constructor.
45
     */
46
    private function __construct()
47
    {
48
        $this->router = new Router();
49
    }
50
51
    /**
52
     * @return Route
53
     */
54
    private static function route(): Route
55
    {
56
        if (!isset(self::$route) || is_null(self::$route)) {
57
            self::$route = new Route;
58
        }
59
60
        return self::$route;
61
    }
62
63
    /**
64
     * @return null|Client
65
     */
66
    private static function dispatch(): ?Client
67
    {
68
        if (!isset(self::$match) || is_null(self::$match)) {
69
            self::$match = self::route()->router->handle();
0 ignored issues
show
Documentation Bug introduced by
It seems like self::route()->router->handle() can also be of type Bonfim\Router\Client. However, the property $match is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
70
        }
71
72
        return self::$match;
73
    }
74
75
    /**
76
     * @param string $method
77
     * @param string $uri
78
     * @param $callback
79
     * @return void
80
     * @throws ReflectionException
81
     */
82
    private function handle(string $method, string $uri, $callback): void
83
    {
84
        $this->router->add([
85
            'uri' => $uri,
86
            'name' => '',
87
            'method' => $method,
88
            'callback' => $callback
89
        ]);
90
91
        $match = $this->dispatch();
92
93
        $args = [];
94
95
        if ($match) {
96
97
            if (is_array($callback)) {
98
                $reflect = new \ReflectionMethod($callback[0], $callback[1]);
99
            } else {
100
                $reflect = new ReflectionFunction();
0 ignored issues
show
Bug introduced by
The call to ReflectionFunction::__construct() has too few arguments starting with name. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

100
                $reflect = /** @scrutinizer ignore-call */ new ReflectionFunction();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
101
            }
102
103
            foreach ($reflect->getParameters() as $i => $param) {
104
                // Caso o parametro seja tipado
105
                if ($param->hasType()) {
106
                    // Adiciona o objecto Request nos parametros da classe
107
                    if ($param->getType()->getName() == Request::class) {
108
                        $args[$i] = new Request();
109
                    }
110
111
                    // Adiciona o objeto Response nos parametros da classe
112
                    if ($param->getType()->getName() == Response::class) {
113
                        $args[$i] = new Response();
114
                    }
115
                } else {
116
                    //Adiciona o restante dos parametros nao tipados
117
                    $args[$i] = $match->getArg($param->getName());
118
                }
119
            }
120
121
            call_user_func_array($match->getCallback(), $args);
122
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
123
        }
124
    }
125
126
    /**
127
     * @param string $uri
128
     * @param $callback
129
     */
130
    public static function get(string $uri, $callback): void
131
    {
132
        self::route()->handle('get', $uri, $callback);
133
    }
134
135
    /**
136
     * @param string $uri
137
     * @param $callback
138
     */
139
    public static function post(string $uri, $callback): void
140
    {
141
        self::route()->handle('post', $uri, $callback);
142
    }
143
144
    /**
145
     * @param string $uri
146
     * @param $callback
147
     */
148
    public static function put(string $uri, $callback): void
149
    {
150
        self::route()->handle('put', $uri, $callback);
151
    }
152
153
    /**
154
     * @param string $uri
155
     * @param $callback
156
     */
157
    public static function patch(string $uri, $callback): void
158
    {
159
        self::route()->handle('patch', $uri, $callback);
160
    }
161
162
    /**
163
     * @param string $uri
164
     * @param $callback
165
     */
166
    public static function delete(string $uri, $callback): void
167
    {
168
        self::route()->handle('delete', $uri, $callback);
169
    }
170
171
    /**
172
     * @param string $uri
173
     * @param $callback
174
     */
175
    public static function options(string $uri, $callback): void
176
    {
177
        self::route()->handle('options', $uri, $callback);
178
    }
179
180
    /**
181
     * @param string $uri
182
     * @param $callback
183
     */
184
    public static function any(string $uri, $callback): void
185
    {
186
        $methods = ['get', 'post', 'put', 'patch', 'delete', 'options'];
187
        self::match($methods, $uri, $callback);
188
    }
189
190
    /**
191
     * @param array $methods
192
     * @param string $uri
193
     * @param $callback
194
     */
195
    public static function match(array $methods, string $uri, $callback): void
196
    {
197
        foreach ($methods as $method) {
198
            self::route()->handle($method, $uri, $callback);
199
        }
200
    }
201
}
202