Advertisement
aaaaaa123456789

Template parsing engine (ptempl.php)

Feb 16th, 2013
115
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. function pt_recursive_implode ($array) {
  4.   if (!is_array($array)) return $array;
  5.   foreach ($array as $key => $value) $array[$key] = pt_recursive_implode($value);
  6.   return implode($array);
  7. }
  8.  
  9. function pt_find_tag ($template, $initial) {
  10.   $result = strpos($template, "<!-- ##", $initial);
  11.   if ($result === false) return null;
  12.   return (int) $result;
  13. }
  14.  
  15. function pt_check_tag ($template, $initial, $depth) {
  16.   $endtag = str_repeat('#', $depth);
  17.   $endpos = strpos($template, "<!-- ###$endtag -->", $initial);
  18.   if ($endpos === false) return false;
  19.   $taglen = ($endpos + 12 + $depth) - $initial;
  20.   if ($taglen == 0) return false;
  21.   $startpos = strpos($template, " -->", $initial);
  22.   if ($startpos >= $endpos) return false;
  23.   $startpos += 4;
  24.   $paramlist = substr($template, $initial + 7, $startpos - $initial - 11);
  25.   $contents = substr($template, $startpos, $endpos - $startpos);
  26.   $mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
  27.   $ppos = strspn($paramlist, $mask);
  28.   if ($ppos == 0) return false;
  29.   $name = substr($paramlist, 0, $ppos);
  30.   if ((ord($name[0]) >= 48) and (ord($name[0]) <= 57)) return false;
  31.   $ppos += strcspn($paramlist, $mask, $ppos);
  32.   $plen = strlen($paramlist);
  33.   $params = array();
  34.   $paramcount = 0;
  35.   while ($ppos < $plen) {
  36.     $next = strspn($paramlist, $mask, $ppos);
  37.     if ($next == 0) break;
  38.     $params[++ $paramcount] = substr($paramlist, $ppos, $next);
  39.     if ((ord($params[$paramcount][0]) >= 48) and (ord($params[$paramcount][0]) <= 57)) return false;
  40.     $ppos += $next;
  41.     $ppos += strcspn($paramlist, $mask, $ppos);
  42.   }
  43.   if ($paramcount > 1)
  44.     for ($p1 = 1, $p2 = 2; $p1 < $paramcount; $p2 = 1 + (($p2 == $paramcount) ? (++ $p1) : $p2))
  45.       if (strpos($params[$p2], $params[$p1]) === 0)
  46.         return false;
  47.   return array($name, $taglen, $params, $contents);
  48. }
  49.  
  50. function pt_parse_tag ($contents, $params, $replace, $header, $footer, $parse_callbacks, $depth, $data) {
  51.   if (!is_string($contents)) $contents = (string) $contents;
  52.   if ($params === null) return array($header, $contents, $footer);
  53.   if (is_bool($params))
  54.     return ((bool) $params) ? pt_parse_template($contents, $parse_callbacks, $depth + 1, $data) : "";
  55.   if (is_int($params)) {
  56.     if ($params <= 0) return "";
  57.     if ($params == 1) return pt_parse_template($contents, $parse_callbacks, $depth + 1, $data);
  58.     $recurse = (pt_find_tag($contents, 0) !== null);
  59.     if ($recurse) {
  60.       $result = array();
  61.       for ($pos = 0; $pos < $params; $pos ++)
  62.         $result[$pos] = pt_parse_template($contents, $parse_callbacks, $depth + 1, $data);
  63.       return $result;
  64.     } else return (((int) $params) > 0) ? array_fill(0, (int) $params, $contents) : "";
  65.   }
  66.   if (is_string($params))
  67.     return pt_parse_template($params, $parse_callbacks, $depth + 1, $data);
  68.   if (is_array($params)) {
  69.     if (isset($params[0])) {
  70.       if (!is_int($params[0])) return "";
  71.       if ($params[0] <= 0) return "";
  72.       $result = array_fill(1, $params[0], "");
  73.       for ($index = 1; $index <= $params[0]; $index ++)
  74.         if (isset($params[$index]))
  75.           $result[$index] = pt_parse_tag($contents, $params[$index], $replace, $header, $footer,
  76.                                          $parse_callbacks, $depth, $data);
  77.       return $result;
  78.     } else {
  79.       $contents = pt_parse_template($contents, $parse_callbacks, $depth + 1, $data);
  80.       foreach ($replace as $pos => $name)
  81.         if (isset($params[$name]))
  82.           $contents = str_replace("$$" . $name, $params[$name], $contents);
  83.         else if (isset($params[$pos]))
  84.           $contents = str_replace("$$" . $name, $params[$pos], $contents);
  85.       return $contents;
  86.     }
  87.   }
  88.   return array($header, $contents, $footer);
  89. }
  90.  
  91. function pt_parse_template ($template, $parse_callbacks, $depth, $data) {
  92.   $result = array();
  93.   $next = 0;
  94.   $tpos = 0;
  95.   $tlen = strlen($template);
  96.   while (($tpos < $tlen) and (($nexttag = pt_find_tag($template, $tpos)) !== null)) {
  97.     if ($nexttag > $tpos)
  98.       $result[$next ++] = substr($template, $tpos, $nexttag - $tpos);
  99.     $tag_data = pt_check_tag($template, $nexttag, $depth);
  100.     if ($tag_data === false) {
  101.       $result[$next ++] = substr($template, $nexttag, $tlen - $nexttag);
  102.       $tpos = $tlen;
  103.       continue;
  104.     }
  105.     $tpos = $nexttag + $tag_data[1];
  106.     $theader = substr($template, $nexttag, strpos($template, "-->", $nexttag) + 3 - $nexttag);
  107.     $tfooter = substr($template, $tpos - $depth - 12, $depth + 12);
  108.     if (is_callable($parse_callbacks)) {
  109.       $result[$next ++] = is_callable($parse_callbacks) ?
  110.         pt_parse_tag($tag_data[3], call_user_func_array($parse_callbacks, array_merge(array($tag_data[0]), $data)),
  111.                      $tag_data[2], $theader, $tfooter, $parse_callbacks, $depth, $data) :
  112.         $theader . $tag_data[3] . $tfooter;
  113.     } else if (is_array($parse_callbacks)) {
  114.       $callback = @$parse_callbacks[$tag_data[0]];
  115.       $result[$next ++] = is_callable($callback) ?
  116.         pt_parse_tag($tag_data[3], call_user_func_array($callback, array_merge($data)), $tag_data[2], $theader, $tfooter,
  117.                      $parse_callbacks, $depth, $data) :
  118.         $theader . $tag_data[3] . $tfooter;
  119.     } else
  120.       $result[$next ++] = $theader . $tag_data[3] . $tfooter;
  121.   }
  122.   if ($tpos < $tlen)
  123.     $result [$next ++] = substr($template, $tpos, $tlen - $tpos);
  124.   return pt_recursive_implode($result);
  125. }
  126.  
  127. function parse_template ($template, $parse_callbacks) {
  128.   if (!is_string($template)) $template = (string) $template;
  129.   if (!(is_callable($parse_callbacks) or is_array($parse_callbacks))) return $template;
  130.   $data = func_get_args();
  131.   array_splice($data, 0, 2);
  132.   return pt_parse_template($template, $parse_callbacks, 0, $data);
  133. }
  134.  
  135. ?>
Advertisement
RAW Paste Data Copied
Advertisement