[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/php-ai-client/third-party/Nyholm/Psr7/ -> Uri.php (source)

   1  <?php
   2  
   3  declare (strict_types=1);
   4  namespace WordPress\AiClientDependencies\Nyholm\Psr7;
   5  
   6  use WordPress\AiClientDependencies\Psr\Http\Message\UriInterface;
   7  /**
   8   * PSR-7 URI implementation.
   9   *
  10   * @author Michael Dowling
  11   * @author Tobias Schultze
  12   * @author Matthew Weier O'Phinney
  13   * @author Tobias Nyholm <tobias.nyholm@gmail.com>
  14   * @author Martijn van der Ven <martijn@vanderven.se>
  15   *
  16   * @final This class should never be extended. See https://github.com/Nyholm/psr7/blob/master/doc/final.md
  17   */
  18  class Uri implements UriInterface
  19  {
  20      private const SCHEMES = ['http' => 80, 'https' => 443];
  21      private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
  22      private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
  23      private const CHAR_GEN_DELIMS = ':\/\?#\[\]@';
  24      /** @var string Uri scheme. */
  25      private $scheme = '';
  26      /** @var string Uri user info. */
  27      private $userInfo = '';
  28      /** @var string Uri host. */
  29      private $host = '';
  30      /** @var int|null Uri port. */
  31      private $port;
  32      /** @var string Uri path. */
  33      private $path = '';
  34      /** @var string Uri query string. */
  35      private $query = '';
  36      /** @var string Uri fragment. */
  37      private $fragment = '';
  38      public function __construct(string $uri = '')
  39      {
  40          if ('' !== $uri) {
  41              if (\false === $parts = \parse_url($uri)) {
  42                  throw new \InvalidArgumentException(\sprintf('Unable to parse URI: "%s"', $uri));
  43              }
  44              // Apply parse_url parts to a URI.
  45              $this->scheme = isset($parts['scheme']) ? \strtr($parts['scheme'], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') : '';
  46              $this->userInfo = $parts['user'] ?? '';
  47              $this->host = isset($parts['host']) ? \strtr($parts['host'], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') : '';
  48              $this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null;
  49              $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : '';
  50              $this->query = isset($parts['query']) ? $this->filterQueryAndFragment($parts['query']) : '';
  51              $this->fragment = isset($parts['fragment']) ? $this->filterQueryAndFragment($parts['fragment']) : '';
  52              if (isset($parts['pass'])) {
  53                  $this->userInfo .= ':' . $parts['pass'];
  54              }
  55          }
  56      }
  57      public function __toString(): string
  58      {
  59          return self::createUriString($this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment);
  60      }
  61      public function getScheme(): string
  62      {
  63          return $this->scheme;
  64      }
  65      public function getAuthority(): string
  66      {
  67          if ('' === $this->host) {
  68              return '';
  69          }
  70          $authority = $this->host;
  71          if ('' !== $this->userInfo) {
  72              $authority = $this->userInfo . '@' . $authority;
  73          }
  74          if (null !== $this->port) {
  75              $authority .= ':' . $this->port;
  76          }
  77          return $authority;
  78      }
  79      public function getUserInfo(): string
  80      {
  81          return $this->userInfo;
  82      }
  83      public function getHost(): string
  84      {
  85          return $this->host;
  86      }
  87      public function getPort(): ?int
  88      {
  89          return $this->port;
  90      }
  91      public function getPath(): string
  92      {
  93          $path = $this->path;
  94          if ('' !== $path && '/' !== $path[0]) {
  95              if ('' !== $this->host) {
  96                  // If the path is rootless and an authority is present, the path MUST be prefixed by "/"
  97                  $path = '/' . $path;
  98              }
  99          } elseif (isset($path[1]) && '/' === $path[1]) {
 100              // If the path is starting with more than one "/", the
 101              // starting slashes MUST be reduced to one.
 102              $path = '/' . \ltrim($path, '/');
 103          }
 104          return $path;
 105      }
 106      public function getQuery(): string
 107      {
 108          return $this->query;
 109      }
 110      public function getFragment(): string
 111      {
 112          return $this->fragment;
 113      }
 114      /**
 115       * @return static
 116       */
 117      public function withScheme($scheme): UriInterface
 118      {
 119          if (!\is_string($scheme)) {
 120              throw new \InvalidArgumentException('Scheme must be a string');
 121          }
 122          if ($this->scheme === $scheme = \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) {
 123              return $this;
 124          }
 125          $new = clone $this;
 126          $new->scheme = $scheme;
 127          $new->port = $new->filterPort($new->port);
 128          return $new;
 129      }
 130      /**
 131       * @return static
 132       */
 133      public function withUserInfo($user, $password = null): UriInterface
 134      {
 135          if (!\is_string($user)) {
 136              throw new \InvalidArgumentException('User must be a string');
 137          }
 138          $info = \preg_replace_callback('/[' . self::CHAR_GEN_DELIMS . self::CHAR_SUB_DELIMS . ']++/', [__CLASS__, 'rawurlencodeMatchZero'], $user);
 139          if (null !== $password && '' !== $password) {
 140              if (!\is_string($password)) {
 141                  throw new \InvalidArgumentException('Password must be a string');
 142              }
 143              $info .= ':' . \preg_replace_callback('/[' . self::CHAR_GEN_DELIMS . self::CHAR_SUB_DELIMS . ']++/', [__CLASS__, 'rawurlencodeMatchZero'], $password);
 144          }
 145          if ($this->userInfo === $info) {
 146              return $this;
 147          }
 148          $new = clone $this;
 149          $new->userInfo = $info;
 150          return $new;
 151      }
 152      /**
 153       * @return static
 154       */
 155      public function withHost($host): UriInterface
 156      {
 157          if (!\is_string($host)) {
 158              throw new \InvalidArgumentException('Host must be a string');
 159          }
 160          if ($this->host === $host = \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) {
 161              return $this;
 162          }
 163          $new = clone $this;
 164          $new->host = $host;
 165          return $new;
 166      }
 167      /**
 168       * @return static
 169       */
 170      public function withPort($port): UriInterface
 171      {
 172          if ($this->port === $port = $this->filterPort($port)) {
 173              return $this;
 174          }
 175          $new = clone $this;
 176          $new->port = $port;
 177          return $new;
 178      }
 179      /**
 180       * @return static
 181       */
 182      public function withPath($path): UriInterface
 183      {
 184          if ($this->path === $path = $this->filterPath($path)) {
 185              return $this;
 186          }
 187          $new = clone $this;
 188          $new->path = $path;
 189          return $new;
 190      }
 191      /**
 192       * @return static
 193       */
 194      public function withQuery($query): UriInterface
 195      {
 196          if ($this->query === $query = $this->filterQueryAndFragment($query)) {
 197              return $this;
 198          }
 199          $new = clone $this;
 200          $new->query = $query;
 201          return $new;
 202      }
 203      /**
 204       * @return static
 205       */
 206      public function withFragment($fragment): UriInterface
 207      {
 208          if ($this->fragment === $fragment = $this->filterQueryAndFragment($fragment)) {
 209              return $this;
 210          }
 211          $new = clone $this;
 212          $new->fragment = $fragment;
 213          return $new;
 214      }
 215      /**
 216       * Create a URI string from its various parts.
 217       */
 218      private static function createUriString(string $scheme, string $authority, string $path, string $query, string $fragment): string
 219      {
 220          $uri = '';
 221          if ('' !== $scheme) {
 222              $uri .= $scheme . ':';
 223          }
 224          if ('' !== $authority) {
 225              $uri .= '//' . $authority;
 226          }
 227          if ('' !== $path) {
 228              if ('/' !== $path[0]) {
 229                  if ('' !== $authority) {
 230                      // If the path is rootless and an authority is present, the path MUST be prefixed by "/"
 231                      $path = '/' . $path;
 232                  }
 233              } elseif (isset($path[1]) && '/' === $path[1]) {
 234                  if ('' === $authority) {
 235                      // If the path is starting with more than one "/" and no authority is present, the
 236                      // starting slashes MUST be reduced to one.
 237                      $path = '/' . \ltrim($path, '/');
 238                  }
 239              }
 240              $uri .= $path;
 241          }
 242          if ('' !== $query) {
 243              $uri .= '?' . $query;
 244          }
 245          if ('' !== $fragment) {
 246              $uri .= '#' . $fragment;
 247          }
 248          return $uri;
 249      }
 250      /**
 251       * Is a given port non-standard for the current scheme?
 252       */
 253      private static function isNonStandardPort(string $scheme, int $port): bool
 254      {
 255          return !isset(self::SCHEMES[$scheme]) || $port !== self::SCHEMES[$scheme];
 256      }
 257      private function filterPort($port): ?int
 258      {
 259          if (null === $port) {
 260              return null;
 261          }
 262          $port = (int) $port;
 263          if (0 > $port || 0xffff < $port) {
 264              throw new \InvalidArgumentException(\sprintf('Invalid port: %d. Must be between 0 and 65535', $port));
 265          }
 266          return self::isNonStandardPort($this->scheme, $port) ? $port : null;
 267      }
 268      private function filterPath($path): string
 269      {
 270          if (!\is_string($path)) {
 271              throw new \InvalidArgumentException('Path must be a string');
 272          }
 273          return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $path);
 274      }
 275      private function filterQueryAndFragment($str): string
 276      {
 277          if (!\is_string($str)) {
 278              throw new \InvalidArgumentException('Query and fragment must be a string');
 279          }
 280          return \preg_replace_callback('/(?:[^' . self::CHAR_UNRESERVED . self::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [__CLASS__, 'rawurlencodeMatchZero'], $str);
 281      }
 282      private static function rawurlencodeMatchZero(array $match): string
 283      {
 284          return \rawurlencode($match[0]);
 285      }
 286  }


Generated : Sat Jun 13 09:38:55 2026 Cross-referenced by PHPXref