[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |