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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
UriTemplate.php
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