Completed
Push — master ( e43f1a...57db71 )
by Arman
26s queued 12s
created

HttpRequest::create()   B

Complexity

Conditions 8
Paths 128

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 30
rs 8.2111
cc 8
nc 128
nop 4
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.4.0
13
 */
14
15
namespace Quantum\Http\Request;
16
17
use Quantum\Exceptions\HttpException;
18
use Quantum\Environment\Server;
19
use Quantum\Bootstrap;
20
21
/**
22
 * Class HttpRequest
23
 * @package Quantum\Http
24
 */
25
abstract class HttpRequest
26
{
27
28
    use Header;
29
    use Body;
30
    use Url;
31
    use Query;
32
    use Params;
33
    use File;
34
35
    /**
36
     * Request method
37
     * @var string
38
     */
39
    private static $__method = null;
40
41
    /**
42
     * Available methods
43
     * @var array
44
     */
45
    private static $availableMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
46
47
    /**
48
     * Server
49
     * @var \Quantum\Environment\Server
50
     */
51
    private static $server;
52
53
    /**
54
     * Initialize the Request
55
     * @param \Quantum\Environment\Server $server
56
     * @throws \Quantum\Exceptions\HttpException
57
     */
58
    public static function init(Server $server)
59
    {
60
61
        if (get_caller_class(3) !== Bootstrap::class) {
62
            throw new HttpException(HttpException::UNEXPECTED_REQUEST_INITIALIZATION);
63
        }
64
65
        self::$server = $server;
66
67
        self::$__method = self::$server->method();
68
69
        self::$__protocol = self::$server->protocol();
70
71
        self::$__host = self::$server->host();
72
73
        self::$__port = self::$server->port();
74
75
        self::$__uri = self::$server->uri();
76
77
        self::$__query = self::$server->query();
78
79
        self::$__headers = array_change_key_case((array)getallheaders(), CASE_LOWER);
80
81
        self::$__request = array_merge(
82
            self::$__request,
83
            self::getParams(),
84
            self::postParams(),
85
            self::getRawInputs()
86
        );
87
88
        self::$__files = self::handleFiles($_FILES);
89
    }
90
91
    /**
92
     * Creates new request for internal use
93
     * @param string $method
94
     * @param string $url
95
     * @param array|null $data
96
     * @param array|null $file
97
     * @throws \Quantum\Exceptions\HttpException
98
     */
99
    public static function create(string $method, string $url, array $data = null, array $file = null)
100
    {
101
        $parsed = parse_url($url);
102
103
        self::setMethod($method);
104
105
        if (isset($parsed['scheme'])) {
106
            self::setProtocol($parsed['scheme']);
107
        }
108
109
        if (isset($parsed['host'])) {
110
            self::setHost($parsed['host']);
111
        }
112
113
        if (isset($parsed['port'])) {
114
            self::setPort($parsed['port']);
115
        }
116
        if (isset($parsed['path'])) {
117
            self::setUri($parsed['path']);
118
        }
119
        if (isset($parsed['query'])) {
120
            self::setQuery($parsed['query']);
121
        }
122
123
        if ($data) {
124
            self::$__request = $data;
125
        }
126
127
        if ($file) {
128
            self::$__files = self::handleFiles($file);
129
        }
130
    }
131
132
    /**
133
     * Flushes the request header , body and files
134
     */
135
    public static function flush()
136
    {
137
        self::$__headers = [];
138
        self::$__request = [];
139
        self::$__files = [];
140
        self::$__protocol = null;
141
        self::$__host = null;
142
        self::$__port = null;
143
        self::$__uri = null;
144
        self::$__query = null;
145
    }
146
147
    /**
148
     * Gets the request method
149
     * @return string|null
150
     */
151
    public static function getMethod(): ?string
152
    {
153
        return self::$__method;
154
    }
155
156
    /**
157
     * Sets the request method
158
     * @param string $method
159
     * @throws \Quantum\Exceptions\HttpException
160
     */
161
    public static function setMethod(string $method)
162
    {
163
        if (!in_array($method, self::$availableMethods)) {
164
            throw new HttpException(HttpException::METHOD_NOT_AVAILABLE);
165
        }
166
167
        self::$__method = $method;
168
    }
169
170
    /**
171
     * Check the request method
172
     * @param string $method
173
     * @return boolean
174
     */
175
    public static function isMethod(string $method): bool
176
    {
177
        return strcasecmp($method, self::$__method) == 0;
178
    }
179
180
    /**
181
     * Gets the nth segment
182
     * @param integer $number
183
     * @return string|null
184
     */
185
    public static function getSegment(int $number): ?string
186
    {
187
        $segments = self::getAllSegments();
188
189
        if (isset($segments[$number])) {
190
            return $segments[$number];
191
        }
192
193
        return null;
194
    }
195
196
    /**
197
     * Gets the segments of current URI
198
     * @return array
199
     */
200
    public static function getAllSegments(): array
201
    {
202
        $segments = explode('/', trim(parse_url(self::$__uri)['path'], '/'));
203
        array_unshift($segments, 'zero_segment');
204
        return $segments;
205
    }
206
207
    /**
208
     * Gets Сross Site Request Forgery Token
209
     * @return string|null
210
     */
211
    public static function getCSRFToken(): ?string
212
    {
213
        $csrfToken = null;
214
215
        if (self::has('token')) {
216
            $csrfToken = (string)self::get('token');
217
        } elseif (self::hasHeader('X-csrf-token')) {
218
            $csrfToken = self::getHeader('X-csrf-token');
219
        }
220
221
        return $csrfToken;
222
    }
223
224
    /**
225
     * Gets Authorization Bearer token
226
     * @return string|null
227
     */
228
    public static function getAuthorizationBearer(): ?string
229
    {
230
        $bearerToken = null;
231
232
        $authorization = (string)self::getHeader('Authorization');
233
234
        if (self::hasHeader('Authorization')) {
235
            if (preg_match('/Bearer\s(\S+)/', $authorization, $matches)) {
236
                $bearerToken = $matches[1];
237
            }
238
        }
239
240
        return $bearerToken;
241
    }
242
243
    /**
244
     * Checks to see if request was AJAX request
245
     * @return bool
246
     */
247
    public static function isAjax(): bool
248
    {
249
        return self::hasHeader('X-REQUESTED-WITH') || self::$server->ajax();
250
    }
251
252
    /**
253
     * Gets the referrer
254
     * @return string|null
255
     */
256
    public static function getReferrer(): ?string
257
    {
258
        return self::$server->referrer();
259
    }
260
261
}
262