Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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: 09.10.2024, 12:56 - Dateigröße: 8.00 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 = array(
019          ''  => array('prefix' => '',  'joiner' => ',', 'query' => false),
020          '+' => array('prefix' => '',  'joiner' => ',', 'query' => false),
021          '#' => array('prefix' => '#', 'joiner' => ',', 'query' => false),
022          '.' => array('prefix' => '.', 'joiner' => '.', 'query' => false),
023          '/' => array('prefix' => '/', 'joiner' => '/', 'query' => false),
024          ';' => array('prefix' => ';', 'joiner' => ';', 'query' => true),
025          '?' => array('prefix' => '?', 'joiner' => '&', 'query' => true),
026          '&' => array('prefix' => '&', 'joiner' => '&', 'query' => true)
027      );
028   
029      /** @var array Delimiters */
030      private static $delims = array(':', '/', '?', '#', '[', ']', '@', '!', '$',
031          '&', '\'', '(', ')', '*', '+', ',', ';', '=');
032   
033      /** @var array Percent encoded delimiters */
034      private static $delimsPct = array('%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 = array();
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 = array();
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 = 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  }
242