Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.55% |
140 / 145 |
|
92.68% |
38 / 41 |
CRAP | |
0.00% |
0 / 1 |
Request | |
96.55% |
140 / 145 |
|
92.68% |
38 / 41 |
91 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
create | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createJson | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createXml | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createUrlEncoded | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createMultipart | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMethod | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
getMethod | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasMethod | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addHeader | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
11 | |||
setQuery | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
addQuery | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
3.14 | |||
getQuery | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasQuery | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
removeQuery | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
removeAllQuery | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
setData | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
addData | |
66.67% |
4 / 6 |
|
0.00% |
0 / 1 |
3.33 | |||
getData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
removeData | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
removeAllData | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
getUriAsString | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
10 | |||
setRequestType | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
8 | |||
getRequestType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasRequestType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
removeRequestType | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
createAsJson | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
isJson | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createAsXml | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
isXml | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createAsUrlEncoded | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
isUrlEncoded | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
createAsMultipart | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
isMultipart | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isValidMethod | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasDataContent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
getDataContent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDataContentLength | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
prepareData | |
75.00% |
3 / 4 |
|
0.00% |
0 / 1 |
2.06 | |||
__call | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Http\Client; |
15 | |
16 | use Pop\Http\Uri; |
17 | use Pop\Http\AbstractRequest; |
18 | use Pop\Mime\Message; |
19 | use Pop\Mime\Part\Header; |
20 | |
21 | /** |
22 | * HTTP client request class |
23 | * |
24 | * @category Pop |
25 | * @package Pop\Http |
26 | * @author Nick Sagona, III <dev@nolainteractive.com> |
27 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
28 | * @license http://www.popphp.org/license New BSD License |
29 | * @version 5.2.0 |
30 | */ |
31 | class Request extends AbstractRequest |
32 | { |
33 | |
34 | /** |
35 | * Request type constants |
36 | * @var string |
37 | */ |
38 | const URLENCODED = 'application/x-www-form-urlencoded'; |
39 | const JSON = 'application/json'; |
40 | const XML = 'application/xml'; |
41 | const MULTIPART = 'multipart/form-data'; |
42 | |
43 | /** |
44 | * Request method |
45 | * @var ?string |
46 | */ |
47 | protected ?string $method = null; |
48 | |
49 | /** |
50 | * Request type |
51 | * @var ?string |
52 | */ |
53 | protected ?string $requestType = null; |
54 | |
55 | /** |
56 | * Client request query data object |
57 | * |
58 | * Can only be a URL-encoded query string on the URI |
59 | * |
60 | * @var ?Data |
61 | */ |
62 | protected ?Data $query = null; |
63 | |
64 | /** |
65 | * Client request data object |
66 | * |
67 | * Can be any type of supported request data: |
68 | * - URL-encoded query string on the URI (GET method) |
69 | * - URL-encoded body (any method other than GET) |
70 | * - JSON-encoded body |
71 | * - XML-encoded body |
72 | * - Multipart/form body |
73 | * |
74 | * @var ?Data |
75 | */ |
76 | protected ?Data $data = null; |
77 | |
78 | /** |
79 | * Constructor |
80 | * |
81 | * Instantiate the request data object |
82 | * |
83 | * @param Uri|string|null $uri |
84 | * @param string $method |
85 | * @param mixed $data |
86 | * @param ?string $type |
87 | * @param bool $strict |
88 | * @throws Exception|\Pop\Http\Exception |
89 | */ |
90 | public function __construct(Uri|string|null $uri = null, string $method = 'GET', mixed $data = null, ?string $type = null, bool $strict = false) |
91 | { |
92 | parent::__construct($uri); |
93 | |
94 | if ($method !== null) { |
95 | $this->setMethod($method, $strict); |
96 | } |
97 | if ($data !== null) { |
98 | $this->setData($data); |
99 | } |
100 | if ($type !== null) { |
101 | $this->setRequestType($type); |
102 | } |
103 | } |
104 | |
105 | /** |
106 | * Factory method to create a Request object |
107 | * |
108 | * @param Uri|string|null $uri |
109 | * @param string $method |
110 | * @param mixed $data |
111 | * @param ?string $type |
112 | * @param bool $strict |
113 | * @throws Exception|\Pop\Http\Exception |
114 | * @return Request |
115 | */ |
116 | public static function create(Uri|string|null $uri = null, string $method = 'GET', mixed $data = null, ?string $type = null, bool $strict = false): Request |
117 | { |
118 | return new self($uri, $method, $data, $type, $strict); |
119 | } |
120 | |
121 | /** |
122 | * Factory method to create a JSON Request object |
123 | * |
124 | * @param Uri|string|null $uri |
125 | * @param string $method |
126 | * @param mixed $data |
127 | * @param bool $strict |
128 | * @throws Exception|\Pop\Http\Exception |
129 | * @return Request |
130 | */ |
131 | public static function createJson(Uri|string|null $uri = null, string $method = 'POST', mixed $data = null, bool $strict = false): Request |
132 | { |
133 | return new self($uri, $method, $data, Request::JSON, $strict); |
134 | } |
135 | |
136 | /** |
137 | * Factory method to create an XML Request object |
138 | * |
139 | * @param Uri|string|null $uri |
140 | * @param string $method |
141 | * @param mixed $data |
142 | * @param bool $strict |
143 | * @throws Exception|\Pop\Http\Exception |
144 | * @return Request |
145 | */ |
146 | public static function createXml(Uri|string|null $uri = null, string $method = 'POST', mixed $data = null, bool $strict = false): Request |
147 | { |
148 | return new self($uri, $method, $data, Request::XML, $strict); |
149 | } |
150 | |
151 | /** |
152 | * Factory method to create a URL-encoded Request object |
153 | * |
154 | * @param Uri|string|null $uri |
155 | * @param string $method |
156 | * @param mixed $data |
157 | * @param bool $strict |
158 | * @throws Exception|\Pop\Http\Exception |
159 | * @return Request |
160 | */ |
161 | public static function createUrlEncoded(Uri|string|null $uri = null, string $method = 'GET', mixed $data = null, bool $strict = false): Request |
162 | { |
163 | return new self($uri, $method, $data, Request::URLENCODED, $strict); |
164 | } |
165 | |
166 | /** |
167 | * Factory method to create a multipart Request object |
168 | * |
169 | * @param Uri|string|null $uri |
170 | * @param string $method |
171 | * @param mixed $data |
172 | * @param bool $strict |
173 | * @throws Exception|\Pop\Http\Exception |
174 | * @return Request |
175 | */ |
176 | public static function createMultipart(Uri|string|null $uri = null, string $method = 'POST', mixed $data = null, bool $strict = false): Request |
177 | { |
178 | return new self($uri, $method, $data, Request::MULTIPART, $strict); |
179 | } |
180 | |
181 | /** |
182 | * Set method |
183 | * |
184 | * @param string $method |
185 | * @param bool $strict |
186 | * @throws Exception |
187 | * @return Request |
188 | */ |
189 | public function setMethod(string $method, bool $strict = false): Request |
190 | { |
191 | $method = strtoupper($method); |
192 | |
193 | if ($strict) { |
194 | if (!$this->isValidMethod($method)) { |
195 | throw new Exception('Error: That request method is not valid.'); |
196 | } |
197 | } |
198 | |
199 | $this->method = $method; |
200 | return $this; |
201 | } |
202 | |
203 | /** |
204 | * Get method |
205 | * |
206 | * @return ?string |
207 | */ |
208 | public function getMethod(): ?string |
209 | { |
210 | return $this->method; |
211 | } |
212 | |
213 | /** |
214 | * Has method |
215 | * |
216 | * @return bool |
217 | */ |
218 | public function hasMethod(): bool |
219 | { |
220 | return ($this->method !== null); |
221 | } |
222 | |
223 | /** |
224 | * Add a header |
225 | * |
226 | * @param Header|string|int $header |
227 | * @param ?string $value |
228 | * @return Request |
229 | */ |
230 | public function addHeader(Header|string|int $header, ?string $value = null): Request |
231 | { |
232 | $contentType = null; |
233 | if (is_numeric($header) && ($value !== null)) { |
234 | $header = Header::parse($value); |
235 | $value = null; |
236 | } |
237 | if (is_string($header) && ($header == 'Content-Type')) { |
238 | $contentType = $value; |
239 | } else if (($header instanceof Header) && ($header->getName() == 'Content-Type')) { |
240 | $contentType = $header->getValue()->getValue(); |
241 | } |
242 | |
243 | switch ($contentType) { |
244 | case Request::JSON: |
245 | $this->requestType = Request::JSON; |
246 | break; |
247 | case Request::XML: |
248 | $this->requestType = Request::XML; |
249 | break; |
250 | case Request::URLENCODED: |
251 | $this->requestType = Request::URLENCODED; |
252 | break; |
253 | case Request::MULTIPART: |
254 | $this->requestType = Request::MULTIPART; |
255 | break; |
256 | } |
257 | |
258 | parent::addHeader($header, $value); |
259 | return $this; |
260 | } |
261 | |
262 | /** |
263 | * Set query data |
264 | * |
265 | * @param mixed $query |
266 | * @param mixed $filters |
267 | * @return Request |
268 | */ |
269 | public function setQuery(mixed $query, mixed $filters = null): Request |
270 | { |
271 | $this->setRequestType(Request::URLENCODED); |
272 | $this->query = ($query instanceof Data) ? $query : new Data($query, $filters, $this); |
273 | return $this; |
274 | } |
275 | |
276 | /** |
277 | * Add query data |
278 | * |
279 | * @param mixed $name |
280 | * @param mixed $value |
281 | * @return Request |
282 | */ |
283 | public function addQuery(mixed $name, mixed $value): Request |
284 | { |
285 | $this->setRequestType(Request::URLENCODED); |
286 | if ($this->query === null) { |
287 | $this->setRequestType(Request::URLENCODED); |
288 | $this->query = new Data([], null, $this); |
289 | } else if (!$this->query->hasRequest()) { |
290 | $this->query->setRequest($this); |
291 | } |
292 | $this->query->addData($name, $value); |
293 | |
294 | return $this; |
295 | } |
296 | |
297 | /** |
298 | * Get query data |
299 | * |
300 | * @return ?Data |
301 | */ |
302 | public function getQuery(): ?Data |
303 | { |
304 | return $this->query; |
305 | } |
306 | |
307 | /** |
308 | * Has query data |
309 | * |
310 | * @return bool |
311 | */ |
312 | public function hasQuery(): bool |
313 | { |
314 | return !empty($this->query); |
315 | } |
316 | |
317 | /** |
318 | * Remove query data |
319 | * |
320 | * @param string $key |
321 | * @return Request |
322 | */ |
323 | public function removeQuery(string $key): Request |
324 | { |
325 | if ($this->query->hasData($key)) { |
326 | $this->query->removeData($key); |
327 | } |
328 | return $this; |
329 | } |
330 | |
331 | /** |
332 | * Remove all query data |
333 | * |
334 | * @return Request |
335 | */ |
336 | public function removeAllQuery(): Request |
337 | { |
338 | $this->query = null; |
339 | |
340 | if ($this->hasHeader('Content-Type')) { |
341 | $this->removeHeader('Content-Type'); |
342 | } |
343 | return $this; |
344 | } |
345 | |
346 | /** |
347 | * Set data |
348 | * |
349 | * @param mixed $data |
350 | * @param mixed $filters |
351 | * @return Request |
352 | */ |
353 | public function setData(mixed $data, mixed $filters = null): Request |
354 | { |
355 | if ($data instanceof Data) { |
356 | if (!$data->hasRequest()) { |
357 | $data->setRequest($this); |
358 | } |
359 | } else { |
360 | $data = new Data($data, $filters, $this); |
361 | } |
362 | |
363 | $this->data = $data; |
364 | |
365 | return $this; |
366 | } |
367 | |
368 | /** |
369 | * Add data |
370 | * |
371 | * @param mixed $name |
372 | * @param mixed $value |
373 | * @return Request |
374 | */ |
375 | public function addData(mixed $name, mixed $value): Request |
376 | { |
377 | if ($this->data === null) { |
378 | $this->data = new Data([], null, $this); |
379 | } else if (!$this->data->hasRequest()) { |
380 | $this->data->setRequest($this); |
381 | } |
382 | $this->data->addData($name, $value); |
383 | |
384 | return $this; |
385 | } |
386 | |
387 | /** |
388 | * Get data |
389 | * |
390 | * @return ?Data |
391 | */ |
392 | public function getData(): ?Data |
393 | { |
394 | return $this->data; |
395 | } |
396 | |
397 | /** |
398 | * Has data |
399 | * |
400 | * @return bool |
401 | */ |
402 | public function hasData(): bool |
403 | { |
404 | return !empty($this->data); |
405 | } |
406 | |
407 | /** |
408 | * Remove data |
409 | * |
410 | * @param string $key |
411 | * @return Request |
412 | */ |
413 | public function removeData(string $key): Request |
414 | { |
415 | if ($this->data->hasData($key)) { |
416 | $this->data->removeData($key); |
417 | } |
418 | return $this; |
419 | } |
420 | |
421 | /** |
422 | * Remove all data |
423 | * |
424 | * @return Request |
425 | */ |
426 | public function removeAllData(): Request |
427 | { |
428 | $this->data = null; |
429 | |
430 | if ($this->hasHeader('Content-Type')) { |
431 | $this->removeHeader('Content-Type'); |
432 | } |
433 | if ($this->hasHeader('Content-Length')) { |
434 | $this->removeHeader('Content-Length'); |
435 | } |
436 | return $this; |
437 | } |
438 | |
439 | /** |
440 | * Get full URI as string |
441 | * |
442 | * @param bool $query |
443 | * @return string |
444 | */ |
445 | public function getUriAsString(bool $query = true): string |
446 | { |
447 | $uri = parent::getUriAsString(); |
448 | |
449 | if ($query) { |
450 | $queryString = null; |
451 | |
452 | // If request has generic query data |
453 | if ($this->hasQuery()) { |
454 | $queryString = $this->query->prepare()->getDataContent(); |
455 | // Else, if request has explicit data configured to be a query string over GET |
456 | } else if (($this->method == 'GET') && ($this->hasData()) && |
457 | (($this->requestType === null) || ($this->requestType == self::URLENCODED))) { |
458 | $queryString = $this->data->prepare()->getDataContent(); |
459 | } |
460 | |
461 | if (!empty($queryString) && !str_contains($uri, $queryString)) { |
462 | $uri .= ((str_contains($uri, '?')) ? '&' : '?') . $queryString; |
463 | } |
464 | } |
465 | |
466 | return $uri; |
467 | } |
468 | |
469 | /** |
470 | * Set request type |
471 | * |
472 | * @param ?string $type |
473 | * @return Request |
474 | */ |
475 | public function setRequestType(string $type = null): Request |
476 | { |
477 | switch ($type) { |
478 | case self::JSON: |
479 | $this->createAsJson(); |
480 | break; |
481 | case self::XML: |
482 | $this->createAsXml(); |
483 | break; |
484 | case self::URLENCODED: |
485 | $this->createAsUrlEncoded(); |
486 | break; |
487 | case self::MULTIPART: |
488 | $this->createAsMultipart(); |
489 | break; |
490 | default: |
491 | $this->requestType = null; |
492 | if ($this->hasHeader('Content-Type')) { |
493 | $this->removeHeader('Content-Type'); |
494 | } |
495 | if ($this->hasHeader('Content-Length')) { |
496 | $this->removeHeader('Content-Length'); |
497 | } |
498 | } |
499 | |
500 | return $this; |
501 | } |
502 | |
503 | /** |
504 | * Get request type |
505 | * |
506 | * @return ?string |
507 | */ |
508 | public function getRequestType(): ?string |
509 | { |
510 | return $this->requestType; |
511 | } |
512 | |
513 | /** |
514 | * Has request type |
515 | * |
516 | * @return bool |
517 | */ |
518 | public function hasRequestType(): bool |
519 | { |
520 | return ($this->requestType !== null); |
521 | } |
522 | |
523 | /** |
524 | * Remove request type |
525 | * |
526 | * @return Request |
527 | */ |
528 | public function removeRequestType(): Request |
529 | { |
530 | $this->requestType = null; |
531 | return $this; |
532 | } |
533 | |
534 | /** |
535 | * Create request as JSON |
536 | * |
537 | * @return Request |
538 | */ |
539 | public function createAsJson(): Request |
540 | { |
541 | $this->requestType = self::JSON; |
542 | |
543 | if ($this->hasHeader('Content-Type')) { |
544 | $this->removeHeader('Content-Type'); |
545 | } |
546 | $this->addHeader('Content-Type', $this->requestType); |
547 | |
548 | return $this; |
549 | } |
550 | |
551 | /** |
552 | * Check if request is JSON |
553 | * |
554 | * @return bool |
555 | */ |
556 | public function isJson(): bool |
557 | { |
558 | return ($this->requestType == self::JSON); |
559 | } |
560 | |
561 | /** |
562 | * Create request as XML |
563 | * |
564 | * @return Request |
565 | */ |
566 | public function createAsXml(): Request |
567 | { |
568 | $this->requestType = self::XML; |
569 | |
570 | if ($this->hasHeader('Content-Type')) { |
571 | $this->removeHeader('Content-Type'); |
572 | } |
573 | $this->addHeader('Content-Type', $this->requestType); |
574 | |
575 | return $this; |
576 | } |
577 | |
578 | /** |
579 | * Check if request is XML |
580 | * |
581 | * @return bool |
582 | */ |
583 | public function isXml(): bool |
584 | { |
585 | return ($this->requestType == self::XML); |
586 | } |
587 | |
588 | /** |
589 | * Create request as a URL-encoded form |
590 | * |
591 | * @return Request |
592 | */ |
593 | public function createAsUrlEncoded(): Request |
594 | { |
595 | $this->requestType = self::URLENCODED; |
596 | |
597 | if ($this->hasHeader('Content-Type')) { |
598 | $this->removeHeader('Content-Type'); |
599 | } |
600 | $this->addHeader('Content-Type', $this->requestType); |
601 | |
602 | return $this; |
603 | } |
604 | |
605 | /** |
606 | * Check if request is a URL-encoded form |
607 | * |
608 | * @return bool |
609 | */ |
610 | public function isUrlEncoded(): bool |
611 | { |
612 | return ($this->requestType == self::URLENCODED); |
613 | } |
614 | |
615 | /** |
616 | * Create request as a multipart form |
617 | * |
618 | * @return Request |
619 | */ |
620 | public function createAsMultipart(): Request |
621 | { |
622 | $this->requestType = self::MULTIPART; |
623 | return $this; |
624 | } |
625 | |
626 | /** |
627 | * Check if request is a multipart form |
628 | * |
629 | * @return bool |
630 | */ |
631 | public function isMultipart(): bool |
632 | { |
633 | return ($this->requestType == self::MULTIPART); |
634 | } |
635 | |
636 | /** |
637 | * Is valid method |
638 | * |
639 | * @param string $method |
640 | * @return bool |
641 | */ |
642 | public function isValidMethod(string $method): bool |
643 | { |
644 | return in_array(strtoupper($method), ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE']); |
645 | } |
646 | |
647 | /** |
648 | * Has data content |
649 | * |
650 | * @return bool |
651 | */ |
652 | public function hasDataContent(): bool |
653 | { |
654 | return (($this->data !== null) && ($this->data->hasDataContent())); |
655 | } |
656 | |
657 | /** |
658 | * Get the data content |
659 | * |
660 | * @return ?string |
661 | */ |
662 | public function getDataContent(): ?string |
663 | { |
664 | return $this->data?->getDataContent(); |
665 | } |
666 | |
667 | /** |
668 | * Get the data content length |
669 | * |
670 | * @param bool $mb |
671 | * @return int|null |
672 | */ |
673 | public function getDataContentLength(bool $mb = false): int|null |
674 | { |
675 | return $this->data?->getDataContentLength($mb); |
676 | } |
677 | |
678 | /** |
679 | * Prepare request data |
680 | * |
681 | * @return Request |
682 | */ |
683 | public function prepareData(): Request |
684 | { |
685 | if (!$this->data->hasRequest()) { |
686 | $this->data->setRequest($this); |
687 | } |
688 | |
689 | $this->data->prepare(); |
690 | |
691 | return $this; |
692 | } |
693 | |
694 | /** |
695 | * Magic method to check the is[Method](), i.e. $request->isPost(); |
696 | * |
697 | * @param string $methodName |
698 | * @param ?array $arguments |
699 | * @throws Exception |
700 | * @return bool |
701 | */ |
702 | public function __call(string $methodName, ?array $arguments = null): bool |
703 | { |
704 | if (str_starts_with($methodName, 'is')) { |
705 | $method = strtoupper(substr($methodName, 2)); |
706 | if ($this->isValidMethod($method)) { |
707 | return ($this->method == $method); |
708 | } else { |
709 | throw new Exception('Error: That request method is not valid.'); |
710 | } |
711 | } else { |
712 | throw new Exception('Error: That method/function is not valid.'); |
713 | } |
714 | } |
715 | |
716 | } |