[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/guzzlehttp/guzzle/src/ -> UriTemplate.php (source)

   1  <?php
   2  namespace GuzzleHttp;
   3  
   4  /**
   5   * Expands URI templates. Userland implementation of PECL uri_template.
   6   *
   7   * @link http://tools.ietf.org/html/rfc6570
   8   */
   9  class UriTemplate
  10  {
  11      /** @var string URI template */
  12      private $template;
  13  
  14      /** @var array Variables to use in the template expansion */
  15      private $variables;
  16  
  17      /** @var array Hash for quick operator lookups */
  18      private static $operatorHash = array(
  19          ''  => array('prefix' => '',  'joiner' => ',', 'query' => false),
  20          '+' => array('prefix' => '',  'joiner' => ',', 'query' => false),
  21          '#' => array('prefix' => '#', 'joiner' => ',', 'query' => false),
  22          '.' => array('prefix' => '.', 'joiner' => '.', 'query' => false),
  23          '/' => array('prefix' => '/', 'joiner' => '/', 'query' => false),
  24          ';' => array('prefix' => ';', 'joiner' => ';', 'query' => true),
  25          '?' => array('prefix' => '?', 'joiner' => '&', 'query' => true),
  26          '&' => array('prefix' => '&', 'joiner' => '&', 'query' => true)
  27      );
  28  
  29      /** @var array Delimiters */
  30      private static $delims = array(':', '/', '?', '#', '[', ']', '@', '!', '$',
  31          '&', '\'', '(', ')', '*', '+', ',', ';', '=');
  32  
  33      /** @var array Percent encoded delimiters */
  34      private static $delimsPct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D',
  35          '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
  36          '%3B', '%3D');
  37  
  38      public function expand($template, array $variables)
  39      {
  40          if (false === strpos($template, '{')) {
  41              return $template;
  42          }
  43  
  44          $this->template = $template;
  45          $this->variables = $variables;
  46  
  47          return preg_replace_callback(
  48              '/\{([^\}]+)\}/',
  49              [$this, 'expandMatch'],
  50              $this->template
  51          );
  52      }
  53  
  54      /**
  55       * Parse an expression into parts
  56       *
  57       * @param string $expression Expression to parse
  58       *
  59       * @return array Returns an associative array of parts
  60       */
  61      private function parseExpression($expression)
  62      {
  63          $result = array();
  64  
  65          if (isset(self::$operatorHash[$expression[0]])) {
  66              $result['operator'] = $expression[0];
  67              $expression = substr($expression, 1);
  68          } else {
  69              $result['operator'] = '';
  70          }
  71  
  72          foreach (explode(',', $expression) as $value) {
  73              $value = trim($value);
  74              $varspec = array();
  75              if ($colonPos = strpos($value, ':')) {
  76                  $varspec['value'] = substr($value, 0, $colonPos);
  77                  $varspec['modifier'] = ':';
  78                  $varspec['position'] = (int) substr($value, $colonPos + 1);
  79              } elseif (substr($value, -1) == '*') {
  80                  $varspec['modifier'] = '*';
  81                  $varspec['value'] = substr($value, 0, -1);
  82              } else {
  83                  $varspec['value'] = (string) $value;
  84                  $varspec['modifier'] = '';
  85              }
  86              $result['values'][] = $varspec;
  87          }
  88  
  89          return $result;
  90      }
  91  
  92      /**
  93       * Process an expansion
  94       *
  95       * @param array $matches Matches met in the preg_replace_callback
  96       *
  97       * @return string Returns the replacement string
  98       */
  99      private function expandMatch(array $matches)
 100      {
 101          static $rfc1738to3986 = array('+' => '%20', '%7e' => '~');
 102  
 103          $replacements = array();
 104          $parsed = self::parseExpression($matches[1]);
 105          $prefix = self::$operatorHash[$parsed['operator']]['prefix'];
 106          $joiner = self::$operatorHash[$parsed['operator']]['joiner'];
 107          $useQuery = self::$operatorHash[$parsed['operator']]['query'];
 108  
 109          foreach ($parsed['values'] as $value) {
 110  
 111              if (!isset($this->variables[$value['value']])) {
 112                  continue;
 113              }
 114  
 115              $variable = $this->variables[$value['value']];
 116              $actuallyUseQuery = $useQuery;
 117              $expanded = '';
 118  
 119              if (is_array($variable)) {
 120  
 121                  $isAssoc = $this->isAssoc($variable);
 122                  $kvp = array();
 123                  foreach ($variable as $key => $var) {
 124  
 125                      if ($isAssoc) {
 126                          $key = rawurlencode($key);
 127                          $isNestedArray = is_array($var);
 128                      } else {
 129                          $isNestedArray = false;
 130                      }
 131  
 132                      if (!$isNestedArray) {
 133                          $var = rawurlencode($var);
 134                          if ($parsed['operator'] == '+' ||
 135                              $parsed['operator'] == '#'
 136                          ) {
 137                              $var = $this->decodeReserved($var);
 138                          }
 139                      }
 140  
 141                      if ($value['modifier'] == '*') {
 142                          if ($isAssoc) {
 143                              if ($isNestedArray) {
 144                                  // Nested arrays must allow for deeply nested
 145                                  // structures.
 146                                  $var = strtr(
 147                                      http_build_query([$key => $var]),
 148                                      $rfc1738to3986
 149                                  );
 150                              } else {
 151                                  $var = $key . '=' . $var;
 152                              }
 153                          } elseif ($key > 0 && $actuallyUseQuery) {
 154                              $var = $value['value'] . '=' . $var;
 155                          }
 156                      }
 157  
 158                      $kvp[$key] = $var;
 159                  }
 160  
 161                  if (empty($variable)) {
 162                      $actuallyUseQuery = false;
 163                  } elseif ($value['modifier'] == '*') {
 164                      $expanded = implode($joiner, $kvp);
 165                      if ($isAssoc) {
 166                          // Don't prepend the value name when using the explode
 167                          // modifier with an associative array.
 168                          $actuallyUseQuery = false;
 169                      }
 170                  } else {
 171                      if ($isAssoc) {
 172                          // When an associative array is encountered and the
 173                          // explode modifier is not set, then the result must be
 174                          // a comma separated list of keys followed by their
 175                          // respective values.
 176                          foreach ($kvp as $k => &$v) {
 177                              $v = $k . ',' . $v;
 178                          }
 179                      }
 180                      $expanded = implode(',', $kvp);
 181                  }
 182  
 183              } else {
 184                  if ($value['modifier'] == ':') {
 185                      $variable = substr($variable, 0, $value['position']);
 186                  }
 187                  $expanded = rawurlencode($variable);
 188                  if ($parsed['operator'] == '+' || $parsed['operator'] == '#') {
 189                      $expanded = $this->decodeReserved($expanded);
 190                  }
 191              }
 192  
 193              if ($actuallyUseQuery) {
 194                  if (!$expanded && $joiner != '&') {
 195                      $expanded = $value['value'];
 196                  } else {
 197                      $expanded = $value['value'] . '=' . $expanded;
 198                  }
 199              }
 200  
 201              $replacements[] = $expanded;
 202          }
 203  
 204          $ret = implode($joiner, $replacements);
 205          if ($ret && $prefix) {
 206              return $prefix . $ret;
 207          }
 208  
 209          return $ret;
 210      }
 211  
 212      /**
 213       * Determines if an array is associative.
 214       *
 215       * This makes the assumption that input arrays are sequences or hashes.
 216       * This assumption is a tradeoff for accuracy in favor of speed, but it
 217       * should work in almost every case where input is supplied for a URI
 218       * template.
 219       *
 220       * @param array $array Array to check
 221       *
 222       * @return bool
 223       */
 224      private function isAssoc(array $array)
 225      {
 226          return $array && array_keys($array)[0] !== 0;
 227      }
 228  
 229      /**
 230       * Removes percent encoding on reserved characters (used with + and #
 231       * modifiers).
 232       *
 233       * @param string $string String to fix
 234       *
 235       * @return string
 236       */
 237      private function decodeReserved($string)
 238      {
 239          return str_replace(self::$delimsPct, self::$delims, $string);
 240      }
 241  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1