PageRenderTime 26ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

/htroot/assets/snippets/maxigallery/chunkie/phx.parser.class.inc.php

https://github.com/gunf/novo-isaak.local
PHP | 417 lines | 353 code | 23 blank | 41 comment | 15 complexity | 630958c37b90f3b74ba405227daf44b0 MD5 | raw file
  1. <?php
  2. /*####
  3. #
  4. # Name: PHx (Placeholders Xtended)
  5. # Version: 2.0 (Rev 5)
  6. # Author: Armand "bS" Pondman (apondman@zerobarrier.nl)
  7. # Date: Nov 09, 2006 21:45 CET
  8. #
  9. ####*/
  10. class PHxParser {
  11. var $version;
  12. var $user;
  13. var $safetags;
  14. var $placeholders = array();
  15. function PHxParser($debug=0,$maxpass=50) {
  16. global $modx;
  17. $this->name = "PHx";
  18. $this->version = "2.0.0.5";
  19. $this->user["mgrid"] = intval($_SESSION['mgrInternalKey']);
  20. $this->user["usrid"] = intval($_SESSION['webInternalKey']);
  21. $this->user["id"] = ($this->user["usrid"] > 0 ) ? (-$this->user["usrid"]) : $this->user["mgrid"];
  22. $this->safetags[0][0] = '~(?<![\[]|^\^)\[(?=[^\+\*\(\[\!]|$)~s';
  23. $this->safetags[0][1] = '~(?<=[^\+\*\)\]\!]|^)\](?=[^\]]|$)~s';
  24. $this->safetags[1][0] = '&_PHX_INTERNAL_091_&';
  25. $this->safetags[1][1] = '&_PHX_INTERNAL_093_&';
  26. $this->safetags[2][0] = '[';
  27. $this->safetags[2][1] = ']';
  28. $this->console = array();
  29. $this->debug = ($debug!='') ? $debug : 0;
  30. $this->debugLog = false;
  31. $this->curPass = 0;
  32. $this->maxPasses = ($maxpass!='') ? $maxpass : 50;
  33. $this->swapSnippetCache = array();
  34. $modx->setPlaceholder("phx", "&_PHX_INTERNAL_&");
  35. }
  36. // Plugin event hook for MODx
  37. function OnParseDocument() {
  38. global $modx;
  39. // Get document output from MODx
  40. $template = $modx->documentOutput;
  41. // To the parse cave .. let's go! *insert batman tune here*
  42. $template = $this->Parse($template);
  43. // Set processed document output in MODx
  44. $modx->documentOutput = $template;
  45. }
  46. // Parser: Preparation, cleaning and checkup
  47. function Parse($template='') {
  48. global $modx;
  49. // If we already reached max passes don't get at it again.
  50. if ($this->curPass == $this->maxPasses) return $template;
  51. // Set template pre-process hash
  52. $st = md5($template);
  53. // Replace non-call characters in the template: [, ]
  54. $template = preg_replace($this->safetags[0],$this->safetags[1],$template);
  55. // To the parse mobile.. let's go! *insert batman tune here*
  56. $template = $this->ParseValues($template);
  57. // clean up unused placeholders that have modifiers attached (MODx can't clean them)
  58. preg_match_all('~\[(\+|\*|\()([^:\+\[\]]+)([^\[\]]*?)(\1|\))\]~s', $template, $matches);
  59. if ($matches[0]) {
  60. $template = str_replace($matches[0], '', $template);
  61. $this->Log("Cleaning unused tags: \n" . implode("\n",$matches[2]) );
  62. }
  63. // Restore non-call characters in the template: [, ]
  64. $template = str_replace($this->safetags[1],$this->safetags[2],$template);
  65. // Set template post-process hash
  66. $et = md5($template);
  67. // If template has changed, parse it once more...
  68. if ($st!=$et) $template = $this->Parse($template);
  69. // Write an event log if debugging is enabled and there is something to log
  70. if ($this->debug && $this->debugLog) {
  71. $modx->logEvent(0,1,$this->createEventLog(), $this->name.' '.$this->version);
  72. $this->debugLog = false;
  73. }
  74. // Return the processed template
  75. return $template;
  76. }
  77. // Parser: Tag detection and replacements
  78. function ParseValues($template='') {
  79. global $modx;
  80. $this->curPass = $this->curPass + 1;
  81. $st = md5($template);
  82. $this->LogPass();
  83. $this->Log("Template input: ".$template);
  84. // MODx Chunks
  85. $this->Log("MODx Chunks -> Merging all chunk tags");
  86. $template = $modx->mergeChunkContent($template);
  87. // MODx Snippets
  88. if ( preg_match_all('~\[(\[|!)([^\[\]]*?)(!|\])\]~s',$template, $matches)) {
  89. $count = count($matches[0]);
  90. $var_search = array();
  91. $var_replace = array();
  92. // for each detected snippt
  93. for($i=0; $i<$count; $i++) {
  94. $isCached = (trim($matches[1][$i])=="!") ? false : true; // is this snippet cached?
  95. $snippet = $matches[2][$i]; // snippet call
  96. if (!$isCached) { // if not cached
  97. $this->swapSnippetCache = $modx->snippetCache; // store the real cache
  98. $modx->snippetCache = array(); // empty cache
  99. $this->Log("MODx Snippet -> uncached: ".$snippet);
  100. } else { // if cached
  101. $this->Log("MODx Snippet -> cached: ".$snippet);
  102. }
  103. // Let MODx evaluate snippet
  104. $replace = $modx->evalSnippets("[[".$snippet."]]");
  105. $this->LogSnippet($replace);
  106. // Replace values
  107. $var_search[] = $matches[0][$i];
  108. $var_replace[] = $replace;
  109. // If not Cached
  110. if (!$isCached) $modx->snippetCache = $this->swapSnippetCache; // put original cache back
  111. }
  112. $template = str_replace($var_search, $var_replace, $template);
  113. }
  114. // PHx / MODx Tags
  115. if ( preg_match_all('~\[(\+|\*|\()([^:\+\[\]]+)([^\[\]]*?)(\1|\))\]~s',$template, $matches)) {
  116. //$matches[0] // Complete string that's need to be replaced
  117. //$matches[1] // Type
  118. //$matches[2] // The placeholder(s)
  119. //$matches[3] // The modifiers
  120. //$matches[4] // Type (end character)
  121. $count = count($matches[0]);
  122. $var_search = array();
  123. $var_replace = array();
  124. for($i=0; $i<$count; $i++) {
  125. $replace = NULL;
  126. $match = $matches[0][$i];
  127. $type = $matches[1][$i];
  128. $type_end = $matches[4][$i];
  129. $input = $matches[2][$i];
  130. $modifiers = $matches[3][$i];
  131. $var_search[] = $match;
  132. switch($type) {
  133. // Document / Template Variable eXtended
  134. case "*":
  135. $this->Log("MODx TV/DV: " . $input);
  136. $input = $modx->mergeDocumentContent("[*".$input."*]");
  137. $replace = $this->Filter($input,$modifiers);
  138. break;
  139. // MODx Setting eXtended
  140. case "(":
  141. $this->Log("MODx Setting variable: " . $input);
  142. $input = $modx->mergeSettingsContent("[(".$input.")]");
  143. $replace = $this->Filter($input,$modifiers);
  144. break;
  145. // MODx Placeholder eXtended
  146. default:
  147. $this->Log("MODx / PHx placeholder variable: " . $input);
  148. // Check if placeholder is set
  149. if ( !array_key_exists($input, $this->placeholders) && !array_key_exists($input, $modx->placeholders) ) {
  150. // not set so try again later.
  151. $replace = $match;
  152. $this->Log(" |--- Skipping - hasn't been set yet.");
  153. }
  154. else {
  155. // is set, get value and run filter
  156. $input = $this->getPHxVariable($input);
  157. $replace = $this->Filter($input,$modifiers);
  158. }
  159. break;
  160. }
  161. $var_replace[] = $replace;
  162. }
  163. $template = str_replace($var_search, $var_replace, $template);
  164. }
  165. $et = md5($template); // Post-process template hash
  166. // Log an event if this was the maximum pass
  167. if ($this->curPass == $this->maxPasses) $this->Log("Max passes reached. infinite loop protection so exiting.\n If you need the extra passes set the max passes to the highest count of nested tags in your template.");
  168. // If this pass is not at maximum passes and the template hash is not the same, get at it again.
  169. if (($this->curPass < $this->maxPasses) && ($st!=$et)) $template = $this->ParseValues($template);
  170. return $template;
  171. }
  172. // Parser: modifier detection and eXtended processing if needed
  173. function Filter($input, $modifiers) {
  174. global $modx;
  175. $output = $input;
  176. $this->Log(" |--- Value = '". $output ."'");
  177. if (preg_match_all('~:([^:=]+)(?:=`(.*?)`(?=:[^:=]+|$))?~s',$modifiers, $matches)) {
  178. $modifier_cmd = $matches[1]; // modifier command
  179. $modifier_value = $matches[2]; // modifier value
  180. $count = count($modifier_cmd);
  181. $condition = array();
  182. for($i=0; $i<$count; $i++) {
  183. $output = trim($output);
  184. $this->Log(" |--- Value = '". $output ."'");
  185. $this->Log(" |--- Modifier = '". $modifier_cmd[$i] ."'");
  186. if ($modifier_value[$i] != '') $this->Log(" |--- Options = '". $modifier_value[$i] ."'");
  187. switch ($modifier_cmd[$i]) {
  188. ##### Conditional Modifiers
  189. case "input": case "if": $output = $modifier_value[$i]; break;
  190. case "equals": case "is": case "eq": $condition[] = intval(($output==$modifier_value[$i])); break;
  191. case "notequals": case "isnot": case "isnt": case "ne":$condition[] = intval(($output!=$modifier_value[$i]));break;
  192. case "isgreaterthan": case "isgt": case "eg": $condition[] = intval(($output>=$modifier_value[$i]));break;
  193. case "islowerthan": case "islt": case "el": $condition[] = intval(($output<=$modifier_value[$i]));break;
  194. case "greaterthan": case "gt": $condition[] = intval(($output>$modifier_value[$i]));break;
  195. case "lowerthan": case "lt":$condition[] = intval(($output<$modifier_value[$i]));break;
  196. case "isinrole": case "ir": case "memberof": case "mo": // Is Member Of (same as inrole but this one can be stringed as a conditional)
  197. if ($output == "&_PHX_INTERNAL_&") $output = $this->user["id"];
  198. $grps = (strlen($modifier_value) > 0 ) ? explode(",",$modifier_value[$i]) :array();
  199. $condition[] = intval($this->isMemberOfWebGroupByUserId($output,$grps));
  200. break;
  201. case "or":$condition[] = "||";break;
  202. case "and": $condition[] = "&&";break;
  203. case "show":
  204. $conditional = implode(' ',$condition);
  205. $isvalid = intval(eval("return (". $conditional. ");"));
  206. if (!$isvalid) { $output = NULL;}
  207. case "then":
  208. $conditional = implode(' ',$condition);
  209. $isvalid = intval(eval("return (". $conditional. ");"));
  210. if ($isvalid) { $output = $modifier_value[$i]; }
  211. else { $output = NULL; }
  212. break;
  213. case "else":
  214. $conditional = implode(' ',$condition);
  215. $isvalid = intval(eval("return (". $conditional. ");"));
  216. if (!$isvalid) { $output = $modifier_value[$i]; }
  217. break;
  218. case "select":
  219. $raw = explode("&",$modifier_value[$i]);
  220. $map = array();
  221. for($m=0; $m<(count($raw)); $m++) {
  222. $mi = explode("=",$raw[$m]);
  223. $map[$mi[0]] = $mi[1];
  224. }
  225. $output = $map[$output];
  226. break;
  227. ##### End of Conditional Modifiers
  228. ##### String Modifiers
  229. case "lcase": $output = strtolower($output); break;
  230. case "ucase": $output = strtoupper($output); break;
  231. case "ucfirst": $output = ucfirst($output); break;
  232. case "htmlent": $output = htmlentities($output,ENT_QUOTES,$modx->config['etomite_charset']); break;
  233. case "esc":
  234. $output = preg_replace("/&amp;(#[0-9]+|[a-z]+);/i", "&$1;", htmlspecialchars($output));
  235. $output = str_replace(array("[","]","`"),array("&#91;","&#93;","&#96;"),$output);
  236. break;
  237. case "strip": $output = preg_replace("~([\n\r\t\s]+)~"," ",$output); break;
  238. case "notags": $output = strip_tags($output); break;
  239. case "length": case "len": $output = strlen($output); break;
  240. case "reverse": $output = strrev($output); break;
  241. case "wordwrap": // default: 70
  242. $wrapat = intval($modifier_value[$i]);
  243. if ($wrapat) { $output = wordwrap($output,$wrapat," ",1); }
  244. else {
  245. $output = wordwrap($output,70," ",1);
  246. }
  247. break;
  248. case "limit": // default: 100
  249. $limit = intval($modifier_value[$i]) ? intval($modifier_value[$i]) : 100;
  250. $output = substr($output,0,$limit);
  251. break;
  252. ##### Special functions
  253. case "math":
  254. $filter = preg_replace("~([a-zA-Z\n\r\t\s])~","",$modifier_value[$i]);
  255. $filter = str_replace("?",$output,$filter);
  256. $output = eval("return ".$filter.";");
  257. break;
  258. case "ifempty": if (empty($output)) $output = $modifier_value[$i]; break;
  259. case "nl2br": $output = nl2br($output); break;
  260. case "date": $output = strftime($modifier_value[$i],0+$output); break;
  261. case "set":
  262. $c = $i+1;
  263. if ($count>$c&&$modifier_cmd[$c]=="value") $output = preg_replace("~([^a-zA-Z0-9])~","",$modifier_value[$i]);
  264. break;
  265. case "value":
  266. if ($i>0&&$modifier_cmd[$i-1]=="set") { $modx->SetPlaceholder("phx.".$output,$modifier_value[$i]); }
  267. $output = NULL;
  268. break;
  269. case "md5": $output = md5($output); break;
  270. case "userinfo":
  271. if ($output == "&_PHX_INTERNAL_&") $output = $this->user["id"];
  272. $output = $this->ModUser($output,$modifier_value[$i]);
  273. break;
  274. case "inrole":
  275. if ($output == "&_PHX_INTERNAL_&") $output = $this->user["id"];
  276. $grps = (strlen($modifier_value) > 0 ) ? explode(",",$modifier_value[$i]) :array();
  277. $output = intval($this->isMemberOfWebGroupByUserId($output,$grps));
  278. break;
  279. default:
  280. $sql= "SELECT snippet FROM " . $modx->getFullTableName("site_snippets") . " WHERE " . $modx->getFullTableName("site_snippets") . ".name='phx:" . $modifier_cmd[$i] . "';";
  281. $result = $modx->dbQuery($sql);
  282. if ($modx->recordCount($result) == 1) {
  283. $row = $modx->fetchRow($result);
  284. ob_start();
  285. $options = $modifier_value[$i];
  286. $custom = eval($row["snippet"]);
  287. $msg = ob_get_contents();
  288. $output = $msg.$custom;
  289. ob_end_clean();
  290. }
  291. break;
  292. }
  293. if (count($condition)) $this->Log(" |--- Condition = '". $condition[count($condition)-1] ."'");
  294. $this->Log(" |--- Output = '". $output ."'");
  295. }
  296. }
  297. return $output;
  298. }
  299. // Event logging (debug)
  300. function createEventLog() {
  301. if($this->console) {
  302. $console = implode("\n",$this->console);
  303. $this->console = array();
  304. return '<pre style="overflow: auto;">' . $console . '</pre>';
  305. }
  306. }
  307. // Returns a cleaned string escaping the HTML and special MODx characters
  308. function LogClean($string) {
  309. $string = preg_replace("/&amp;(#[0-9]+|[a-z]+);/i", "&$1;", htmlspecialchars($string));
  310. $string = str_replace(array("[","]","`"),array("&#91;","&#93;","&#96;"),$string);
  311. return $string;
  312. }
  313. // Simple log entry
  314. function Log($string) {
  315. if ($this->debug) {$this->debugLog = true; $this->console[] = (count($this->console)+1-$this->curPass). " [". strftime("%H:%M:%S",time()). "] " . $this->LogClean($string);}
  316. }
  317. // Log snippet output
  318. function LogSnippet($string) {
  319. if ($this->debug) {$this->debugLog = true; $this->console[] = (count($this->console)+1-$this->curPass). " [". strftime("%H:%M:%S",time()). "] " . " |--- Returns: <div style='margin: 10px;'>".$this->LogClean($string)."</div>";}
  320. }
  321. // Log pass
  322. function LogPass() {
  323. $this->console[] = "<div style='margin: 2px;margin-top: 5px;border-bottom: 1px solid black;'>Pass " . $this->curPass . "</div>";
  324. }
  325. // Returns the specified field from the user record
  326. // positive userid = manager, negative integer = webuser
  327. function ModUser($userid,$field) {
  328. global $modx;
  329. if (intval($userid) < 0) {
  330. $user = $modx->getWebUserInfo(-($userid));
  331. } else {
  332. $user = $modx->getUserInfo($userid);
  333. }
  334. return $user[$field];
  335. }
  336. // Returns true if the user id is in one the specified webgroups
  337. function isMemberOfWebGroupByUserId($userid=0,$groupNames=array()) {
  338. global $modx;
  339. // if $groupNames is not an array return false
  340. if(!is_array($groupNames)) return false;
  341. // if the user id is a negative number make it positive
  342. if (intval($userid) < 0) { $userid = -($userid); }
  343. // Creates an array with all webgroups the user id is in
  344. $tbl = $modx->getFullTableName("webgroup_names");
  345. $tbl2 = $modx->getFullTableName("web_groups");
  346. $sql = "SELECT wgn.name FROM $tbl wgn INNER JOIN $tbl2 wg ON wg.webgroup=wgn.id AND wg.webuser='".$userid."'";
  347. $grpNames = $modx->db->getColumn("name",$sql);
  348. // Check if a supplied group matches a webgroup from the array we just created
  349. foreach($groupNames as $k=>$v)
  350. if(in_array(trim($v),$grpNames)) return true;
  351. // If we get here the above logic did not find a match, so return false
  352. return false;
  353. }
  354. // Returns the value of a PHx/MODx placeholder.
  355. function getPHxVariable($name) {
  356. global $modx;
  357. // Check if this variable is created by PHx
  358. if (array_key_exists($name, $this->placeholders)) {
  359. // Return the value from PHx
  360. return $this->placeholders[$name];
  361. } else {
  362. // Return the value from MODx
  363. return $modx->getPlaceholder($name);
  364. }
  365. }
  366. // Sets a placeholder variable which can only be access by PHx
  367. function setPHxVariable($name, $value) {
  368. if ($name != "phx") $this->placeholders[$name] = $value;
  369. }
  370. }
  371. ?>