 
        
        
        
######################   Template Class ####################
#
# Met de class Template is het mogelijk om in een template bestand bepaalde variable-waarden te plaatsen.
# dit maakt het makkelijker voor disgners om een layout te veranderen zonder php te hoeven gebruiken.
# De template file kan elk normaal ascii bestand zijn en kan bestaan uit HTML, gewone tekst etc etc.
# Het model wat word vervangen heeft het volgende formaat: %[(a-z)]%
#
# Vereiste variabelen:
# $vars --  Een array gevuld met sleutel waarden die in het template bestand moeten worden
#           vervangen en de daarbijbehordende nieuwe waarden.
#
# Het systeem is:
#   - Hoofdletter ongevoelig,
#   - Alfanumerieke tekens en _ worden geaccepteerd,
#
# Vb.:
# $var = new Template("textfile.template.html");
# print $var->parse(    // aanroep om "dailer.template.htm" te parsen
#       array(
#           "link" => $templateLink,    // in het template bestand word "%[link]% vervangen door de waarde in $templateLink
#       )
#   );
#
######
# Door:     Willem de Vries
# Date:     9 februari 2005
# Voor:     Virtual Pc Services
# Versie:   2.2
#
######
# Changelog:
#    1.0 (WdV 7-11-2003): statische functie ombouwen naar object
#    1.1 (WdV 13-2-2004): parsen moet ook zonder parameters kunnen
#    1.2 (JF  15-2-2004): Set functie toegevoegd om variablen aan template toe te voegen, aaroep: set(variablenaam, value)
#    1.3 (JF  24-3-2004): Endless loop bug gefixed, bij openen van template kwam hij bij lege file of file zonder
#                         regeleinde niet bij eof bij lezen van filesize.
#    1.4 (WdV 04-3-2005): Nieuwe functie om default-waardes uit een HTML-comment veld te halen.
#    2.0 (WdV 09-2-2005): grotendeels herschreven refresh() en parse() routine. Nu 50% sneller!
#    2.1 (WdV 15-2-2005): Mogelijkheid om een template aan te maken vanuit een string ipv. een file uit te lezen
#    2.2 (WdV 28-10-2005): On-the-fly compressie om geheugen te sparen, kleinere array properties
#    2.3 (WdV 15-12-2005): Gebruik van de "TEMPLATE_SEARCH" superglobal om een (relatief) zoekpad op te geven waarin
#                          templates gezocht moeten worden.
###############################################################
function _slashjoin() {
    $out = array();
    foreach(func_get_args() as $param) {
        if ($param)
            $out[] = $param;
    }
    return preg_replace('#([/]+)#', '/', join('/', $out));
}
function _dirlist($str, $regex = '.*') {
    $out = array();
    $dh = (is_dir($str)) ? @opendir($str) : null;
    while ($dh and $fil = readdir($dh)) {
        $out[] = _slashjoin($str, $fil);
    }
    if ( !$out) return;
    list($item) = array_values(preg_grep("|$regex|i", $out));
#    error_log(__FUNCTION__ . " Matching items for |$regex|");
#    error_log(__FUNCTION__ . " Subdirs in $str: " . join('|', $out));
#    error_log(__FUNCTION__ . " Found dir '$item'");
    return ($item) ? $item : $str;
}
class Template {
    var $fn = null;
    var $filename = null;
    var $ch = null;
    var $error = null;
    var $searchpath = null;
    var $searchdir = null;
    var $inf = null;
    var $def = null;
    var $me = 'object';
    var $vars = array();
    function Template($name) {
        # Compatibility
        $this->filename =& $this->fn;
        $this->me = strtoupper(get_class($this));
        $this->searchpath = $GLOBALS[$this->me . "_SEARCH"];
        if (defined($this->me . "_COMPRESS")) {
            foreach(array(array('gzcompress', 'gzuncompress'), array('gzdeflate', 'gzinflate')) as $grp) {
                if (function_exists($grp[0])) {
                    $this->def = $grp[0];
                    $this->inf = $grp[1];
                    break;
                }
            }
        }
        $this->fn = $name;
        $this->refresh();
    }
    function set($varname, $value = ''){
        $this->vars[$varname] = $value;
    }
    function get($varname) {
        return $this->vars[$varname];
    }
    function refresh() {
        if (!preg_match('/\.([^\.\/\s]+)$/', $this->fn, $found) ) {
             $this->cached($this->fn);
             $this->fn = null;
             $this->error = null;
             return;
        }
        # Implementatie zoekpad
        $subdirs = preg_split('/([\s]*;[\s]*)/', $this->searchpath);
        if (! $subdirs)
            $subdirs = array('');
        list($a, $up, $b, $path) = preg_match('/^(([\.]+\/)*)(.+)/', $this->fn, $found) ? $found : array('', '', '', $found[0]);
        foreach($subdirs as $subdir) {
            $sub = _slashjoin($up, $subdir);
            # Wanneer de basis zoekdirectory niet bestaat, dan controleren we nog even
            # of deze naam niet partieel voorkomt ergens in de boom. Zie functie _dirlist().
            if ($subdir and !is_dir($sub)) {
                $sub = _dirlist(dirname($sub), preg_replace('/([^0-9a-z]+)$/', '', $subdir) );
            }
            $this->searchdir = _slashjoin($sub, $path);
            $exists = (file_exists($this->searchdir) and filesize($this->searchdir) > 0);
            if ($exists) {
                $this->searchpath = $sub;
                break;
            }
        }
        $readable = ($exists and is_readable($this->searchdir) );
        $soort = ($readable) ? filetype($this->searchdir) : "";
        if ($readable and $soort == "file") {
            $this->cached( join('', file($this->searchdir)) );
            $this->error = null;
        } elseif (!$exists) {
            $this->error( sprintf("'%s' bestaat niet.", $this->searchdir) );
        } elseif (!$readable) {
            $this->error( sprintf("'%s' kan niet worden gelezen.", $this->searchdir) );
        } elseif ($exists && $soort != "file") {
            $this->error( sprintf("'%s' is geen geldig bestand; %s", $this->searchdir, $soort) );
        }
        return;
    }
    function error($str) {
        $text = sprintf('%s %s [in %s]', $this->me, $str, $_SERVER['SCRIPT_NAME']);
        $this->error = $text;
        if ($_SERVER['IS_DEVEL'] and $this->error) error_log($this->error);
    }
    function parse($vars = array()) {
        $vars = $vars + $this->vars;
        if ($this->searchpath)
            # Voeg een slash toe aan het einde van het pad - templates verwachten dit!
            $vars['_searchpath'] = trim(_slashjoin($this->searchpath, ' '));
        $match = array();
        $repl = array();
        foreach(array_keys($vars) as $key){
            $match[] = sprintf("/(%%\[%s\]%%)/i", preg_quote($key));
            $repl[] = $vars[$key];
        }
        $match[] = '/%\[[^\[\]]+\]%/';   # Catch all
        $repl[] = '';
        return preg_replace($match, $repl, $this->cached());
    }
    function extractData() {
        $reg = '/<\!--(\s*([^=\s\<\>]+)[\s=]+[\'"]?([^\'"\s\<\>]+))+\s*-->/';
        $comment = '/<\!--\s*(.+)\s*-->/';
        $fields = '/([^=\s<>]+)[\s=]+([\'\"])?([^\s<>\2]+)/';
        if (! preg_match_all($comment, $this->cached(), $found) )
            return false;
        foreach($found[1] as $line) {
            preg_match_all($fields, $line, $res);
            for($i=0; $i < sizeof($res[0]); $i++) {
                $this->vars[$res[1][$i]] = $res[3][$i];
            }
        }
        return $this->vars;
    }
    function cached($str = null) {
            if (is_null($str)) {
                #request
                $do = $this->inf;
                return ($this->compressed() and $this->ch) ? $do($this->ch) : $this->ch;
            }
            $do = $this->def;
            $this->ch = ($this->compressed()) ? $do($str, 9) : $str;
    }
    function compressed() {
        return ($this->inf || $this->def);
    }
}
# EOF
?>
 
	Deze afbeelding is verkleind. Klik op het plaatje om de volledige afbeelding te bekijken.
 
