PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Http/Request.php

https://gitlab.com/ealexis.t/trends
PHP | 1058 lines | 468 code | 142 blank | 448 comment | 44 complexity | c347df0bde85ac4c38a9037b45f48e0a MD5 | raw file
  1. <?php
  2. namespace Illuminate\Http;
  3. use Closure;
  4. use ArrayAccess;
  5. use SplFileInfo;
  6. use RuntimeException;
  7. use Illuminate\Support\Arr;
  8. use Illuminate\Support\Str;
  9. use Illuminate\Support\Traits\Macroable;
  10. use Illuminate\Contracts\Support\Arrayable;
  11. use Symfony\Component\HttpFoundation\ParameterBag;
  12. use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
  13. class Request extends SymfonyRequest implements Arrayable, ArrayAccess
  14. {
  15. use Macroable;
  16. /**
  17. * The decoded JSON content for the request.
  18. *
  19. * @var string
  20. */
  21. protected $json;
  22. /**
  23. * All of the converted files for the request.
  24. *
  25. * @var array
  26. */
  27. protected $convertedFiles;
  28. /**
  29. * The user resolver callback.
  30. *
  31. * @var \Closure
  32. */
  33. protected $userResolver;
  34. /**
  35. * The route resolver callback.
  36. *
  37. * @var \Closure
  38. */
  39. protected $routeResolver;
  40. /**
  41. * Create a new Illuminate HTTP request from server variables.
  42. *
  43. * @return static
  44. */
  45. public static function capture()
  46. {
  47. static::enableHttpMethodParameterOverride();
  48. return static::createFromBase(SymfonyRequest::createFromGlobals());
  49. }
  50. /**
  51. * Return the Request instance.
  52. *
  53. * @return $this
  54. */
  55. public function instance()
  56. {
  57. return $this;
  58. }
  59. /**
  60. * Get the request method.
  61. *
  62. * @return string
  63. */
  64. public function method()
  65. {
  66. return $this->getMethod();
  67. }
  68. /**
  69. * Get the root URL for the application.
  70. *
  71. * @return string
  72. */
  73. public function root()
  74. {
  75. return rtrim($this->getSchemeAndHttpHost().$this->getBaseUrl(), '/');
  76. }
  77. /**
  78. * Get the URL (no query string) for the request.
  79. *
  80. * @return string
  81. */
  82. public function url()
  83. {
  84. return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/');
  85. }
  86. /**
  87. * Get the full URL for the request.
  88. *
  89. * @return string
  90. */
  91. public function fullUrl()
  92. {
  93. $query = $this->getQueryString();
  94. $question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';
  95. return $query ? $this->url().$question.$query : $this->url();
  96. }
  97. /**
  98. * Get the full URL for the request with the added query string parameters.
  99. *
  100. * @param array $query
  101. * @return string
  102. */
  103. public function fullUrlWithQuery(array $query)
  104. {
  105. return count($this->query()) > 0
  106. ? $this->url().'/?'.http_build_query(array_merge($this->query(), $query))
  107. : $this->fullUrl().'?'.http_build_query($query);
  108. }
  109. /**
  110. * Get the current path info for the request.
  111. *
  112. * @return string
  113. */
  114. public function path()
  115. {
  116. $pattern = trim($this->getPathInfo(), '/');
  117. return $pattern == '' ? '/' : $pattern;
  118. }
  119. /**
  120. * Get the current encoded path info for the request.
  121. *
  122. * @return string
  123. */
  124. public function decodedPath()
  125. {
  126. return rawurldecode($this->path());
  127. }
  128. /**
  129. * Get a segment from the URI (1 based index).
  130. *
  131. * @param int $index
  132. * @param string|null $default
  133. * @return string|null
  134. */
  135. public function segment($index, $default = null)
  136. {
  137. return Arr::get($this->segments(), $index - 1, $default);
  138. }
  139. /**
  140. * Get all of the segments for the request path.
  141. *
  142. * @return array
  143. */
  144. public function segments()
  145. {
  146. $segments = explode('/', $this->path());
  147. return array_values(array_filter($segments, function ($v) {
  148. return $v != '';
  149. }));
  150. }
  151. /**
  152. * Determine if the current request URI matches a pattern.
  153. *
  154. * @param mixed string
  155. * @return bool
  156. */
  157. public function is()
  158. {
  159. foreach (func_get_args() as $pattern) {
  160. if (Str::is($pattern, urldecode($this->path()))) {
  161. return true;
  162. }
  163. }
  164. return false;
  165. }
  166. /**
  167. * Determine if the current request URL and query string matches a pattern.
  168. *
  169. * @param mixed string
  170. * @return bool
  171. */
  172. public function fullUrlIs()
  173. {
  174. $url = $this->fullUrl();
  175. foreach (func_get_args() as $pattern) {
  176. if (Str::is($pattern, $url)) {
  177. return true;
  178. }
  179. }
  180. return false;
  181. }
  182. /**
  183. * Determine if the request is the result of an AJAX call.
  184. *
  185. * @return bool
  186. */
  187. public function ajax()
  188. {
  189. return $this->isXmlHttpRequest();
  190. }
  191. /**
  192. * Determine if the request is the result of an PJAX call.
  193. *
  194. * @return bool
  195. */
  196. public function pjax()
  197. {
  198. return $this->headers->get('X-PJAX') == true;
  199. }
  200. /**
  201. * Determine if the request is over HTTPS.
  202. *
  203. * @return bool
  204. */
  205. public function secure()
  206. {
  207. return $this->isSecure();
  208. }
  209. /**
  210. * Returns the client IP address.
  211. *
  212. * @return string
  213. */
  214. public function ip()
  215. {
  216. return $this->getClientIp();
  217. }
  218. /**
  219. * Returns the client IP addresses.
  220. *
  221. * @return array
  222. */
  223. public function ips()
  224. {
  225. return $this->getClientIps();
  226. }
  227. /**
  228. * Determine if the request contains a given input item key.
  229. *
  230. * @param string|array $key
  231. * @return bool
  232. */
  233. public function exists($key)
  234. {
  235. $keys = is_array($key) ? $key : func_get_args();
  236. $input = $this->all();
  237. foreach ($keys as $value) {
  238. if (! array_key_exists($value, $input)) {
  239. return false;
  240. }
  241. }
  242. return true;
  243. }
  244. /**
  245. * Determine if the request contains a non-empty value for an input item.
  246. *
  247. * @param string|array $key
  248. * @return bool
  249. */
  250. public function has($key)
  251. {
  252. $keys = is_array($key) ? $key : func_get_args();
  253. foreach ($keys as $value) {
  254. if ($this->isEmptyString($value)) {
  255. return false;
  256. }
  257. }
  258. return true;
  259. }
  260. /**
  261. * Determine if the given input key is an empty string for "has".
  262. *
  263. * @param string $key
  264. * @return bool
  265. */
  266. protected function isEmptyString($key)
  267. {
  268. $value = $this->input($key);
  269. $boolOrArray = is_bool($value) || is_array($value);
  270. return ! $boolOrArray && trim((string) $value) === '';
  271. }
  272. /**
  273. * Get all of the input and files for the request.
  274. *
  275. * @return array
  276. */
  277. public function all()
  278. {
  279. return array_replace_recursive($this->input(), $this->allFiles());
  280. }
  281. /**
  282. * Retrieve an input item from the request.
  283. *
  284. * @param string $key
  285. * @param string|array|null $default
  286. * @return string|array
  287. */
  288. public function input($key = null, $default = null)
  289. {
  290. $input = $this->getInputSource()->all() + $this->query->all();
  291. return data_get($input, $key, $default);
  292. }
  293. /**
  294. * Get a subset of the items from the input data.
  295. *
  296. * @param array|mixed $keys
  297. * @return array
  298. */
  299. public function only($keys)
  300. {
  301. $keys = is_array($keys) ? $keys : func_get_args();
  302. $results = [];
  303. $input = $this->all();
  304. foreach ($keys as $key) {
  305. Arr::set($results, $key, data_get($input, $key));
  306. }
  307. return $results;
  308. }
  309. /**
  310. * Get all of the input except for a specified array of items.
  311. *
  312. * @param array|mixed $keys
  313. * @return array
  314. */
  315. public function except($keys)
  316. {
  317. $keys = is_array($keys) ? $keys : func_get_args();
  318. $results = $this->all();
  319. Arr::forget($results, $keys);
  320. return $results;
  321. }
  322. /**
  323. * Intersect an array of items with the input data.
  324. *
  325. * @param array|mixed $keys
  326. * @return array
  327. */
  328. public function intersect($keys)
  329. {
  330. return array_filter($this->only(is_array($keys) ? $keys : func_get_args()));
  331. }
  332. /**
  333. * Retrieve a query string item from the request.
  334. *
  335. * @param string $key
  336. * @param string|array|null $default
  337. * @return string|array
  338. */
  339. public function query($key = null, $default = null)
  340. {
  341. return $this->retrieveItem('query', $key, $default);
  342. }
  343. /**
  344. * Determine if a cookie is set on the request.
  345. *
  346. * @param string $key
  347. * @return bool
  348. */
  349. public function hasCookie($key)
  350. {
  351. return ! is_null($this->cookie($key));
  352. }
  353. /**
  354. * Retrieve a cookie from the request.
  355. *
  356. * @param string $key
  357. * @param string|array|null $default
  358. * @return string|array
  359. */
  360. public function cookie($key = null, $default = null)
  361. {
  362. return $this->retrieveItem('cookies', $key, $default);
  363. }
  364. /**
  365. * Get an array of all of the files on the request.
  366. *
  367. * @return array
  368. */
  369. public function allFiles()
  370. {
  371. $files = $this->files->all();
  372. return $this->convertedFiles
  373. ? $this->convertedFiles
  374. : $this->convertedFiles = $this->convertUploadedFiles($files);
  375. }
  376. /**
  377. * Convert the given array of Symfony UploadedFiles to custom Laravel UploadedFiles.
  378. *
  379. * @param array $files
  380. * @return array
  381. */
  382. protected function convertUploadedFiles(array $files)
  383. {
  384. return array_map(function ($file) {
  385. if (is_null($file) || (is_array($file) && empty(array_filter($file)))) {
  386. return $file;
  387. }
  388. return is_array($file)
  389. ? $this->convertUploadedFiles($file)
  390. : UploadedFile::createFromBase($file);
  391. }, $files);
  392. }
  393. /**
  394. * Retrieve a file from the request.
  395. *
  396. * @param string $key
  397. * @param mixed $default
  398. * @return \Symfony\Component\HttpFoundation\File\UploadedFile|array|null
  399. */
  400. public function file($key = null, $default = null)
  401. {
  402. return data_get($this->allFiles(), $key, $default);
  403. }
  404. /**
  405. * Determine if the uploaded data contains a file.
  406. *
  407. * @param string $key
  408. * @return bool
  409. */
  410. public function hasFile($key)
  411. {
  412. if (! is_array($files = $this->file($key))) {
  413. $files = [$files];
  414. }
  415. foreach ($files as $file) {
  416. if ($this->isValidFile($file)) {
  417. return true;
  418. }
  419. }
  420. return false;
  421. }
  422. /**
  423. * Check that the given file is a valid file instance.
  424. *
  425. * @param mixed $file
  426. * @return bool
  427. */
  428. protected function isValidFile($file)
  429. {
  430. return $file instanceof SplFileInfo && $file->getPath() != '';
  431. }
  432. /**
  433. * Determine if a header is set on the request.
  434. *
  435. * @param string $key
  436. * @return bool
  437. */
  438. public function hasHeader($key)
  439. {
  440. return ! is_null($this->header($key));
  441. }
  442. /**
  443. * Retrieve a header from the request.
  444. *
  445. * @param string $key
  446. * @param string|array|null $default
  447. * @return string|array
  448. */
  449. public function header($key = null, $default = null)
  450. {
  451. return $this->retrieveItem('headers', $key, $default);
  452. }
  453. /**
  454. * Retrieve a server variable from the request.
  455. *
  456. * @param string $key
  457. * @param string|array|null $default
  458. * @return string|array
  459. */
  460. public function server($key = null, $default = null)
  461. {
  462. return $this->retrieveItem('server', $key, $default);
  463. }
  464. /**
  465. * Retrieve an old input item.
  466. *
  467. * @param string $key
  468. * @param string|array|null $default
  469. * @return string|array
  470. */
  471. public function old($key = null, $default = null)
  472. {
  473. return $this->session()->getOldInput($key, $default);
  474. }
  475. /**
  476. * Flash the input for the current request to the session.
  477. *
  478. * @param string $filter
  479. * @param array $keys
  480. * @return void
  481. */
  482. public function flash($filter = null, $keys = [])
  483. {
  484. $flash = (! is_null($filter)) ? $this->$filter($keys) : $this->input();
  485. $this->session()->flashInput($flash);
  486. }
  487. /**
  488. * Flash only some of the input to the session.
  489. *
  490. * @param array|mixed $keys
  491. * @return void
  492. */
  493. public function flashOnly($keys)
  494. {
  495. $keys = is_array($keys) ? $keys : func_get_args();
  496. return $this->flash('only', $keys);
  497. }
  498. /**
  499. * Flash only some of the input to the session.
  500. *
  501. * @param array|mixed $keys
  502. * @return void
  503. */
  504. public function flashExcept($keys)
  505. {
  506. $keys = is_array($keys) ? $keys : func_get_args();
  507. return $this->flash('except', $keys);
  508. }
  509. /**
  510. * Flush all of the old input from the session.
  511. *
  512. * @return void
  513. */
  514. public function flush()
  515. {
  516. $this->session()->flashInput([]);
  517. }
  518. /**
  519. * Retrieve a parameter item from a given source.
  520. *
  521. * @param string $source
  522. * @param string $key
  523. * @param string|array|null $default
  524. * @return string|array
  525. */
  526. protected function retrieveItem($source, $key, $default)
  527. {
  528. if (is_null($key)) {
  529. return $this->$source->all();
  530. }
  531. return $this->$source->get($key, $default);
  532. }
  533. /**
  534. * Merge new input into the current request's input array.
  535. *
  536. * @param array $input
  537. * @return void
  538. */
  539. public function merge(array $input)
  540. {
  541. $this->getInputSource()->add($input);
  542. }
  543. /**
  544. * Replace the input for the current request.
  545. *
  546. * @param array $input
  547. * @return void
  548. */
  549. public function replace(array $input)
  550. {
  551. $this->getInputSource()->replace($input);
  552. }
  553. /**
  554. * Get the JSON payload for the request.
  555. *
  556. * @param string $key
  557. * @param mixed $default
  558. * @return mixed
  559. */
  560. public function json($key = null, $default = null)
  561. {
  562. if (! isset($this->json)) {
  563. $this->json = new ParameterBag((array) json_decode($this->getContent(), true));
  564. }
  565. if (is_null($key)) {
  566. return $this->json;
  567. }
  568. return data_get($this->json->all(), $key, $default);
  569. }
  570. /**
  571. * Get the input source for the request.
  572. *
  573. * @return \Symfony\Component\HttpFoundation\ParameterBag
  574. */
  575. protected function getInputSource()
  576. {
  577. if ($this->isJson()) {
  578. return $this->json();
  579. }
  580. return $this->getMethod() == 'GET' ? $this->query : $this->request;
  581. }
  582. /**
  583. * Determine if the given content types match.
  584. *
  585. * @param string $actual
  586. * @param string $type
  587. * @return bool
  588. */
  589. public static function matchesType($actual, $type)
  590. {
  591. if ($actual === $type) {
  592. return true;
  593. }
  594. $split = explode('/', $actual);
  595. return isset($split[1]) && preg_match('#'.preg_quote($split[0], '#').'/.+\+'.preg_quote($split[1], '#').'#', $type);
  596. }
  597. /**
  598. * Determine if the request is sending JSON.
  599. *
  600. * @return bool
  601. */
  602. public function isJson()
  603. {
  604. return Str::contains($this->header('CONTENT_TYPE'), ['/json', '+json']);
  605. }
  606. /**
  607. * Determine if the current request is asking for JSON in return.
  608. *
  609. * @return bool
  610. */
  611. public function wantsJson()
  612. {
  613. $acceptable = $this->getAcceptableContentTypes();
  614. return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
  615. }
  616. /**
  617. * Determines whether the current requests accepts a given content type.
  618. *
  619. * @param string|array $contentTypes
  620. * @return bool
  621. */
  622. public function accepts($contentTypes)
  623. {
  624. $accepts = $this->getAcceptableContentTypes();
  625. if (count($accepts) === 0) {
  626. return true;
  627. }
  628. $types = (array) $contentTypes;
  629. foreach ($accepts as $accept) {
  630. if ($accept === '*/*' || $accept === '*') {
  631. return true;
  632. }
  633. foreach ($types as $type) {
  634. if ($this->matchesType($accept, $type) || $accept === strtok($type, '/').'/*') {
  635. return true;
  636. }
  637. }
  638. }
  639. return false;
  640. }
  641. /**
  642. * Return the most suitable content type from the given array based on content negotiation.
  643. *
  644. * @param string|array $contentTypes
  645. * @return string|null
  646. */
  647. public function prefers($contentTypes)
  648. {
  649. $accepts = $this->getAcceptableContentTypes();
  650. $contentTypes = (array) $contentTypes;
  651. foreach ($accepts as $accept) {
  652. if (in_array($accept, ['*/*', '*'])) {
  653. return $contentTypes[0];
  654. }
  655. foreach ($contentTypes as $contentType) {
  656. $type = $contentType;
  657. if (! is_null($mimeType = $this->getMimeType($contentType))) {
  658. $type = $mimeType;
  659. }
  660. if ($this->matchesType($type, $accept) || $accept === strtok($type, '/').'/*') {
  661. return $contentType;
  662. }
  663. }
  664. }
  665. }
  666. /**
  667. * Determines whether a request accepts JSON.
  668. *
  669. * @return bool
  670. */
  671. public function acceptsJson()
  672. {
  673. return $this->accepts('application/json');
  674. }
  675. /**
  676. * Determines whether a request accepts HTML.
  677. *
  678. * @return bool
  679. */
  680. public function acceptsHtml()
  681. {
  682. return $this->accepts('text/html');
  683. }
  684. /**
  685. * Get the data format expected in the response.
  686. *
  687. * @param string $default
  688. * @return string
  689. */
  690. public function format($default = 'html')
  691. {
  692. foreach ($this->getAcceptableContentTypes() as $type) {
  693. if ($format = $this->getFormat($type)) {
  694. return $format;
  695. }
  696. }
  697. return $default;
  698. }
  699. /**
  700. * Get the bearer token from the request headers.
  701. *
  702. * @return string|null
  703. */
  704. public function bearerToken()
  705. {
  706. $header = $this->header('Authorization', '');
  707. if (Str::startsWith($header, 'Bearer ')) {
  708. return Str::substr($header, 7);
  709. }
  710. }
  711. /**
  712. * Create an Illuminate request from a Symfony instance.
  713. *
  714. * @param \Symfony\Component\HttpFoundation\Request $request
  715. * @return \Illuminate\Http\Request
  716. */
  717. public static function createFromBase(SymfonyRequest $request)
  718. {
  719. if ($request instanceof static) {
  720. return $request;
  721. }
  722. $content = $request->content;
  723. $request = (new static)->duplicate(
  724. $request->query->all(), $request->request->all(), $request->attributes->all(),
  725. $request->cookies->all(), $request->files->all(), $request->server->all()
  726. );
  727. $request->content = $content;
  728. $request->request = $request->getInputSource();
  729. return $request;
  730. }
  731. /**
  732. * {@inheritdoc}
  733. */
  734. public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
  735. {
  736. return parent::duplicate($query, $request, $attributes, $cookies, array_filter((array) $files), $server);
  737. }
  738. /**
  739. * Get the session associated with the request.
  740. *
  741. * @return \Illuminate\Session\Store
  742. *
  743. * @throws \RuntimeException
  744. */
  745. public function session()
  746. {
  747. if (! $this->hasSession()) {
  748. throw new RuntimeException('Session store not set on request.');
  749. }
  750. return $this->getSession();
  751. }
  752. /**
  753. * Get the user making the request.
  754. *
  755. * @param string|null $guard
  756. * @return mixed
  757. */
  758. public function user($guard = null)
  759. {
  760. return call_user_func($this->getUserResolver(), $guard);
  761. }
  762. /**
  763. * Get the route handling the request.
  764. *
  765. * @param string|null $param
  766. *
  767. * @return \Illuminate\Routing\Route|object|string
  768. */
  769. public function route($param = null)
  770. {
  771. $route = call_user_func($this->getRouteResolver());
  772. if (is_null($route) || is_null($param)) {
  773. return $route;
  774. } else {
  775. return $route->parameter($param);
  776. }
  777. }
  778. /**
  779. * Get a unique fingerprint for the request / route / IP address.
  780. *
  781. * @return string
  782. *
  783. * @throws \RuntimeException
  784. */
  785. public function fingerprint()
  786. {
  787. if (! $this->route()) {
  788. throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');
  789. }
  790. return sha1(
  791. implode('|', $this->route()->methods()).
  792. '|'.$this->route()->domain().
  793. '|'.$this->route()->uri().
  794. '|'.$this->ip()
  795. );
  796. }
  797. /**
  798. * Get the user resolver callback.
  799. *
  800. * @return \Closure
  801. */
  802. public function getUserResolver()
  803. {
  804. return $this->userResolver ?: function () {
  805. //
  806. };
  807. }
  808. /**
  809. * Set the user resolver callback.
  810. *
  811. * @param \Closure $callback
  812. * @return $this
  813. */
  814. public function setUserResolver(Closure $callback)
  815. {
  816. $this->userResolver = $callback;
  817. return $this;
  818. }
  819. /**
  820. * Get the route resolver callback.
  821. *
  822. * @return \Closure
  823. */
  824. public function getRouteResolver()
  825. {
  826. return $this->routeResolver ?: function () {
  827. //
  828. };
  829. }
  830. /**
  831. * Set the route resolver callback.
  832. *
  833. * @param \Closure $callback
  834. * @return $this
  835. */
  836. public function setRouteResolver(Closure $callback)
  837. {
  838. $this->routeResolver = $callback;
  839. return $this;
  840. }
  841. /**
  842. * Get all of the input and files for the request.
  843. *
  844. * @return array
  845. */
  846. public function toArray()
  847. {
  848. return $this->all();
  849. }
  850. /**
  851. * Determine if the given offset exists.
  852. *
  853. * @param string $offset
  854. * @return bool
  855. */
  856. public function offsetExists($offset)
  857. {
  858. return array_key_exists($offset, $this->all());
  859. }
  860. /**
  861. * Get the value at the given offset.
  862. *
  863. * @param string $offset
  864. * @return mixed
  865. */
  866. public function offsetGet($offset)
  867. {
  868. return data_get($this->all(), $offset);
  869. }
  870. /**
  871. * Set the value at the given offset.
  872. *
  873. * @param string $offset
  874. * @param mixed $value
  875. * @return void
  876. */
  877. public function offsetSet($offset, $value)
  878. {
  879. return $this->getInputSource()->set($offset, $value);
  880. }
  881. /**
  882. * Remove the value at the given offset.
  883. *
  884. * @param string $offset
  885. * @return void
  886. */
  887. public function offsetUnset($offset)
  888. {
  889. return $this->getInputSource()->remove($offset);
  890. }
  891. /**
  892. * Check if an input element is set on the request.
  893. *
  894. * @param string $key
  895. * @return bool
  896. */
  897. public function __isset($key)
  898. {
  899. return ! is_null($this->__get($key));
  900. }
  901. /**
  902. * Get an input element from the request.
  903. *
  904. * @param string $key
  905. * @return mixed
  906. */
  907. public function __get($key)
  908. {
  909. $all = $this->all();
  910. if (array_key_exists($key, $all)) {
  911. return $all[$key];
  912. } else {
  913. return $this->route($key);
  914. }
  915. }
  916. }