Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

UriTemplate.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 7.93 KiB


001  <?php
002  namespace GuzzleHttp;
003   
004  /**
005   * Expands URI templates. Userland implementation of PECL uri_template.
006   *
007   * @link http://tools.ietf.org/html/rfc6570
008   */
009  class UriTemplate
010  {
011      /** @var string URI template */
012      private $template;
013   
014      /** @var array Variables to use in the template expansion */
015      private $variables;
016   
017      /** @var array Hash for quick operator lookups */
018      private static $operatorHash = [
019          ''  => ['prefix' => '',  'joiner' => ',', 'query' => false],
020          '+' => ['prefix' => '',  'joiner' => ',', 'query' => false],
021          '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false],
022          '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false],
023          '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false],
024          ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true],
025          '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true],
026          '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true]
027      ];
028   
029      /** @var array Delimiters */
030      private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$',
031          '&', '\'', '(', ')', '*', '+', ',', ';', '='];
032   
033      /** @var array Percent encoded delimiters */
034      private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D',
035          '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
036          '%3B', '%3D'];
037   
038      public function expand($template, array $variables)
039      {
040          if (false === strpos($template, '{')) {
041              return $template;
042          }
043   
044          $this->template = $template;
045          $this->variables = $variables;
046   
047          return preg_replace_callback(
048              '/\{([^\}]+)\}/',
049              [$this, 'expandMatch'],
050              $this->template
051          );
052      }
053   
054      /**
055       * Parse an expression into parts
056       *
057       * @param string $expression Expression to parse
058       *
059       * @return array Returns an associative array of parts
060       */
061      private function parseExpression($expression)
062      {
063          $result = [];
064   
065          if (isset(self::$operatorHash[$expression[0]])) {
066              $result['operator'] = $expression[0];
067              $expression = substr($expression, 1);
068          } else {
069              $result['operator'] = '';
070          }
071   
072          foreach (explode(',', $expression) as $value) {
073              $value = trim($value);
074              $varspec = [];
075              if ($colonPos = strpos($value, ':')) {
076                  $varspec['value'] = substr($value, 0, $colonPos);
077                  $varspec['modifier'] = ':';
078                  $varspec['position'] = (int) substr($value, $colonPos + 1);
079              } elseif (substr($value, -1) === '*') {
080                  $varspec['modifier'] = '*';
081                  $varspec['value'] = substr($value, 0, -1);
082              } else {
083                  $varspec['value'] = (string) $value;
084                  $varspec['modifier'] = '';
085              }
086              $result['values'][] = $varspec;
087          }
088   
089          return $result;
090      }
091   
092      /**
093       * Process an expansion
094       *
095       * @param array $matches Matches met in the preg_replace_callback
096       *
097       * @return string Returns the replacement string
098       */
099      private function expandMatch(array $matches)
100      {
101          static $rfc1738to3986 = ['+' => '%20', '%7e' => '~'];
102   
103          $replacements = [];
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              if (!isset($this->variables[$value['value']])) {
111                  continue;
112              }
113   
114              $variable = $this->variables[$value['value']];
115              $actuallyUseQuery = $useQuery;
116              $expanded = '';
117   
118              if (is_array($variable)) {
119                  $isAssoc = $this->isAssoc($variable);
120                  $kvp = [];
121                  foreach ($variable as $key => $var) {
122                      if ($isAssoc) {
123                          $key = rawurlencode($key);
124                          $isNestedArray = is_array($var);
125                      } else {
126                          $isNestedArray = false;
127                      }
128   
129                      if (!$isNestedArray) {
130                          $var = rawurlencode($var);
131                          if ($parsed['operator'] === '+' ||
132                              $parsed['operator'] === '#'
133                          ) {
134                              $var = $this->decodeReserved($var);
135                          }
136                      }
137   
138                      if ($value['modifier'] === '*') {
139                          if ($isAssoc) {
140                              if ($isNestedArray) {
141                                  // Nested arrays must allow for deeply nested
142                                  // structures.
143                                  $var = strtr(
144                                      http_build_query([$key => $var]),
145                                      $rfc1738to3986
146                                  );
147                              } else {
148                                  $var = $key . '=' . $var;
149                              }
150                          } elseif ($key > 0 && $actuallyUseQuery) {
151                              $var = $value['value'] . '=' . $var;
152                          }
153                      }
154   
155                      $kvp[$key] = $var;
156                  }
157   
158                  if (empty($variable)) {
159                      $actuallyUseQuery = false;
160                  } elseif ($value['modifier'] === '*') {
161                      $expanded = implode($joiner, $kvp);
162                      if ($isAssoc) {
163                          // Don't prepend the value name when using the explode
164                          // modifier with an associative array.
165                          $actuallyUseQuery = false;
166                      }
167                  } else {
168                      if ($isAssoc) {
169                          // When an associative array is encountered and the
170                          // explode modifier is not set, then the result must be
171                          // a comma separated list of keys followed by their
172                          // respective values.
173                          foreach ($kvp as $k => &$v) {
174                              $v = $k . ',' . $v;
175                          }
176                      }
177                      $expanded = implode(',', $kvp);
178                  }
179              } else {
180                  if ($value['modifier'] === ':') {
181                      $variable = substr($variable, 0, $value['position']);
182                  }
183                  $expanded = rawurlencode($variable);
184                  if ($parsed['operator'] === '+' || $parsed['operator'] === '#') {
185                      $expanded = $this->decodeReserved($expanded);
186                  }
187              }
188   
189              if ($actuallyUseQuery) {
190                  if (!$expanded && $joiner !== '&') {
191                      $expanded = $value['value'];
192                  } else {
193                      $expanded = $value['value'] . '=' . $expanded;
194                  }
195              }
196   
197              $replacements[] = $expanded;
198          }
199   
200          $ret = implode($joiner, $replacements);
201          if ($ret && $prefix) {
202              return $prefix . $ret;
203          }
204   
205          return $ret;
206      }
207   
208      /**
209       * Determines if an array is associative.
210       *
211       * This makes the assumption that input arrays are sequences or hashes.
212       * This assumption is a tradeoff for accuracy in favor of speed, but it
213       * should work in almost every case where input is supplied for a URI
214       * template.
215       *
216       * @param array $array Array to check
217       *
218       * @return bool
219       */
220      private function isAssoc(array $array)
221      {
222          return $array && array_keys($array)[0] !== 0;
223      }
224   
225      /**
226       * Removes percent encoding on reserved characters (used with + and #
227       * modifiers).
228       *
229       * @param string $string String to fix
230       *
231       * @return string
232       */
233      private function decodeReserved($string)
234      {
235          return str_replace(self::$delimsPct, self::$delims, $string);
236      }
237  }
238