UriPartsFilter.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * @package Grav\Framework\Uri
  4. *
  5. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Framework\Uri;
  9. /**
  10. * Class Uri
  11. * @package Grav\Framework\Uri
  12. */
  13. class UriPartsFilter
  14. {
  15. const HOSTNAME_REGEX = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/u';
  16. /**
  17. * @param string $scheme
  18. * @return string
  19. * @throws \InvalidArgumentException If the scheme is invalid.
  20. */
  21. public static function filterScheme($scheme)
  22. {
  23. if (!\is_string($scheme)) {
  24. throw new \InvalidArgumentException('Uri scheme must be a string');
  25. }
  26. return strtolower($scheme);
  27. }
  28. /**
  29. * Filters the user info string.
  30. *
  31. * @param string $info The raw user or password.
  32. * @return string The percent-encoded user or password string.
  33. * @throws \InvalidArgumentException
  34. */
  35. public static function filterUserInfo($info)
  36. {
  37. if (!\is_string($info)) {
  38. throw new \InvalidArgumentException('Uri user info must be a string');
  39. }
  40. return preg_replace_callback(
  41. '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u',
  42. function ($match) {
  43. return rawurlencode($match[0]);
  44. },
  45. $info
  46. ) ?? '';
  47. }
  48. /**
  49. * @param string $host
  50. * @return string
  51. * @throws \InvalidArgumentException If the host is invalid.
  52. */
  53. public static function filterHost($host)
  54. {
  55. if (!\is_string($host)) {
  56. throw new \InvalidArgumentException('Uri host must be a string');
  57. }
  58. if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
  59. $host = '[' . $host . ']';
  60. } elseif ($host && preg_match(static::HOSTNAME_REGEX, $host) !== 1) {
  61. throw new \InvalidArgumentException('Uri host name validation failed');
  62. }
  63. return strtolower($host);
  64. }
  65. /**
  66. * Filter Uri port.
  67. *
  68. * This method
  69. *
  70. * @param int|null $port
  71. * @return int|null
  72. * @throws \InvalidArgumentException If the port is invalid.
  73. */
  74. public static function filterPort($port = null)
  75. {
  76. if (null === $port || (\is_int($port) && ($port >= 0 && $port <= 65535))) {
  77. return $port;
  78. }
  79. throw new \InvalidArgumentException('Uri port must be null or an integer between 0 and 65535');
  80. }
  81. /**
  82. * Filter Uri path.
  83. *
  84. * This method percent-encodes all reserved characters in the provided path string. This method
  85. * will NOT double-encode characters that are already percent-encoded.
  86. *
  87. * @param string $path The raw uri path.
  88. * @return string The RFC 3986 percent-encoded uri path.
  89. * @throws \InvalidArgumentException If the path is invalid.
  90. * @link http://www.faqs.org/rfcs/rfc3986.html
  91. */
  92. public static function filterPath($path)
  93. {
  94. if (!\is_string($path)) {
  95. throw new \InvalidArgumentException('Uri path must be a string');
  96. }
  97. return preg_replace_callback(
  98. '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u',
  99. function ($match) {
  100. return rawurlencode($match[0]);
  101. },
  102. $path
  103. ) ?? '';
  104. }
  105. /**
  106. * Filters the query string or fragment of a URI.
  107. *
  108. * @param string $query The raw uri query string.
  109. * @return string The percent-encoded query string.
  110. * @throws \InvalidArgumentException If the query is invalid.
  111. */
  112. public static function filterQueryOrFragment($query)
  113. {
  114. if (!\is_string($query)) {
  115. throw new \InvalidArgumentException('Uri query string and fragment must be a string');
  116. }
  117. return preg_replace_callback(
  118. '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u',
  119. function ($match) {
  120. return rawurlencode($match[0]);
  121. },
  122. $query
  123. ) ?? '';
  124. }
  125. }