| Total Complexity | 120 |
| Total Lines | 1069 |
| Duplicated Lines | 0 % |
| Changes | 12 | ||
| Bugs | 0 | Features | 0 |
Complex classes like Request often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Request, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 49 | class Request |
||
| 50 | { |
||
| 51 | use HttpRequest, |
||
| 52 | HttpResources, |
||
| 53 | CanBePrecognitive, |
||
| 54 | InteractsWithInput, |
||
| 55 | InteractsWithContentTypes; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Get the acceptable of content types. |
||
| 59 | * |
||
| 60 | * @var string[] $acceptableContenTypes |
||
| 61 | */ |
||
| 62 | protected $acceptableContentTypes; |
||
| 63 | |||
| 64 | /** |
||
| 65 | * Get the custom parameters. |
||
| 66 | * |
||
| 67 | * @var \Syscodes\Components\Http\Loaders\Parameters $attributes |
||
| 68 | */ |
||
| 69 | public $attributes; |
||
| 70 | |||
| 71 | /** |
||
| 72 | * The base URL. |
||
| 73 | * |
||
| 74 | * @var string $baseUrl |
||
| 75 | */ |
||
| 76 | protected $baseUrl; |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Get the client ip. |
||
| 80 | * |
||
| 81 | * @var mixed $clientIp |
||
| 82 | */ |
||
| 83 | protected $clientIp; |
||
| 84 | |||
| 85 | /** |
||
| 86 | * Gets cookies ($_COOKIE). |
||
| 87 | * |
||
| 88 | * @var \Syscodes\Components\Http\Loaders\Inputs $cookies |
||
| 89 | */ |
||
| 90 | public $cookies; |
||
| 91 | |||
| 92 | /** |
||
| 93 | * Gets the string with format JSON. |
||
| 94 | * |
||
| 95 | * @var string|resource|object|null $content |
||
| 96 | */ |
||
| 97 | protected $content; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * The default Locale this request. |
||
| 101 | * |
||
| 102 | * @var string $defaultLocale |
||
| 103 | */ |
||
| 104 | protected $defaultLocale = 'en'; |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Gets files request ($_FILES). |
||
| 108 | * |
||
| 109 | * @var \Syscodes\Components\Http\Loaders\Files $files |
||
| 110 | */ |
||
| 111 | public $files; |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Get the headers request ($_SERVER). |
||
| 115 | * |
||
| 116 | * @var \Syscodes\Components\Http\Loaders\Headers $headers |
||
| 117 | */ |
||
| 118 | public $headers; |
||
| 119 | |||
| 120 | /** |
||
| 121 | * The decoded JSON content for the request. |
||
| 122 | * |
||
| 123 | * @var \Syscodes\Components\Http\Loaders\Parameters|null $json |
||
| 124 | */ |
||
| 125 | protected $json; |
||
| 126 | |||
| 127 | /** |
||
| 128 | * The current language of the application. |
||
| 129 | * |
||
| 130 | * @var string $languages |
||
| 131 | */ |
||
| 132 | protected $languages; |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Get the locale. |
||
| 136 | * |
||
| 137 | * @var string $locale |
||
| 138 | */ |
||
| 139 | protected $locale; |
||
| 140 | |||
| 141 | /** |
||
| 142 | * The method name. |
||
| 143 | * |
||
| 144 | * @var string $method |
||
| 145 | */ |
||
| 146 | protected $method; |
||
| 147 | |||
| 148 | /** |
||
| 149 | * The path info of URL. |
||
| 150 | * |
||
| 151 | * @var string $pathInfo |
||
| 152 | */ |
||
| 153 | protected $pathInfo; |
||
| 154 | |||
| 155 | /** |
||
| 156 | * Query string parameters ($_GET). |
||
| 157 | * |
||
| 158 | * @var \Syscodes\Components\Http\Loaders\Parameters $query |
||
| 159 | */ |
||
| 160 | public $query; |
||
| 161 | |||
| 162 | /** |
||
| 163 | * Request body parameters ($_POST). |
||
| 164 | * |
||
| 165 | * @var \Syscodes\Components\Http\Loaders\Parameters $request |
||
| 166 | */ |
||
| 167 | public $request; |
||
| 168 | |||
| 169 | /** |
||
| 170 | * Get request URI. |
||
| 171 | * |
||
| 172 | * @var string $requestToUri |
||
| 173 | */ |
||
| 174 | protected $requestToUri; |
||
| 175 | |||
| 176 | /** |
||
| 177 | * Get the route resolver callback. |
||
| 178 | * |
||
| 179 | * @var \Closure $routeResolver |
||
| 180 | */ |
||
| 181 | protected $routeResolver; |
||
| 182 | |||
| 183 | /** |
||
| 184 | * The Session implementation. |
||
| 185 | * |
||
| 186 | * @var \Syscodes\Components\Contracts\Session\Session $session |
||
| 187 | */ |
||
| 188 | protected $session; |
||
| 189 | |||
| 190 | /** |
||
| 191 | * The detected uri and server variables ($_SERVER). |
||
| 192 | * |
||
| 193 | * @var \Syscodes\Components\Http\Loaders\Server $server |
||
| 194 | */ |
||
| 195 | public $server; |
||
| 196 | |||
| 197 | /** |
||
| 198 | * List of routes uri. |
||
| 199 | * |
||
| 200 | * @var \Syscodes\Components\Http\URI $uri |
||
| 201 | */ |
||
| 202 | public $uri; |
||
| 203 | |||
| 204 | /** |
||
| 205 | * Stores the valid locale codes. |
||
| 206 | * |
||
| 207 | * @var array $validLocales |
||
| 208 | */ |
||
| 209 | protected $validLocales = []; |
||
| 210 | |||
| 211 | /** |
||
| 212 | * Constructor: Create new the Request class. |
||
| 213 | * |
||
| 214 | * @param array $query |
||
| 215 | * @param array $request |
||
| 216 | * @param array $attributes |
||
| 217 | * @param array $cookies |
||
| 218 | * @param array $files |
||
| 219 | * @param array $server |
||
| 220 | * @param string|resource|null $content |
||
| 221 | * |
||
| 222 | * @return void |
||
| 223 | */ |
||
| 224 | public function __construct( |
||
| 225 | array $query = [], |
||
| 226 | array $request = [], |
||
| 227 | array $attributes = [], |
||
| 228 | array $cookies = [], |
||
| 229 | array $files = [], |
||
| 230 | array $server = [], |
||
| 231 | $content = null |
||
| 232 | ) { |
||
| 233 | $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content); |
||
| 234 | |||
| 235 | $this->detectLocale(); |
||
| 236 | } |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Sets the parameters for this request. |
||
| 240 | * |
||
| 241 | * @param array $query |
||
| 242 | * @param array $request |
||
| 243 | * @param array $attributes |
||
| 244 | * @param array $cookies |
||
| 245 | * @param array $files |
||
| 246 | * @param array $server |
||
| 247 | * |
||
| 248 | * @return void |
||
| 249 | */ |
||
| 250 | public function initialize( |
||
| 251 | array $query = [], |
||
| 252 | array $request = [], |
||
| 253 | array $attributes = [], |
||
| 254 | array $cookies = [], |
||
| 255 | array $files = [], |
||
| 256 | array $server = [], |
||
| 257 | $content = null |
||
| 258 | ): void { |
||
| 259 | $this->query = new Inputs($query); |
||
| 260 | $this->request = new Inputs($request); |
||
| 261 | $this->attributes = new Parameters($attributes); |
||
| 262 | $this->cookies = new Inputs($cookies); |
||
| 263 | $this->files = new Files($files); |
||
| 264 | $this->server = new Server($server); |
||
| 265 | $this->headers = new Headers($this->server->all()); |
||
| 266 | |||
| 267 | // Variables initialized |
||
| 268 | $this->uri = new URI; |
||
| 269 | $this->method = null; |
||
| 270 | $this->baseUrl = null; |
||
| 271 | $this->content = $content; |
||
| 272 | $this->pathInfo = null; |
||
| 273 | $this->languages = null; |
||
| 274 | $this->acceptableContentTypes = null; |
||
| 275 | $this->validLocales = config('app.supportedLocales'); |
||
|
|
|||
| 276 | $this->clientIp = new RequestClientIP($this->server->all()); |
||
| 277 | } |
||
| 278 | |||
| 279 | /** |
||
| 280 | * Clones a request and overrides some of its parameters. |
||
| 281 | * |
||
| 282 | * @param array|null $query |
||
| 283 | * @param array|null $request |
||
| 284 | * @param array|null $attributes |
||
| 285 | * @param array|null $cookies |
||
| 286 | * @param array|null $files |
||
| 287 | * @param array|null $server |
||
| 288 | * |
||
| 289 | * @return static |
||
| 290 | */ |
||
| 291 | public function duplicate( |
||
| 292 | array $query = null, |
||
| 293 | array $request = null, |
||
| 294 | array $attributes = null, |
||
| 295 | array $cookies = null, |
||
| 296 | array $files = null, |
||
| 297 | array $server = null |
||
| 298 | ): static { |
||
| 299 | $duplicate = clone $this; |
||
| 300 | |||
| 301 | if (null !== $query) { |
||
| 302 | $duplicate->query = new Inputs($query); |
||
| 303 | } |
||
| 304 | |||
| 305 | if (null !== $request) { |
||
| 306 | $duplicate->request = new Inputs($request); |
||
| 307 | } |
||
| 308 | |||
| 309 | if (null !== $attributes) { |
||
| 310 | $duplicate->attributes = new Parameters($attributes); |
||
| 311 | } |
||
| 312 | |||
| 313 | if (null !== $cookies) { |
||
| 314 | $duplicate->cookies = new Inputs($cookies); |
||
| 315 | } |
||
| 316 | |||
| 317 | if (null !== $files) { |
||
| 318 | $duplicate->files = new Files($files); |
||
| 319 | } |
||
| 320 | |||
| 321 | if (null !== $server) { |
||
| 322 | $duplicate->server = new Server($server); |
||
| 323 | $duplicate->headers = new Headers($duplicate->server->all()); |
||
| 324 | } |
||
| 325 | |||
| 326 | $duplicate->uri = new URI; |
||
| 327 | $duplicate->locale = null; |
||
| 328 | $duplicate->method = null; |
||
| 329 | $duplicate->baseUrl = null; |
||
| 330 | $duplicate->pathInfo = null; |
||
| 331 | $duplicate->validLocales = config('app.supportedLocales'); |
||
| 332 | $duplicate->clientIp = new RequestClientIP($duplicate->server->all()); |
||
| 333 | |||
| 334 | return $duplicate; |
||
| 335 | } |
||
| 336 | |||
| 337 | /** |
||
| 338 | * Returns the desired segment, or $default if it does not exist. |
||
| 339 | * |
||
| 340 | * @param int $index The segment number (1-based index) |
||
| 341 | * @param mixed $default Default value to return |
||
| 342 | * |
||
| 343 | * @return string |
||
| 344 | */ |
||
| 345 | public function segment($index, $default = null) |
||
| 346 | { |
||
| 347 | return $this->uri->getSegment($index, $default); |
||
| 348 | } |
||
| 349 | |||
| 350 | /** |
||
| 351 | * Returns all segments in an array. For total of segments |
||
| 352 | * used the function PHP count(). |
||
| 353 | * |
||
| 354 | * @return array|null |
||
| 355 | */ |
||
| 356 | public function segments() |
||
| 357 | { |
||
| 358 | return $this->uri->getSegments(); |
||
| 359 | } |
||
| 360 | |||
| 361 | /** |
||
| 362 | * Returns the total number of segment. |
||
| 363 | * |
||
| 364 | * @return int|null |
||
| 365 | */ |
||
| 366 | public function totalSegments() |
||
| 367 | { |
||
| 368 | return $this->uri->getTotalSegments(); |
||
| 369 | } |
||
| 370 | |||
| 371 | /** |
||
| 372 | * Handles setting up the locale, auto-detecting of language. |
||
| 373 | * |
||
| 374 | * @return void |
||
| 375 | */ |
||
| 376 | public function detectLocale(): void |
||
| 377 | { |
||
| 378 | $this->languages = $this->defaultLocale = config('app.locale'); |
||
| 379 | |||
| 380 | $this->setLocale($this->validLocales[0]); |
||
| 381 | } |
||
| 382 | |||
| 383 | /** |
||
| 384 | * Returns the default locale as set. |
||
| 385 | * |
||
| 386 | * @return string |
||
| 387 | */ |
||
| 388 | public function getDefaultLocale(): string |
||
| 389 | { |
||
| 390 | return $this->defaultLocale; |
||
| 391 | } |
||
| 392 | |||
| 393 | /** |
||
| 394 | * Gets the current locale, with a fallback to the default. |
||
| 395 | * |
||
| 396 | * @return string |
||
| 397 | */ |
||
| 398 | public function getLocale(): string |
||
| 399 | { |
||
| 400 | return $this->languages ?: $this->defaultLocale; |
||
| 401 | } |
||
| 402 | |||
| 403 | /** |
||
| 404 | * Sets the locale string for this request. |
||
| 405 | * |
||
| 406 | * @param string $locale |
||
| 407 | * |
||
| 408 | * @return self |
||
| 409 | */ |
||
| 410 | public function setLocale(string $locale): self |
||
| 411 | { |
||
| 412 | if ( ! in_array($locale, $this->validLocales, true)) { |
||
| 413 | $locale = $this->defaultLocale; |
||
| 414 | } |
||
| 415 | |||
| 416 | $this->languages = $locale; |
||
| 417 | |||
| 418 | Locale::setDefault($locale); |
||
| 419 | |||
| 420 | return $this; |
||
| 421 | } |
||
| 422 | |||
| 423 | /** |
||
| 424 | * Returns the full request string. |
||
| 425 | * |
||
| 426 | * @param string $key |
||
| 427 | * @param mixed $default |
||
| 428 | * |
||
| 429 | * @return mixed |
||
| 430 | */ |
||
| 431 | public function get(string $key, $default = null) |
||
| 432 | { |
||
| 433 | if ($this !== $result = $this->attributes->get($key, $this)) { |
||
| 434 | return $result; |
||
| 435 | } |
||
| 436 | |||
| 437 | if ($this->query->has($key)) { |
||
| 438 | return $this->query->all()[$key]; |
||
| 439 | } |
||
| 440 | |||
| 441 | if ($this->request->has($key)) { |
||
| 442 | return $this->request->all()[$key]; |
||
| 443 | } |
||
| 444 | |||
| 445 | return $default; |
||
| 446 | } |
||
| 447 | |||
| 448 | /** |
||
| 449 | * Gets the Session. |
||
| 450 | * |
||
| 451 | * @return \Syscodes\Components\Http\Session\SessionInterface |
||
| 452 | * |
||
| 453 | * @throws \Syscodes\Components\Http\Exceptions\SessionNotFoundException |
||
| 454 | */ |
||
| 455 | public function getSession() |
||
| 456 | { |
||
| 457 | $this->hasSession() |
||
| 458 | ? new SessionDecorator($this->session()) |
||
| 459 | : throw new SessionNotFoundException; |
||
| 460 | } |
||
| 461 | |||
| 462 | /** |
||
| 463 | * Whether the request contains a Session object. |
||
| 464 | * |
||
| 465 | * @return bool |
||
| 466 | */ |
||
| 467 | public function hasSession(): bool |
||
| 468 | { |
||
| 469 | return ! is_null($this->session); |
||
| 470 | } |
||
| 471 | |||
| 472 | /** |
||
| 473 | * Get the session associated with the request. |
||
| 474 | * |
||
| 475 | * @return \Syscodes\Components\Contracts\Session\Session |
||
| 476 | * |
||
| 477 | * @throws RuntimeException |
||
| 478 | */ |
||
| 479 | public function session() |
||
| 480 | { |
||
| 481 | if ( ! $this->hasSession()) { |
||
| 482 | throw new RuntimeException('Session store not set on request'); |
||
| 483 | } |
||
| 484 | |||
| 485 | return $this->session; |
||
| 486 | } |
||
| 487 | |||
| 488 | /** |
||
| 489 | * Set the session instance on the request. |
||
| 490 | * |
||
| 491 | * @param \Syscodes\Components\Contracts\Session\Session $session |
||
| 492 | * |
||
| 493 | * @return void |
||
| 494 | */ |
||
| 495 | public function setSession($session): void |
||
| 496 | { |
||
| 497 | $this->session = $session; |
||
| 498 | } |
||
| 499 | |||
| 500 | /** |
||
| 501 | * Get the JSON payload for the request. |
||
| 502 | * |
||
| 503 | * @param string|null $key |
||
| 504 | * @param mixed $default |
||
| 505 | * |
||
| 506 | * @return \Syscodes\Components\Http\Utilities\Parameters|mixed |
||
| 507 | */ |
||
| 508 | public function json($key = null, $default = null) |
||
| 509 | { |
||
| 510 | if ( ! isset($this->json)) { |
||
| 511 | $this->json = new Parameters((array) json_decode($this->getContent(), true)); |
||
| 512 | } |
||
| 513 | |||
| 514 | if (is_null($key)) { |
||
| 515 | return $this->json; |
||
| 516 | } |
||
| 517 | |||
| 518 | return Arr::get($this->json->all(), $key, $default); |
||
| 519 | } |
||
| 520 | |||
| 521 | /** |
||
| 522 | * Set the JSON payload for the request. |
||
| 523 | * |
||
| 524 | * @param \Syscodes\Components\Http\Utilities\Parameters $json |
||
| 525 | * |
||
| 526 | * @return static |
||
| 527 | */ |
||
| 528 | public function setJson($json): static |
||
| 529 | { |
||
| 530 | $this->json = $json; |
||
| 531 | |||
| 532 | return $this; |
||
| 533 | } |
||
| 534 | |||
| 535 | /** |
||
| 536 | * Gets a list of content types acceptable by the client browser in preferable order. |
||
| 537 | * |
||
| 538 | * @return string[] |
||
| 539 | */ |
||
| 540 | public function getAcceptableContentTypes(): array |
||
| 541 | { |
||
| 542 | if (null !== $this->acceptableContentTypes) { |
||
| 543 | return $this->acceptableContentTypes; |
||
| 544 | } |
||
| 545 | |||
| 546 | return $this->acceptableContentTypes = array_map('strval', [$this->headers->get('Accept')]); |
||
| 547 | } |
||
| 548 | |||
| 549 | /** |
||
| 550 | * Returns whether this is an AJAX request or not. |
||
| 551 | * Alias of isXmlHttpRequest(). |
||
| 552 | * |
||
| 553 | * @return bool |
||
| 554 | */ |
||
| 555 | public function ajax(): bool |
||
| 556 | { |
||
| 557 | return $this->isXmlHttpRequest(); |
||
| 558 | } |
||
| 559 | |||
| 560 | /** |
||
| 561 | * Returns whether this is an AJAX request or not. |
||
| 562 | * |
||
| 563 | * @return bool |
||
| 564 | */ |
||
| 565 | public function isXmlHttpRequest(): bool |
||
| 566 | { |
||
| 567 | return ! empty($this->server->get('HTTP_X_REQUESTED_WITH')) && |
||
| 568 | strtolower($this->server->get('HTTP_X_REQUESTED_WITH')) === 'xmlhttprequest'; |
||
| 569 | } |
||
| 570 | |||
| 571 | /** |
||
| 572 | * Determine if the request is the result of a PJAX call. |
||
| 573 | * |
||
| 574 | * @return bool |
||
| 575 | */ |
||
| 576 | public function pjax(): bool |
||
| 577 | { |
||
| 578 | return $this->headers->get('X-PJAX') == true; |
||
| 579 | } |
||
| 580 | |||
| 581 | /** |
||
| 582 | * Determine if the request is the result of a prefetch call. |
||
| 583 | * |
||
| 584 | * @return bool |
||
| 585 | */ |
||
| 586 | public function prefetch(): bool |
||
| 587 | { |
||
| 588 | return strcasecmp($this->server->get('HTTP_X_MOZ') ?? '', 'prefetch') === 0 || |
||
| 589 | strcasecmp($this->headers->get('Purpose') ?? '', 'prefetch') === 0; |
||
| 590 | } |
||
| 591 | |||
| 592 | /** |
||
| 593 | * Checks if the method request is of specified type. |
||
| 594 | * |
||
| 595 | * @param string $method |
||
| 596 | * |
||
| 597 | * @return bool |
||
| 598 | */ |
||
| 599 | public function isMethod(string $method): bool |
||
| 600 | { |
||
| 601 | return $this->getMethod() === strtoupper($method); |
||
| 602 | } |
||
| 603 | |||
| 604 | /** |
||
| 605 | * Alias of the request method. |
||
| 606 | * |
||
| 607 | * @return string |
||
| 608 | */ |
||
| 609 | public function method(): string |
||
| 612 | } |
||
| 613 | |||
| 614 | /** |
||
| 615 | * Returns the input method used (GET, POST, DELETE, etc.). |
||
| 616 | * |
||
| 617 | * @return string |
||
| 618 | * |
||
| 619 | * @throws \LogicException |
||
| 620 | */ |
||
| 621 | public function getmethod(): string |
||
| 622 | { |
||
| 623 | if (null !== $this->method) { |
||
| 624 | return $this->method; |
||
| 625 | } |
||
| 626 | |||
| 627 | $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET')); |
||
| 628 | |||
| 629 | if ('POST' !== $this->method) { |
||
| 630 | return $this->method; |
||
| 631 | } |
||
| 632 | |||
| 633 | $method = $this->headers->get('X-HTTP-METHOD-OVERRIDE'); |
||
| 634 | |||
| 635 | if ( ! $method && self::$httpMethodParameterOverride) { |
||
| 636 | $method = $this->request->get('_method', $this->query->get('_method', 'POST')); |
||
| 637 | } |
||
| 638 | |||
| 639 | if ( ! is_string($method)) { |
||
| 640 | return $this->method; |
||
| 641 | } |
||
| 642 | |||
| 643 | $method = strtoupper($method); |
||
| 644 | |||
| 645 | if (in_array($method, ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'PATCH', 'PURGE', 'TRACE'], true)) { |
||
| 646 | return $this->method = $method; |
||
| 647 | } |
||
| 648 | |||
| 649 | if ( ! preg_match('/^[A-Z]++$/D', $method)) { |
||
| 650 | throw new LogicException(sprintf('Invalid method override "%s".', $method)); |
||
| 651 | } |
||
| 652 | |||
| 653 | return $this->method = $method; |
||
| 654 | } |
||
| 655 | |||
| 656 | /** |
||
| 657 | * Sets the request method. |
||
| 658 | * |
||
| 659 | * @param string $method |
||
| 660 | * |
||
| 661 | * @return void |
||
| 662 | */ |
||
| 663 | public function setMethod(string $method): void |
||
| 664 | { |
||
| 665 | $this->method = null; |
||
| 666 | |||
| 667 | $this->server->set('REQUEST_METHOD', $method); |
||
| 668 | } |
||
| 669 | |||
| 670 | /** |
||
| 671 | * Get the input source for the request. |
||
| 672 | * |
||
| 673 | * @return \Syscodes\Components\Http\Utilities\Parameters |
||
| 674 | */ |
||
| 675 | public function getInputSource() |
||
| 676 | { |
||
| 677 | if ($this->isJson()) { |
||
| 678 | return $this->json(); |
||
| 679 | } |
||
| 680 | |||
| 681 | return in_array($this->getMethod(), ['GET', 'HEAD']) ? $this->query : $this->request; |
||
| 682 | } |
||
| 683 | |||
| 684 | /** |
||
| 685 | * Determine if the current request URI matches a pattern. |
||
| 686 | * |
||
| 687 | * @param mixed ...$patterns |
||
| 688 | * |
||
| 689 | * @return bool |
||
| 690 | */ |
||
| 691 | public function is(...$patterns): bool |
||
| 692 | { |
||
| 693 | $path = $this->decodedPath(); |
||
| 694 | |||
| 695 | foreach ($patterns as $pattern) { |
||
| 696 | if (Str::is($pattern, $path)) { |
||
| 697 | return true; |
||
| 698 | } |
||
| 699 | } |
||
| 700 | |||
| 701 | return false; |
||
| 702 | } |
||
| 703 | |||
| 704 | /** |
||
| 705 | * Determine if the route name matches a given pattern. |
||
| 706 | * |
||
| 707 | * @param mixed ...$patterns |
||
| 708 | * |
||
| 709 | * @return bool |
||
| 710 | */ |
||
| 711 | public function routeIs(...$patterns): bool |
||
| 712 | { |
||
| 713 | return $this->route() && $this->route()->is(...$patterns); |
||
| 714 | } |
||
| 715 | |||
| 716 | /** |
||
| 717 | * Get the route handling the request. |
||
| 718 | * |
||
| 719 | * @param string|null $param |
||
| 720 | * @param mixed $default |
||
| 721 | * |
||
| 722 | * @return \Syscodes\Components\Routing\Route|object|string|null |
||
| 723 | */ |
||
| 724 | public function route($param = null, $default = null) |
||
| 725 | { |
||
| 726 | $route = call_user_func($this->getRouteResolver()); |
||
| 727 | |||
| 728 | if (is_null($route) || is_null($param)) { |
||
| 729 | return $route; |
||
| 730 | } |
||
| 731 | |||
| 732 | return $route->parameter($param, $default); |
||
| 733 | } |
||
| 734 | |||
| 735 | /** |
||
| 736 | * Get the current decoded path info for the request. |
||
| 737 | * |
||
| 738 | * @return string |
||
| 739 | */ |
||
| 740 | public function decodedPath(): string |
||
| 741 | { |
||
| 742 | return rawurldecode($this->path()); |
||
| 743 | } |
||
| 744 | |||
| 745 | /** |
||
| 746 | * Get the current path info for the request. |
||
| 747 | * |
||
| 748 | * @return string |
||
| 749 | */ |
||
| 750 | public function path(): string |
||
| 751 | { |
||
| 752 | $path = trim($this->getPathInfo(), '/'); |
||
| 753 | |||
| 754 | return $path == '' ? '/' : $path; |
||
| 755 | } |
||
| 756 | |||
| 757 | /** |
||
| 758 | * Get the full URL for the request. |
||
| 759 | * |
||
| 760 | * @return string |
||
| 761 | */ |
||
| 762 | public function fullUrl(): string |
||
| 763 | { |
||
| 764 | $query = $this->getQueryString(); |
||
| 765 | |||
| 766 | $question = $this->getBaseUrl().$this->getPathInfo() === '/' ? '/?' : '?'; |
||
| 767 | |||
| 768 | return $query ? $this->url().$question.$query : $this->url(); |
||
| 769 | } |
||
| 770 | |||
| 771 | /** |
||
| 772 | * Generates the normalized query string for the Request. |
||
| 773 | * |
||
| 774 | * @return string |
||
| 775 | */ |
||
| 776 | public function getQueryString(): ?string |
||
| 777 | { |
||
| 778 | $queryString = RequestUtils::normalizedQueryString($this->server->get('QUERY_STRING')); |
||
| 779 | |||
| 780 | return '' === $queryString ? null : $queryString; |
||
| 781 | } |
||
| 782 | |||
| 783 | /** |
||
| 784 | * Retunrs the request body content. |
||
| 785 | * |
||
| 786 | * @return string |
||
| 787 | */ |
||
| 788 | public function getContent(): string |
||
| 789 | { |
||
| 790 | if (null === $this->content || false === $this->content) { |
||
| 791 | $this->content = file_get_contents('php://input'); |
||
| 792 | } |
||
| 793 | |||
| 794 | return $this->content; |
||
| 795 | } |
||
| 796 | |||
| 797 | /** |
||
| 798 | * Returns the path being requested relative to the executed script. |
||
| 799 | * |
||
| 800 | * @return string |
||
| 801 | */ |
||
| 802 | public function getPathInfo(): string |
||
| 803 | { |
||
| 804 | if (null === $this->pathInfo) { |
||
| 805 | $this->pathInfo = $this->parsePathInfo(); |
||
| 806 | } |
||
| 807 | |||
| 808 | return $this->pathInfo; |
||
| 809 | } |
||
| 810 | |||
| 811 | /** |
||
| 812 | * Returns the root URL from which this request is executed. |
||
| 813 | * |
||
| 814 | * @return string |
||
| 815 | */ |
||
| 816 | public function getBaseUrl(): string |
||
| 817 | { |
||
| 818 | if (null === $this->baseUrl) { |
||
| 819 | $this->baseUrl = $this->parseBaseUrl(); |
||
| 820 | } |
||
| 821 | |||
| 822 | return $this->baseUrl; |
||
| 823 | } |
||
| 824 | |||
| 825 | /** |
||
| 826 | * Returns the requested URI. |
||
| 827 | * |
||
| 828 | * @return string |
||
| 829 | */ |
||
| 830 | public function getRequestUri(): string |
||
| 831 | { |
||
| 832 | if (null === $this->requestToUri) { |
||
| 833 | $this->requestToUri = $this->parseRequestUri(); |
||
| 834 | } |
||
| 835 | |||
| 836 | return $this->requestToUri; |
||
| 837 | } |
||
| 838 | |||
| 839 | /** |
||
| 840 | * Generates a normalized URI (URL) for the Request. |
||
| 841 | * |
||
| 842 | * @return string |
||
| 843 | */ |
||
| 844 | public function getUri(): string |
||
| 845 | { |
||
| 846 | if (null !== $query = $this->getQueryString()) { |
||
| 847 | $query = '?'.$query; |
||
| 848 | } |
||
| 849 | |||
| 850 | return $this->getSchemeWithHttpHost().$this->getBaseUrl().$this->getPathInfo().$query; |
||
| 851 | } |
||
| 852 | |||
| 853 | /** |
||
| 854 | * Gets the request's scheme. |
||
| 855 | * |
||
| 856 | * @return string |
||
| 857 | */ |
||
| 858 | public function getScheme(): string |
||
| 859 | { |
||
| 860 | return $this->secure() ? $this->uri->setScheme('https') : $this->uri->setScheme('http'); |
||
| 861 | } |
||
| 862 | |||
| 863 | /** |
||
| 864 | * Returns the host name. |
||
| 865 | * |
||
| 866 | * @return string |
||
| 867 | */ |
||
| 868 | public function getHost(): string |
||
| 869 | { |
||
| 870 | if ($forwardedHost = $this->server->get('HTTP_X_FORWARDED_HOST')) { |
||
| 871 | $host = $forwardedHost[0]; |
||
| 872 | } elseif ( ! $host = $this->headers->get('HOST')) { |
||
| 873 | if ( ! $host = $this->server->get('SERVER_NAME')) { |
||
| 874 | $host = $this->server->get('REMOTE_ADDR', ''); |
||
| 875 | } |
||
| 876 | } |
||
| 877 | |||
| 878 | $host = strtolower(preg_replace('/:\d+$/', '', trim(($host)))); |
||
| 879 | |||
| 880 | return $this->uri->setHost($host); |
||
| 881 | } |
||
| 882 | |||
| 883 | /** |
||
| 884 | * Returns the port on which the request is made. |
||
| 885 | * |
||
| 886 | * @return int |
||
| 887 | */ |
||
| 888 | public function getPort(): int |
||
| 889 | { |
||
| 890 | if ( ! $this->server->get('HTTP_HOST')) { |
||
| 891 | return $this->server->get('SERVER_PORT'); |
||
| 892 | } |
||
| 893 | |||
| 894 | return 'https' === $this->getScheme() ? $this->uri->setPort(443) : $this->uri->setPort(80); |
||
| 895 | } |
||
| 896 | |||
| 897 | /** |
||
| 898 | * Get the user. |
||
| 899 | * |
||
| 900 | * @return string|null |
||
| 901 | */ |
||
| 902 | public function getUser(): ?string |
||
| 903 | { |
||
| 904 | $user = $this->uri->setUser( |
||
| 905 | $this->headers->get('PHP_AUTH_USER') |
||
| 906 | ); |
||
| 907 | |||
| 908 | return $user; |
||
| 909 | } |
||
| 910 | |||
| 911 | /** |
||
| 912 | * Get the password. |
||
| 913 | * |
||
| 914 | * @return string|null |
||
| 915 | */ |
||
| 916 | public function getPassword(): ?string |
||
| 917 | { |
||
| 918 | $password = $this->uri->setPassword( |
||
| 919 | $this->headers->get('PHP_AUTH_PW') |
||
| 920 | ); |
||
| 921 | |||
| 922 | return $password; |
||
| 923 | } |
||
| 924 | |||
| 925 | /** |
||
| 926 | * Gets the user info. |
||
| 927 | * |
||
| 928 | * @return string|null |
||
| 929 | */ |
||
| 930 | public function getUserInfo(): ?string |
||
| 931 | { |
||
| 932 | return $this->uri->getUserInfo(); |
||
| 933 | } |
||
| 934 | |||
| 935 | /** |
||
| 936 | * Returns the HTTP host being requested. |
||
| 937 | * |
||
| 938 | * @return string |
||
| 939 | */ |
||
| 940 | public function getHttpHost(): string |
||
| 941 | { |
||
| 942 | $scheme = $this->getScheme(); |
||
| 943 | $port = $this->getPort(); |
||
| 944 | |||
| 945 | if (('http' === $scheme && 80 === $port) || ('https' === $scheme && 443 === $port)) { |
||
| 946 | return $this->getHost(); |
||
| 947 | } |
||
| 948 | |||
| 949 | return $this->getHost().':'.$port; |
||
| 950 | } |
||
| 951 | |||
| 952 | /** |
||
| 953 | * Gets the scheme and HTTP host. |
||
| 954 | * |
||
| 955 | * @return string |
||
| 956 | */ |
||
| 957 | public function getSchemeWithHttpHost(): string |
||
| 958 | { |
||
| 959 | return $this->getScheme().'://'.$this->getHttpHost(); |
||
| 960 | } |
||
| 961 | |||
| 962 | /** |
||
| 963 | * Get the root URL for the application. |
||
| 964 | * |
||
| 965 | * @return string |
||
| 966 | */ |
||
| 967 | public function root(): string |
||
| 968 | { |
||
| 969 | return rtrim($this->getSchemeWithHttpHost().$this->getBaseUrl(), '/'); |
||
| 970 | } |
||
| 971 | |||
| 972 | /** |
||
| 973 | * Get the URL for the request. |
||
| 974 | * |
||
| 975 | * @return string |
||
| 976 | */ |
||
| 977 | public function url(): string |
||
| 981 | } |
||
| 982 | |||
| 983 | /** |
||
| 984 | * Returns the referer. |
||
| 985 | * |
||
| 986 | * @param string $default |
||
| 987 | * |
||
| 988 | * @return string |
||
| 989 | */ |
||
| 990 | public function referer(string $default = ''): string |
||
| 991 | { |
||
| 992 | return $this->server->get('HTTP_REFERER', $default); |
||
| 993 | } |
||
| 994 | |||
| 995 | /** |
||
| 996 | * Attempts to detect if the current connection is secure through |
||
| 997 | * over HTTPS protocol. |
||
| 998 | * |
||
| 999 | * @return bool |
||
| 1000 | */ |
||
| 1001 | public function secure(): bool |
||
| 1002 | { |
||
| 1003 | if ( ! empty($this->server->get('HTTPS')) && strtolower($this->server->get('HTTPS')) !== 'off') { |
||
| 1004 | return true; |
||
| 1005 | } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $this->server->get('HTTP_X_FORWARDED_PROTO') === 'https') { |
||
| 1006 | return true; |
||
| 1007 | } elseif ( ! empty($this->server->get('HTTP_FRONT_END_HTTPS')) && strtolower($this->server->get('HTTP_FRONT_END_HTTPS')) !== 'off') { |
||
| 1008 | return true; |
||
| 1009 | } |
||
| 1010 | |||
| 1011 | return false; |
||
| 1012 | } |
||
| 1013 | |||
| 1014 | /** |
||
| 1015 | * Returns the user agent. |
||
| 1016 | * |
||
| 1017 | * @param string|null $default |
||
| 1018 | * |
||
| 1019 | * @return string |
||
| 1020 | */ |
||
| 1021 | public function userAgent(string $default = null): string |
||
| 1022 | { |
||
| 1023 | return $this->server->get('HTTP_USER_AGENT', $default); |
||
| 1024 | } |
||
| 1025 | |||
| 1026 | /** |
||
| 1027 | * Get the client IP address. |
||
| 1028 | * |
||
| 1029 | * @return string|null |
||
| 1030 | */ |
||
| 1031 | public function ip(): ?string |
||
| 1032 | { |
||
| 1033 | return $this->clientIp->getClientIp(); |
||
| 1034 | } |
||
| 1035 | |||
| 1036 | /** |
||
| 1037 | * Get the route resolver callback. |
||
| 1038 | * |
||
| 1039 | * @return \Closure |
||
| 1040 | */ |
||
| 1041 | public function getRouteResolver(): Closure |
||
| 1042 | { |
||
| 1043 | return $this->routeResolver ?: function () { |
||
| 1044 | // |
||
| 1045 | }; |
||
| 1046 | } |
||
| 1047 | |||
| 1048 | /** |
||
| 1049 | * Set the route resolver callback. |
||
| 1050 | * |
||
| 1051 | * @param \Closure $callback |
||
| 1052 | * |
||
| 1053 | * @return static |
||
| 1054 | */ |
||
| 1055 | public function setRouteResolver(Closure $callback): static |
||
| 1056 | { |
||
| 1057 | $this->routeResolver = $callback; |
||
| 1058 | |||
| 1059 | return $this; |
||
| 1060 | } |
||
| 1061 | |||
| 1062 | /** |
||
| 1063 | * Magic method. |
||
| 1064 | * |
||
| 1065 | * Get an element from the request. |
||
| 1066 | * |
||
| 1067 | * @return string[] |
||
| 1068 | */ |
||
| 1069 | public function __get($key) |
||
| 1070 | { |
||
| 1071 | return Arr::get($this->all(), $key, fn () => $this->route($key)); |
||
| 1072 | } |
||
| 1073 | |||
| 1074 | /** |
||
| 1075 | * Magic method. |
||
| 1076 | * |
||
| 1077 | * Returns the Request as an HTTP string. |
||
| 1078 | * |
||
| 1079 | * @return string |
||
| 1080 | */ |
||
| 1081 | public function __toString(): string |
||
| 1100 | } |
||
| 1101 | |||
| 1102 | /** |
||
| 1103 | * Magic method. |
||
| 1104 | * |
||
| 1105 | * Clones the current request. |
||
| 1106 | * |
||
| 1107 | * @return void |
||
| 1108 | */ |
||
| 1109 | public function __clone() |
||
| 1110 | { |
||
| 1111 | $this->query = clone $this->query; |
||
| 1112 | $this->request = clone $this->request; |
||
| 1113 | $this->attributes = clone $this->attributes; |
||
| 1114 | $this->cookies = clone $this->cookies; |
||
| 1115 | $this->files = clone $this->files; |
||
| 1116 | $this->server = clone $this->server; |
||
| 1117 | $this->headers = clone $this->headers; |
||
| 1118 | } |
||
| 1119 | } |
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
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. 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.