<?php /*~ template.driver.inc.php
.---------------------------------------------------------------------------.
|  Software: Document Template Engine                                       |
|   Version: 2.1                                                            |
|   Contact: via www.uniwits.com                                            |
|      Info: http://www.uniwits.com/DTEv2/                                  |
|   Support: http://www.uniwits.com/support/                                |
| ------------------------------------------------------------------------- |
|     Admin: Yuxiang Mao (project admininistrator)                          |
|   Authors: Yuxiang Mao (Uniwits) support@reserv.uniwits.com               |
|   Founder: Yuxiang Mao                                                    |
| Copyright (c) 2010-2012, Yuxiang Mao. All Rights Reserved.                |
| ------------------------------------------------------------------------- |
|   License: Distributed under Uniwits Shareware License (USL)              |
|            http://www.uniwits.com/licenses/shareware/                     |
| This program is distributed as a part of software provided by Uniwits     |
| System WITHOUT ANY WARRANTY; without even the implied warranty of         |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                      |
| ------------------------------------------------------------------------- |
*/ require_once('template.gen.inc.php'); class TemplateDriver { var $root; var $accesstable; var $dataset; function TemplateDriver(&$parsedTmpl,&$dataset) { $this->root=&$parsedTmpl['root']; $this->accesstable=&$parsedTmpl['accesstable']; $this->dataset=&$dataset; } function output() { $TT=array(null=>0); $this->write($this->root,$TT,$this->dataset); } function writeout($methodarr,$str) { if ($methodarr) { for ($mi=sizeof($methodarr)-1;$mi>=0;$mi--) { switch ($methodarr[$mi]) { case 1: $str=urlencode($str); break; case 2: $str=htmlspecialchars($str); break; case 3: $str=nl2br(htmlspecialchars($str)); break; case 4: $str=addcslashes($str,"\0..\37\\'\""); break; case 5: $str=htmlspecialchars($str); $str=TemplateGenerator::parse_links($str); break; case 6: $str=nl2br(htmlspecialchars($str)); $str=TemplateGenerator::parse_links($str); break; case 7: $str=str_replace('-','--',$str); break; } } } $this->writeoutraw($str); } function writeoutraw($str) { echo $str; } function write(&$subroot,&$zbTimeTable,&$dataset) { for ($i=0;$i<sizeof($subroot);$i++) { switch ($subroot[$i][0]) { case 1: $this->writeout(0,$subroot[$i][1]); break; case 2: $this->writeout($subroot[$i][1],$this->query($subroot[$i][2],$zbTimeTable,$dataset)); break; case 3: $iTime=array(0); $aqid=$subroot[$i][1]; $substru=array(&$subroot[$i][2]); $zbTimeTable[$aqid[sizeof($aqid)-1]]=&$iTime[0]; $ads=@$this->getAreaDataSet($aqid,sizeof($aqid),$zbTimeTable,$dataset); for ($iTime[0]=0;$iTime[0]<sizeof($ads);$iTime[0]++) { if (isset($ads[$iTime[0]])) $this->write($substru[0],$zbTimeTable,$dataset); } $iTime[0]=0; break; case 4: $calledidlen=sizeof($subroot[$i][1]); $aid=$subroot[$i][1][$calledidlen-1]; $as=$this->accesstable[$aid]; if (sizeof($subroot[$i][1])>1) { $dataaid=$subroot[$i][1]; array_pop($dataaid); $ads=$this->query($dataaid,$zbTimeTable,$dataset); } else $ads=$dataset; if ($ads!==NULL) { $subTT=array(null=>0); $this->write($as,$subTT,$ads); } break; case 5: $qv=$this->query($subroot[$i][2],$zbTimeTable,$dataset); if (0<=$qv && $qv<sizeof($subroot[$i][3])) $this->writeout($subroot[$i][1],$subroot[$i][3][$qv]); break; } } } function getAreaDataSet(&$aqid,$idxLimit,&$zbTimeTable,&$dataset) { $ads=array(&$dataset); for ($i=0;$i<$idxLimit-1;$i++) { if (!isset($ads[0][ $aqid[$i] ][ $zbTimeTable[$aqid[$i]] ])) return NULL; $ads=array(&$ads[0][ $aqid[$i] ][ $zbTimeTable[$aqid[$i]] ]); } if ($idxLimit>0) return $ads[0][$aqid[$idxLimit-1]]; else return $ads; } function query(&$aqid,&$zbTimeTable,&$dataset) { $topIdx=sizeof($aqid)-1; $areaDataSet=$this->getAreaDataSet($aqid,$topIdx,$zbTimeTable,$dataset); $vid=$aqid[$topIdx]; if ($topIdx<=0) { return $dataset[$vid]; } else { $iTime=(int)$zbTimeTable[$aqid[$topIdx-1]]; return $areaDataSet[$iTime][$vid]; } } function getRoot() { return $this->root; } } class TemplateLoader { var $fixedLabels; var $dataset; var $labelsLoaded; var $labelFiles; var $Cache_File_Mode=0664; function TemplateLoader(&$dataset,$fixedLabels=array()) { $this->dataset=&$dataset; $this->fixedLabels=&$fixedLabels; $this->labelsLoaded=false; $this->labelFiles=array(); } function addLabelFiles($filenameOrArray) { if (is_string($filenameOrArray)) array_push($this->labelFiles,$filenameOrArray); elseif (is_array($filenameOrArray)) $this->labelFiles=array_merge($this->labelFiles,$filenameOrArray); } static function loadLabelFromFile($filename) { $fp=fopen($filename,'rb'); $parts=array(); while ($pt=fgets($fp,4096)) array_push($parts,$pt); fclose($fp); $wholefile=implode("",$parts); return self::loadLabelFromText($wholefile); } static function loadLabelFromText($wholefile) { $fixedLabels=array(); for ($wfi=0,$wfsize=strlen($wholefile);$wfi<$wfsize;) { $nlbl=strcspn($wholefile,"\r\n",$wfi); $nlbi=$wfi+$nlbl; $line=substr($wholefile,$wfi,$nlbl); if ($nlbi+1<$wfsize && $wholefile[$nlbi]==="\r" && $wholefile[$nlbi+1]==="\n") $wfi=$nlbi+2; else $wfi=$nlbi+1; if (!trim($line)) continue; $parts=explode("=",$line,2); if (strlen($parts[1])<1024 && strlen($parts[1])>3 && (strncmp($parts[1],'<<<',3)===0 || strncmp($parts[1],'<<[',3)===0)) { $endSymbol=substr(trim($parts[1]),3); $startwfi=$wfi; $endwfi=$wfi; while ($wfi<$wfsize) { $nlbl=strcspn($wholefile,"\r\n",$wfi); $nbli=$wfi+$nlbl; $line=substr($wholefile,$wfi,$nlbl); if ($nbli+1<$wfsize && $wholefile[$nbli]==="\r" && $wholefile[$nbli+1]==="\n") $wfi=$nbli+2; else $wfi=$nbli+1; if ($line===$endSymbol) break; $endwfi=$nbli; } if (strncmp($parts[1],'<<[',3)==0) { $text=substr($wholefile,$startwfi,$endwfi-$startwfi); $text=str_replace("\r","",$text); $text=str_replace("\n","",$text); $fixedLabels[trim($parts[0])]=$text; } else $fixedLabels[trim($parts[0])]=substr($wholefile,$startwfi,$endwfi-$startwfi); } else { $fixedLabels[trim($parts[0])]=$parts[1]; } } return $fixedLabels; } function loadFixedLabels() { if ($this->labelsLoaded) return $this->fixedLabels; $this->labelsLoaded=true; for ($lfi=sizeof($this->labelFiles)-1;$lfi>=0;$lfi--) $this->fixedLabels+=self::loadLabelFromFile($this->labelFiles[$lfi]); return $this->fixedLabels; } function compiledFileName($tmplFileName,$parameter,$depFiles=array()) { $namesum=$tmplFileName; $tfs=stat($tmplFileName); $fullname=$tfs[0].'#'.base_convert($tfs[1],10,36).'#'; $fullname.='#'; foreach ($depFiles as $df) { $namesum.='\0'; $namesum.=$df; $s=stat($df); $fullname.=$s[0].'.'.base_convert($s[1],10,36).'-'; } $fullname.='#'.base_convert(sprintf("%u",crc32($namesum)),10,36).'#'; $trail=base64_encode($parameter); $trail=str_replace('-','-0',$trail); $trail=str_replace('+','-1',$trail); $trail=str_replace('/','-2',$trail); return $fullname.$trail; } function newTemplateGenerator($tmplFileName,&$fixedLabels,&$dependsOnFiles) { return new TemplateGenerator($tmplFileName,$fixedLabels,$dependsOnFiles); } function newTemplateDriver(&$parsedData) { return new TemplateDriver($parsedData,$this->dataset); } function file_put_contents($filename,$data) { $dir=dirname($filename); if (!is_dir($dir)) @mkdir($dir,0755|$this->Cache_File_Mode,true); $fp=fopen($filename,"wb"); fwrite($fp,$data); fclose($fp); } function file_get_contents($filename) { $fp=fopen($filename,"rb"); $data=fread($fp,filesize($filename)); fclose($fp); return $data; } function load($tmplFileName,$cachePrefix='./',$parameter='',$dependsOnFiles=array()) { if ($cachePrefix!==null && !is_string($cachePrefix)) trigger_error("The second argument of load is expected to be a string."); if (!is_string($parameter)) trigger_error("The third argument of load is expected to be a string."); if ($cachePrefix!==null) { $ptdfile=$cachePrefix.$this->compiledFileName($tmplFileName,$parameter,$dependsOnFiles); $parsedData=@unserialize($this->file_get_contents($ptdfile)); } else { $ptdfile=false; $parsedData=false; } $orgMTime=filemtime($tmplFileName); $dependsOnFiles=$dependsOnFiles+$this->labelFiles; $somediff=false; foreach($dependsOnFiles as $dof) { if (file_exists($dof)) { $dofmt=filemtime($dof); if ($orgMTime<$dofmt) $orgMTime=$dofmt; if ($parsedData) { if ($parsedData['dependsOnFiles'][$dof]['size']!=filesize($dof)) $somediff=true; } } } $ptdMTime=$ptdfile?@filemtime($ptdfile):0; if ($somediff || !$ptdMTime || $ptdMTime<$orgMTime) { $fixedLabels=$this->loadFixedLabels(); $parser=$this->newTemplateGenerator($tmplFileName,$fixedLabels,$dependsOnFiles); $parsedData=$parser->generate(); if ($cachePrefix!==null) { $this->file_put_contents($ptdfile,serialize($parsedData)); chmod($ptdfile,$this->Cache_File_Mode); touch($ptdfile,$orgMTime); } } return $this->newTemplateDriver($parsedData,$this->dataset); } } ?>