]>
git.p6c8.net - form-email.git/blob - form-email/class.Template.php
4 # Template (Version 2.0)
6 # Klasse zum Parsen von Templates
8 # Autor: Patrick Canterino <patrick@patshaping.de>
9 # Letzte Aenderung: 3.7.2006
18 var $defined_vars = array();
19 var $loop_vars = array();
23 # Kompletten Vorlagentext zurueckgeben
27 # Rueckgabe: Kompletter Vorlagentext (String)
29 function get_template()
31 return $this->template
;
36 # Kompletten Vorlagentext aendern
38 # Parameter: Vorlagentext
40 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
42 function set_template($text)
44 $this->template
= $text;
49 # Vorlagentext ans Template-Objekt anhaengen
51 # Parameter: Vorlagentext
53 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
55 function add_text($text)
57 $this->set_template($this->get_template().$text);
62 # Einlesen einer Vorlagendatei und {INCLUDE}-Anweisungen ggf. verarbeiten
63 # (Text wird an bereits vorhandenen Text angehaengt)
65 # Parameter: 1. Datei zum Einlesen
66 # 2. Status-Code (Boolean):
67 # true => {INCLUDE}-Anweisungen nicht verarbeiten
68 # false => {INCLUDE}-Anweisungen verarbeiten (Standard)
70 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
72 function read_file($file,$not_include=0)
76 if(filesize($file) > 0)
78 $fp = fopen($file,'r');
80 $content = fread($fp,filesize($file));
85 $this->add_text($content);
88 if(!$not_include) $this->parse_includes();
93 # Wert einer Variable setzen
95 # Parameter: 1. Name der Variable
96 # 2. Wert, den die Variable erhalten soll
98 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
100 function set_var($var,$content)
102 $this->vars
[$var] = $content;
107 # Wert einer Variable zurueckgeben
109 # Parameter: (optional) Variablenname
111 # Rueckgabe: Wert der Variable;
112 # wenn die Variable nicht existiert, false;
113 # wenn kein Variablenname angegeben wurde, wird ein
114 # Array mit den Variablennamen zurueckgegeben
116 function get_var($var=false)
120 if(isset($this->vars
[$var]))
122 return $this->vars
[$var];
131 return array_keys($this->vars
);
137 # Daten fuer eine Schleife setzen
139 # Parameter: 1. Name der Schleife
140 # 2. Array mit den Arrays mit den Variablen fuer
141 # die Schleifendurchgaenge
143 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
145 function set_loop_data($loop,$data)
147 $this->loop_vars
[$loop] = $data;
152 # Daten fuer einen Schleifendurchgang hinzufuegen
154 # Parameter: 1. Name der Schleife
155 # 2. Array mit den Variablen fuer den
158 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
160 function add_loop_data($loop,$data)
162 if(isset($this->loop_vars
[$loop]) && is_array($this->loop_vars
[$loop]))
164 array_push($this->loop_vars
[$loop],$data);
168 $this->loop_vars
[$loop] = array($data);
174 # In der Template definierte Variablen auslesen, Variablen
175 # ersetzen, {IF}- und {TRIM}-Bloecke parsen
177 # Parameter: -nichts-
179 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
183 # Zuerst die Schleifen parsen
185 if(is_array($this->loop_vars
) && ($loops = array_keys($this->loop_vars
)))
187 foreach($loops as $loop)
189 $this->parse_loop($loop);
193 # Normale Variablen durchgehen
195 if(($vars = $this->get_var()) !== false && is_array($vars))
197 foreach($vars as $var)
199 $val = $this->get_var($var);
201 $this->parse_if_block($var,$val);
205 $this->fillin_array($var,$val);
209 $this->fillin($var,$val);
216 # Jetzt dasselbe mit denen, die direkt in der Template-Datei definiert
217 # sind, machen. Ich weiss, dass das eine ziemlich unsaubere Loesung ist,
218 # aber es funktioniert
220 $this->get_defined_vars();
222 foreach($this->defined_vars
as $var)
224 $val = $this->get_var($var);
226 $this->parse_if_block($var,$val);
227 $this->fillin($var,$val);
232 # {TRIM}-Bloecke entfernen
234 $this->parse_trim_blocks();
239 # Variablen durch Text ersetzen
241 # Parameter: 1. Variable zum Ersetzen
242 # 2. Text, durch den die Variable ersetzt werden soll
244 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
246 function fillin($var,$text)
248 $template = $this->get_template();
249 $template = str_replace('{'.$var.'}',$text,$template);
251 $this->set_template($template);
256 # Variable durch Array ersetzen
258 # Parameter: 1. Variable zum Ersetzen
259 # 2. Array, durch das die Variable ersetzt werden soll
260 # 3. Zeichenkette, mit der das Array verbunden werden soll
263 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
265 function fillin_array($var,$array,$glue='')
267 $this->fillin($var,implode($glue,$array));
272 # Template in Datei schreiben
274 # Parameter: Datei-Handle
276 # Rueckgabe: Status-Code (Boolean)
278 function to_file($handle)
280 return @fwrite
($handle,$this->get_template());
285 # Den gesicherten Stand des Template-Textes sichern
287 # Parameter: -nichts-
289 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
293 $this->template
= $this->original
;
298 # Aktuellen Stand des Template-Textes sichern
299 # (alte Sicherung wird ueberschrieben)
301 # Parameter: -nichts-
303 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
305 function save_state()
307 $this->original
= $this->template
;
312 # Eine Schleife parsen
314 # Parameter: Name der Schleife
316 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
318 function parse_loop($name)
320 $template = $this->get_template();
321 if(strpos($template,'{LOOP '.$name.'}') === false) return;
324 $name_len = strlen($name);
326 while(($begin = strpos($template,'{LOOP '.$name.'}',$offset)) !== false)
328 if(($end = strpos($template,'{ENDLOOP}',$begin+
6+
$name_len)) !== false)
330 $block = substr($template,$begin,$end+
9-$begin);
331 $content = substr($block,$name_len+
7,-9);
335 for($x=0;$x<count($this->loop_vars
[$name]);$x++
)
337 $loop_data = $this->loop_vars
[$name][$x];
338 $loop_vars = array_keys($loop_data);
340 $ctpl = new Template
;
341 $ctpl->set_template($content);
343 foreach($loop_vars as $loop_var)
345 $ctpl->set_var($name.'.'.$loop_var,$loop_data[$loop_var]);
349 $parsed_block .= $ctpl->get_template();
354 $template = str_replace($block,$parsed_block,$template);
355 $offset = $begin+
strlen($parsed_block);
360 $this->set_template($template);
365 # In der Template-Datei definierte Variablen auslesen
367 # Parameter: -nichts-
369 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
371 function get_defined_vars()
373 $template = $this->get_template();
374 if(strpos($template,'{DEFINE ') === false) return;
378 while(strpos($template,'{DEFINE ',$offset) !== false)
380 $begin = strpos($template,'{DEFINE ',$offset)+
8;
390 for($x=$begin;$x<strlen($template);$x++
)
392 if($template[$x] == "\012" ||
$template[$x] == "\015")
394 # Wenn in einem {DEFINE}-Block ein Zeilenumbruch gefunden wird,
395 # brechen wir mit dem Parsen des Blockes ab
402 if($template[$x] == '"')
404 # Der Inhalt der Variable ist hier zu Ende
408 if($template[$x+
1] == '}')
410 # Hier ist der Block zu Ende
412 if($this->get_var($name) === false)
414 # Die Variable wird nur gesetzt, wenn sie nicht bereits gesetzt ist
416 $this->set_var($name,$content);
417 array_push($this->defined_vars
,$name);
420 # {DEFINE}-Block entfernen
422 $pre = substr($template,0,$begin-8);
423 $post = substr($template,$x+
2);
425 $template = $pre.$post;
429 $offset = strlen($pre);
433 elseif($template[$x] == '\\')
435 # Ein Backslash wurde gefunden, er dient zum Escapen von Zeichen
437 if($template[$x+
1] == 'n')
439 # "\n" in Zeilenumbrueche umwandeln
443 else $content .= $template[$x+
1];
447 else $content .= $template[$x];
455 if($template[$x] == '"') $var_open = 1;
461 # Variablennamen auslesen
463 if($template[$x] == '}' && $name != '')
465 # Wir haben einen {DEFINE}-Block
470 # Alles ab hier sollte mit dem Teil verbunden werden, der das
471 # {DEFINE} in einer Zeile verarbeitet
473 # Der Parser fuer {DEFINE}-Bloecke ist nicht rekursiv, was auch
474 # nicht noetig sein sollte
476 if(($end = strpos($template,'{ENDDEFINE}',$x)) !== false)
480 $content = substr($template,$x,$end-$x);
482 if($this->get_var($name) === false)
484 # Die Variable wird nur gesetzt, wenn sie nicht bereits gesetzt ist
486 $this->set_var($name,$content);
487 array_push($this->defined_vars
,$name);
490 $pre = substr($template,0,$begin-8);
491 $post = substr($template,$end+
11);
493 $template = $pre.$post;
497 $offset = strlen($pre);
502 elseif($template[$x] != ' ')
504 $name .= $template[$x];
516 $this->set_template($template);
521 # IF-Bloecke verarbeiten
523 # Parameter: 1. Name des IF-Blocks (das, was nach dem IF steht)
524 # 2. Status-Code (true => Inhalt anzeigen
525 # false => Inhalt nicht anzeigen
526 # 3. true => Verneinten Block nicht parsen
527 # false => Verneinten Block parsen (Standard)
529 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
531 function parse_if_block($name,$state,$no_negate=0)
533 $template = $this->get_template();
537 while(strpos($template,'{IF '.$name.'}') !== false)
539 # Das alles hier ist nicht wirklich elegant geloest...
540 # ... aber solange es funktioniert... ;-)
544 $start = strpos($template,'{IF '.$name.'}');
545 $tpl_tmp = substr($template,$start);
546 $splitted = explode('{ENDIF}',$tpl_tmp);
548 $block = ''; # Kompletter bedingter Block
549 $ifs = 0; # IF-Zaehler (wird fuer jedes IF erhoeht und fuer jedes ENDIF erniedrigt)
553 for($x=0;$x<count($splitted);$x++
)
555 if($x == count($splitted)-1) die('Nesting error found while parsing IF block "'.$name.'" nr. '.$count.' in template file "'.$this->file
.'"');
557 $ifs +
= substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen
558 $ifs--; # Zaehler um 1 erniedrigen
559 $block .= $splitted[$x].'{ENDIF}'; # Daten zum Block hinzufuegen
563 # Zaehler wieder 0, also haben wir das Ende des IF-Blocks gefunden :-))
569 $if_block = substr($block,strlen($name)+
5,-7); # Alles zwischen {IF} und {ENDIF}
573 $else_block = ''; # Alles ab {ELSE}
574 $ifs = 0; # IF-Zaehler
576 $splitted = explode('{ELSE}',$if_block);
578 for($x=0;$x<count($splitted);$x++
)
580 $ifs +
= substr_count($splitted[$x],'{IF '); # Zum Zaehler jedes Vorkommen von IF hinzuzaehlen
581 $ifs -= substr_count($splitted[$x],'{ENDIF}'); # Vom Zaehler jedes Vorkommen von ENDIF abziehen
585 # Zaehler 0, also haben wir das Ende des IF-Abschnitts gefunden
587 # Aus dem Rest den ELSE-Block zusammenbauen
589 for($y=$x+
1;$y<count($splitted);$y++
)
591 $else_block .= '{ELSE}'.$splitted[$y];
596 $if_block = substr($if_block,0,strlen($if_block)-strlen($else_block));
597 $else_block = substr($else_block,6);
604 # Block durch die jeweiligen Daten ersetzen
606 $replacement = ($state) ?
$if_block : $else_block;
608 $template = str_replace($block,$replacement,$template);
611 $this->set_template($template);
613 # Evtl. verneinte Form parsen
617 $this->parse_if_block('!'.$name,!$state,1);
621 # parse_trim_blocks()
623 # {TRIM}-Bloecke parsen
625 # Dieser Parser ist nicht rekursiv, was auch nicht
626 # noetig sein sollte.
628 # Parameter: -nichts-
630 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
632 function parse_trim_blocks()
634 $template = $this->get_template();
635 if(strpos($template,'{TRIM}') === false) return;
639 while(($begin = strpos($template,'{TRIM}',$offset)) !== false)
641 if(($end = strpos($template,'{ENDTRIM}',$begin+
6)) !== false)
643 $block = substr($template,$begin,$end+
9-$begin);
644 $content = substr($block,6,-9);
646 $trimmed = trim($content);
648 $template = str_replace($block,$trimmed,$template);
650 $offset = $begin+
strlen($trimmed);
655 $this->set_template($template);
660 # Bedingungstags in einem Vorlagentext verarbeiten
662 # Parameter: 1. Tagname
663 # 2. Status-Code (true => Tag-Inhalt anzeigen
664 # false => Tag-Inhalt nicht anzeigen
666 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
668 function parse_condtag($condtag,$state)
670 $template = $this->get_template();
672 while(strpos($template,'<'.$condtag.'>') !== false)
674 $start = strpos($template,'<'.$condtag.'>'); # Beginn des Blocks
675 $end = strpos($template,'</'.$condtag.'>')+
strlen($condtag)+
3; # Ende des Blocks
677 $extract = substr($template,$start,$end-$start); # Kompletten Bedingungsblock extrahieren...
679 $replacement = ($state) ?
substr($extract,strlen($condtag)+
2,0-strlen($condtag)-3) : '';
681 $template = str_replace($extract,$replacement,$template); # Block durch neue Daten ersetzen
683 $this->set_template($template);
688 # {INCLUDE}-Anweisungen verarbeiten
690 # Parameter: -nichts-
692 # Rueckgabe: -nichts- (Template-Objekt wird modifiziert)
694 function parse_includes()
696 $template = $this->get_template();
697 if(strpos($template,'{INCLUDE ') === false) return;
703 while(($begin = strpos($template,'{INCLUDE ',$offset)) !== false)
711 if($template[$start] == '"')
720 for($x=$start;$x<strlen($template);$x++
)
722 if($template[$x] == "\012" ||
$template[$x] == "\015")
727 elseif($long == 0 && $template[$x] == ' ')
732 elseif($long == 1 && $template[$x] == '"')
734 if($template[$x+
1] != '}') $skip = 1;
737 elseif($long == 0 && $template[$x] == '}')
743 $file .= $template[$x];
747 if($skip == 1) continue;
753 $is_absolute = (strtoupper(substr(PHP_OS
,0,3)) === 'WIN')
754 ?
preg_match('!^([a-z]:)?/!i',$file)
755 : preg_match('!^/!',$file);
759 if(!empty($this->file
)) $dir = dirname($this->file
);
762 $dir = str_replace('\\','/',$dir);
764 if(!preg_match('!/+$!',$dir)) $dir .= '/';
766 $filepath = $dir.$file;
769 if(is_file($filepath))
772 $inc->read_file($filepath);
775 ?
$start +
strlen($file) +
2
776 : $start +
strlen($file) +
1;
778 $pre = substr($template,0,$begin);
779 $post = substr($template,$end);
781 $template = $pre.$inc->get_template().$post;
782 $offset = strlen($pre)+
strlen($inc->get_template());
789 $this->set_template($template);
patrick-canterino.de