MonsterInsights_GA_Lib_Utils_URITemplate

Implementation of levels 1-3 of the URI Template spec.

Defined (1)

The class is defined in the following location(s).

/assets/lib/google/src/Google/Utils/URITemplate.php  
  1. class MonsterInsights_GA_Lib_Utils_URITemplate 
  2. const TYPE_MAP = "1"; 
  3. const TYPE_LIST = "2"; 
  4. const TYPE_SCALAR = "4"; 
  5.  
  6. /** 
  7. * @var $operators array 
  8. * These are valid at the start of a template block to 
  9. * modify the way in which the variables inside are 
  10. * processed. 
  11. */ 
  12. private $operators = array( 
  13. "+" => "reserved",  
  14. "/" => "segments",  
  15. "." => "dotprefix",  
  16. "#" => "fragment",  
  17. ";" => "semicolon",  
  18. "?" => "form",  
  19. "&" => "continuation" 
  20. ); 
  21.  
  22. /** 
  23. * @var reserved array 
  24. * These are the characters which should not be URL encoded in reserved 
  25. * strings. 
  26. */ 
  27. private $reserved = array( 
  28. "=", ", ", "!", "@", "|", ":", "/", "?", "#",  
  29. "[", "]", '$', "&", "'", "(", ")", "*", "+", ";" 
  30. ); 
  31. private $reservedEncoded = array( 
  32. "%3D", "%2C", "%21", "%40", "%7C", "%3A", "%2F", "%3F",  
  33. "%23", "%5B", "%5D", "%24", "%26", "%27", "%28", "%29",  
  34. "%2A", "%2B", "%3B" 
  35. ); 
  36.  
  37. public function parse($string, array $parameters) 
  38. return $this->resolveNextSection($string, $parameters); 
  39.  
  40. /** 
  41. * This function finds the first matching {...} block and 
  42. * executes the replacement. It then calls itself to find 
  43. * subsequent blocks, if any. 
  44. */ 
  45. private function resolveNextSection($string, $parameters) 
  46. $start = strpos($string, "{"); 
  47. if ($start === false) { 
  48. return $string; 
  49. $end = strpos($string, "}"); 
  50. if ($end === false) { 
  51. return $string; 
  52. $string = $this->replace($string, $start, $end, $parameters); 
  53. return $this->resolveNextSection($string, $parameters); 
  54.  
  55. private function replace($string, $start, $end, $parameters) 
  56. // We know a data block will have {} round it, so we can strip that. 
  57. $data = substr($string, $start + 1, $end - $start - 1); 
  58.  
  59. // If the first character is one of the reserved operators, it effects 
  60. // the processing of the stream. 
  61. if (isset($this->operators[$data[0]])) { 
  62. $op = $this->operators[$data[0]]; 
  63. $data = substr($data, 1); 
  64. $prefix = ""; 
  65. $prefix_on_missing = false; 
  66.  
  67. switch ($op) { 
  68. case "reserved": 
  69. // Reserved means certain characters should not be URL encoded 
  70. $data = $this->replaceVars($data, $parameters, ", ", null, true); 
  71. break; 
  72. case "fragment": 
  73. // Comma separated with fragment prefix. Bare values only. 
  74. $prefix = "#"; 
  75. $prefix_on_missing = true; 
  76. $data = $this->replaceVars($data, $parameters, ", ", null, true); 
  77. break; 
  78. case "segments": 
  79. // Slash separated data. Bare values only. 
  80. $prefix = "/"; 
  81. $data =$this->replaceVars($data, $parameters, "/"); 
  82. break; 
  83. case "dotprefix": 
  84. // Dot separated data. Bare values only. 
  85. $prefix = "."; 
  86. $prefix_on_missing = true; 
  87. $data = $this->replaceVars($data, $parameters, "."); 
  88. break; 
  89. case "semicolon": 
  90. // Semicolon prefixed and separated. Uses the key name 
  91. $prefix = ";"; 
  92. $data = $this->replaceVars($data, $parameters, ";", "=", false, true, false); 
  93. break; 
  94. case "form": 
  95. // Standard URL format. Uses the key name 
  96. $prefix = "?"; 
  97. $data = $this->replaceVars($data, $parameters, "&", "="); 
  98. break; 
  99. case "continuation": 
  100. // Standard URL, but with leading ampersand. Uses key name. 
  101. $prefix = "&"; 
  102. $data = $this->replaceVars($data, $parameters, "&", "="); 
  103. break; 
  104.  
  105. // Add the initial prefix character if data is valid. 
  106. if ($data || ($data !== false && $prefix_on_missing)) { 
  107. $data = $prefix . $data; 
  108.  
  109. } else { 
  110. // If no operator we replace with the defaults. 
  111. $data = $this->replaceVars($data, $parameters); 
  112. // This is chops out the {...} and replaces with the new section. 
  113. return substr($string, 0, $start) . $data . substr($string, $end + 1); 
  114.  
  115. private function replaceVars( 
  116. $section,  
  117. $parameters,  
  118. $sep = ", ",  
  119. $combine = null,  
  120. $reserved = false,  
  121. $tag_empty = false,  
  122. $combine_on_empty = true 
  123. ) { 
  124. if (strpos($section, ", ") === false) { 
  125. // If we only have a single value, we can immediately process. 
  126. return $this->combine( 
  127. $section,  
  128. $parameters,  
  129. $sep,  
  130. $combine,  
  131. $reserved,  
  132. $tag_empty,  
  133. $combine_on_empty 
  134. ); 
  135. } else { 
  136. // If we have multiple values, we need to split and loop over them. 
  137. // Each is treated individually, then glued together with the 
  138. // separator character. 
  139. $vars = explode(", ", $section); 
  140. return $this->combineList( 
  141. $vars,  
  142. $sep,  
  143. $parameters,  
  144. $combine,  
  145. $reserved,  
  146. false, // Never emit empty strings in multi-param replacements 
  147. $combine_on_empty 
  148. ); 
  149.  
  150. public function combine( 
  151. $key,  
  152. $parameters,  
  153. $sep,  
  154. $combine,  
  155. $reserved,  
  156. $tag_empty,  
  157. $combine_on_empty 
  158. ) { 
  159. $length = false; 
  160. $explode = false; 
  161. $skip_final_combine = false; 
  162. $value = false; 
  163.  
  164. // Check for length restriction. 
  165. if (strpos($key, ":") !== false) { 
  166. list($key, $length) = explode(":", $key); 
  167.  
  168. // Check for explode parameter. 
  169. if ($key[strlen($key) - 1] == "*") { 
  170. $explode = true; 
  171. $key = substr($key, 0, -1); 
  172. $skip_final_combine = true; 
  173.  
  174. // Define the list separator. 
  175. $list_sep = $explode ? $sep : ", "; 
  176.  
  177. if (isset($parameters[$key])) { 
  178. $data_type = $this->getDataType($parameters[$key]); 
  179. switch ($data_type) { 
  180. case self::TYPE_SCALAR: 
  181. $value = $this->getValue($parameters[$key], $length); 
  182. break; 
  183. case self::TYPE_LIST: 
  184. $values = array(); 
  185. foreach ($parameters[$key] as $pkey => $pvalue) { 
  186. $pvalue = $this->getValue($pvalue, $length); 
  187. if ($combine && $explode) { 
  188. $values[$pkey] = $key . $combine . $pvalue; 
  189. } else { 
  190. $values[$pkey] = $pvalue; 
  191. $value = implode($list_sep, $values); 
  192. if ($value == '') { 
  193. return ''; 
  194. break; 
  195. case self::TYPE_MAP: 
  196. $values = array(); 
  197. foreach ($parameters[$key] as $pkey => $pvalue) { 
  198. $pvalue = $this->getValue($pvalue, $length); 
  199. if ($explode) { 
  200. $pkey = $this->getValue($pkey, $length); 
  201. $values[] = $pkey . "=" . $pvalue; // Explode triggers = combine. 
  202. } else { 
  203. $values[] = $pkey; 
  204. $values[] = $pvalue; 
  205. $value = implode($list_sep, $values); 
  206. if ($value == '') { 
  207. return false; 
  208. break; 
  209. } else if ($tag_empty) { 
  210. // If we are just indicating empty values with their key name, return that. 
  211. return $key; 
  212. } else { 
  213. // Otherwise we can skip this variable due to not being defined. 
  214. return false; 
  215.  
  216. if ($reserved) { 
  217. $value = str_replace($this->reservedEncoded, $this->reserved, $value); 
  218.  
  219. // If we do not need to include the key name, we just return the raw 
  220. // value. 
  221. if (!$combine || $skip_final_combine) { 
  222. return $value; 
  223.  
  224. // Else we combine the key name: foo=bar, if value is not the empty string. 
  225. return $key . ($value != '' || $combine_on_empty ? $combine . $value : ''); 
  226.  
  227. /** 
  228. * Return the type of a passed in value 
  229. */ 
  230. private function getDataType($data) 
  231. if (is_array($data)) { 
  232. reset($data); 
  233. if (key($data) !== 0) { 
  234. return self::TYPE_MAP; 
  235. return self::TYPE_LIST; 
  236. return self::TYPE_SCALAR; 
  237.  
  238. /** 
  239. * Utility function that merges multiple combine calls 
  240. * for multi-key templates. 
  241. */ 
  242. private function combineList( 
  243. $vars,  
  244. $sep,  
  245. $parameters,  
  246. $combine,  
  247. $reserved,  
  248. $tag_empty,  
  249. $combine_on_empty 
  250. ) { 
  251. $ret = array(); 
  252. foreach ($vars as $var) { 
  253. $response = $this->combine( 
  254. $var,  
  255. $parameters,  
  256. $sep,  
  257. $combine,  
  258. $reserved,  
  259. $tag_empty,  
  260. $combine_on_empty 
  261. ); 
  262. if ($response === false) { 
  263. continue; 
  264. $ret[] = $response; 
  265. return implode($sep, $ret); 
  266.  
  267. /** 
  268. * Utility function to encode and trim values 
  269. */ 
  270. private function getValue($value, $length) 
  271. if ($length) { 
  272. $value = substr($value, 0, $length); 
  273. $value = rawurlencode($value); 
  274. return $value;