summaryrefslogtreecommitdiff
path: root/web/include/Template.inc
diff options
context:
space:
mode:
Diffstat (limited to 'web/include/Template.inc')
-rw-r--r--web/include/Template.inc238
1 files changed, 238 insertions, 0 deletions
diff --git a/web/include/Template.inc b/web/include/Template.inc
new file mode 100644
index 0000000..144bcdb
--- /dev/null
+++ b/web/include/Template.inc
@@ -0,0 +1,238 @@
+<?
+ # vim:set ts=4:
+ # vim:set shiftwidth=4:
+
+ /*
+ * Beat - 3node BTS
+ * (c) 2002
+ * Guenther Harrasser/3node
+ * Peter Palfrader/3node
+ * Florian Reitmeir/3node
+ * Bernhard Weitzhofer/3node
+ *
+ * $Id:$
+ */
+
+#
+# Todo:
+# * cachen von Positionen
+# * Dokumentation
+# * Aufräumen
+# * bei IF / UNLESS mit mehreren Values AND/OR auswahl ermöglichen
+#
+class Template
+{
+ var $raw_content;
+ var $parsed_content;
+ var $path;
+
+ var $begin_parse_time;
+ var $end_parse_time;
+
+
+ #
+ # new Class, read file..
+ function Template($filename,$path='.')
+ {
+ $this->path=$path;
+ $content_array = file($this->path.'/'.$filename);
+ $this->raw_content = implode("", $content_array);
+ $this->global_data=array();
+ }
+
+ function parse(&$data)
+ {
+ if ( ! $this->begin_parse_time )
+ $this->begin_parse_time = microtime();
+ if ( $GLOBALS['global_template_params'] )
+ $data = array_merge($data, $GLOBALS['global_template_params']);
+ $this->parsed_content=$this->parse_rek($data, $this->raw_content);
+ $this->end_parse_time = microtime();
+ }
+
+ function evaluate(&$data, &$name, &$values, $and)
+ {
+ if ($and === true)
+ $return_value = true;
+ else
+ $return_value = false;
+
+ foreach ($values as $value)
+ {
+ if ($and === true)
+ $return_value &= ($data[$name]==$value);
+ else
+ $return_value |= ($data[$name]==$value);
+ }
+ return $return_value;
+ }
+
+ function parse_rek(&$data, &$raw)
+ {
+ $position = 0;
+ $out = '';
+ # JA, dieses komische !== brauchts wirklich so.
+ # GENAU SO
+ # GLAUBS MIR EINFACH
+ # $a !== $b Not identical TRUE if $a is not equal to $b, or they are not of the same type. (PHP 4 only)
+ while ( ($command_position=strpos($raw, '<TMPL', $position) ) !== false )
+ {
+ # get text before command
+ $out.=substr($raw, $position, $command_position-$position);
+
+ # get command
+ preg_match("/_(.+?)\s+NAME=\"(.+?)\"(?:\s+VALUE=\"(.+?)\")?.*?>/", substr($raw,$command_position), $matches);
+ $command = array();
+ $command['command']=$matches[1];
+ $command['name']=$matches[2];
+ if (isset($matches[3])) {
+ $command['value']=$matches[3];
+ preg_match("/(VALUE=.*)\s*>/", substr($raw,$command_position), $matches);
+ if ( isset($matches) )
+ {
+ $command['values'] = explode('VALUE=', $matches[1]);
+ unset($command['values'][0]);
+ foreach ( $command['values'] as $key=>$value)
+ {
+ $command['values'][$key] = substr(trim($value),1,-1);
+ }
+ }
+ }
+
+ # get new position
+ $position=strpos($raw, '>', $command_position)+1;
+
+ switch($command['command'])
+ {
+ case 'INCLUDE':
+ $template = new Template($command['name'],$this->path);
+ $template->parse($data);
+ $out.=$template->output();
+ break;
+ case 'VAR_NOESC':
+ $out.=$data[$command['name']];
+ break;
+ case 'VAR':
+ $out.=htmlspecialchars($data[$command['name']]);
+ break;
+ case 'UNLESS':
+ $endif_command_position=strpos($raw, '</TMPL_UNLESS NAME="'.$command['name'].'">', $position);
+ $if_text=substr($raw, $position,$endif_command_position-$position);
+ $position=strpos($raw, '>', $endif_command_position)+1;
+
+ if (isset($command['value']))
+ {
+ if ( ! $this->evaluate($data, $command['name'], $command['values'], false) )
+ #if ( $data[$command['name']]!=$command['value'] )
+ $out.=$this->parse_rek($data, $if_text);
+ }
+ else
+ {
+ if ( ! $data[$command['name']] )
+ $out.=$this->parse_rek($data, $if_text);
+ }
+ break;
+ case 'IF':
+ $endif_command_position=strpos($raw, '</TMPL_IF NAME="'.$command['name'].'">', $position);
+ $if_text=substr($raw, $position,$endif_command_position-$position);
+ $position=strpos($raw, '>', $endif_command_position)+1;
+
+ if (isset($command['value']))
+ {
+ if ( $this->evaluate($data, $command['name'], $command['values'], false) )
+ # if ( $data[$command['name']]==$command['value'] )
+ $out.=$this->parse_rek($data, $if_text);
+ }
+ else
+ {
+ if ( $data[$command['name']] )
+ $out.=$this->parse_rek($data, $if_text);
+ }
+ break;
+ case 'CMP':
+ $endif_command_position=strpos($raw, '</TMPL_CMP NAME="'.$command['name'].'">', $position);
+ $if_text=substr($raw, $position,$endif_command_position-$position);
+ $position=strpos($raw, '>', $endif_command_position)+1;
+
+ if ( $data[$command['name']]==$data[$command['value']] )
+ $out.=$this->parse_rek($data, $if_text);
+ break;
+ case 'LOOP':
+ $endloop_command_position=strpos($raw, '</TMPL_LOOP NAME="'.$command['name'].'">', $position);
+ $loop_text=substr($raw, $position,$endloop_command_position-$position);
+ $position=strpos($raw, '>', $endloop_command_position)+1;
+
+ if ( isset($data[$command['name']]) )
+ {
+ foreach ( $data[$command['name']] as $row )
+ {
+ # test if row is set...
+ if ( isset( $row ) )
+ {
+ # set global variable scope
+ $local=array_merge($data, $row);
+ $out.=$this->parse_rek($local, $loop_text);
+ }
+ }
+ }
+ break;
+# (TMPL_ACCESS - wie TPL_LOOP, nur, dass nicht auf alle array-elemente zugegriffen wird,
+# sondern nur auf das in VALUE angegebene. wird VALUE nicht angegeben, wird das 1. element verwendet.)
+ case 'ACCESS':
+ $endaccess_command_position=strpos($raw, '</TMPL_ACCESS NAME="'.$command['name'].'">', $position);
+ $access_text=substr($raw, $position,$endaccess_command_position-$position);
+ $position=strpos($raw, '>', $endaccess_command_position)+1;
+ if ( isset($data[$command['name']]) ) {
+ if ( isset( $command['value'] ) ) {
+ $row = $data[$command['name']][$command['value']];
+ }
+ else {
+ reset( $data[$command['name']] );
+ $row = current( $data[$command['name']] );
+ }
+ if ( isset( $row ) )
+ {
+ # set global variable scope
+ $local=array_merge($data, $row);
+ $out.=$this->parse_rek($local, $access_text);
+ }
+ }
+ break;
+ case 'NAMESPACE':
+ $endloop_command_position=strpos($raw, '</TMPL_NAMESPACE NAME="'.$command['name'].'">', $position);
+ $loop_text=substr($raw, $position,$endloop_command_position-$position);
+ $position=strpos($raw, '>', $endloop_command_position)+1;
+
+ if ( isset($data[$command['name']]) )
+ {
+ $row = $data[$command['name']];
+ # set global variable scope
+ $local=array_merge($data, $row);
+ $out.=$this->parse_rek($local, $loop_text);
+ }
+ break;
+ case 'RANDOM':
+ $endloop_command_position = strpos($raw, '</TMPL_RANDOM NAME="'.$command['name'].'">', $next_pos);
+ $loop_text=substr($raw, $position,$endloop_command_position-$position);
+
+ $hits = split( '<TMPL_RANDOM NAME="'.$command['name'].'">', $loop_text );
+ $chosen = rand(0, sizeof($hits) - 1);
+ $position=strpos($raw, '>', $endloop_command_position)+1;
+
+ $out.=$this->parse_rek($data, $hits[$chosen]);
+ break;
+ }
+ }
+ $out.=substr($raw, $position);
+ return $out;
+ }
+
+ function output()
+ {
+ header('Cache-Control: no-cache, must-revalidate');
+ header('Pragma: no-cache');
+ $time = $this->end_parse_time-$this->begin_parse_time;
+ return $this->parsed_content."\n<!-- time: ".$time." secs -->\n";
+ }
+}
+?>