-
- public function replace($s, $r) {
- if (!x($r,'$lang')){
- $r['$lang'] = &$this->_get_lang();
- }
- $this->r = $r;
- $this->search = array();
- $this->replace = array();
- $this->_build_replace($r, "");
- #$s = str_replace(array("\n","\r"),array("§n§","§r§"),$s);
- $s = $this->_build_nodes($s);
- $s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s);
- if ($s==Null) $this->_preg_error();
-
- // remove comments block
- $s = preg_replace('/{#[^#]*#}/', "" , $s);
-
- // replace strings recursively (limit to 10 loops)
- $os = ""; $count=0;
- while($os!=$s && $count<10){
- $os=$s; $count++;
- $s = str_replace($this->search,$this->replace, $s);
+ private function _replcb($m) {
+ //var_dump(array_map('htmlspecialchars', $m));
+ $this->done = false;
+ $this->nodes[] = (array) $m;
+ return "||" . (count($this->nodes) - 1) . "||";
+ }
+
+ private function _build_nodes($s) {
+ $this->done = false;
+ while (!$this->done) {
+ $this->done = true;
+ $s = preg_replace_callback('|{{ *([a-z]*) *([^}]*)}}([^{]*({{ *else *}}[^{]*)?){{ *end\1 *}}|', array($this, "_replcb"), $s);
+ if ($s == Null)
+ $this->_preg_error();
+ }
+ //({{ *else *}}[^{]*)?
+ krsort($this->nodes);
+ return $s;
+ }
+
+ private function var_replace($s) {
+ $m = array();
+ /** regexp:
+ * \$ literal $
+ * (\[)? optional open square bracket
+ * ([a-zA-Z0-9-_]+\.?)+ var name, followed by optional
+ * dot, repeated at least 1 time
+ * (|[a-zA-Z0-9-_:]+)* pipe followed by filter name and args, zero or many
+ * (?(1)\]) if there was opened square bracket
+ * (subgrup 1), match close bracket
+ */
+ if (preg_match_all('/\$(\[)?([a-zA-Z0-9-_]+\.?)+(\|[a-zA-Z0-9-_:]+)*(?(1)\])/', $s, $m)) {
+ foreach ($m[0] as $var) {
+
+ $exp = str_replace(array("[", "]"), array("", ""), $var);
+ $exptks = explode("|", $exp);
+
+ $varn = $exptks[0];
+ unset($exptks[0]);
+ $val = $this->_get_var($varn, true);
+ if ($val != KEY_NOT_EXISTS) {
+ /* run filters */
+ /*
+ * Filter are in form of:
+ * filtername:arg:arg:arg
+ *
+ * "filtername" is function name
+ * "arg"s are optional, var value is appended to the end
+ * if one "arg"==='x' , is replaced with var value
+ *
+ * examples:
+ * $item.body|htmlspecialchars // escape html chars
+ * $item.body|htmlspecialchars|strtoupper // escape html and uppercase result
+ * $item.created|date:%Y %M %j // format date (created is a timestamp)
+ * $item.body|str_replace:cat:dog // replace all "cat" with "dog"
+ * $item.body|str_replace:cat:dog:x:1 // replace one "cat" with "dog"
+
+ */
+ foreach ($exptks as $filterstr) {
+ $filter = explode(":", $filterstr);
+ $filtername = $filter[0];
+ unset($filter[0]);
+ $valkey = array_search("x", $filter);
+ if ($valkey === false) {
+ $filter[] = $val;
+ } else {
+ $filter[$valkey] = $val;
+ }
+ if (function_exists($filtername)) {
+ $val = call_user_func_array($filtername, $filter);
+ }
+ }
+ $s = str_replace($var, $val, $s);
+ }