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. |
|
(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 = 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