Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

Template.php

Go to the documentation of this file.
00001 <?php 00002 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 00003 // 00004 // Copyright (c) 2003 Laurent Bedubourg 00005 // 00006 // This library is free software; you can redistribute it and/or 00007 // modify it under the terms of the GNU Lesser General Public 00008 // License as published by the Free Software Foundation; either 00009 // version 2.1 of the License, or (at your option) any later version. 00010 // 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 // Lesser General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public 00017 // License along with this library; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 // 00020 // Authors: Laurent Bedubourg <laurent.bedubourg@free.fr> 00021 // 00022 00023 00024 class PHPTAL_Template 00025 { 00026 var $_ctx; 00027 var $_code; 00028 var $_codeFile; 00029 var $_funcName; 00030 var $_sourceFile; 00031 var $_error = false; 00032 var $_repository = false; 00033 var $_cacheDir = false; 00034 var $_parent = false; 00035 var $_parentPath = false; 00036 var $_prepared = false; 00037 var $_cacheManager; 00038 00039 var $_outputMode = PHPTAL_XHTML; 00040 00041 var $_inputFilters; 00042 var $_outputFilters; 00043 var $_resolvers; 00044 var $_locator; 00045 00046 var $_headers = false; 00047 00048 var $_translator; 00049 00050 var $_encoding = 'UTF-8'; 00051 00059 function PHPTAL_Template($file, $repository=false, $cache_dir=false) 00060 { 00061 $this->_sourceFile = $file; 00062 $this->_repository = $repository; 00063 00064 // deduce intermediate php code cache directory 00065 if (!$cache_dir) { 00066 if (defined('PHPTAL_CACHE_DIR')) { 00067 $cache_dir = PHPTAL_CACHE_DIR; 00068 } else { 00069 $cache_dir = PHPTAL_DEFAULT_CACHE_DIR; 00070 } 00071 } 00072 $this->_cacheDir = $cache_dir; 00073 00074 // instantiate a new context for this template 00075 // !!! this context may be overwritten by a parent context 00076 $this->_ctx = new PHPTAL_Context(); 00077 00078 // create resolver vector and the default filesystem resolver 00079 $this->_resolvers = new OArray(); 00080 $this->_resolvers->push(new PHPTAL_SourceResolver()); 00081 00082 // vector for source filters 00083 $this->_inputFilters = new OArray(); 00084 $this->_outputFilters = new OArray(); 00085 00086 // if no cache manager set, we instantiate default dummy one 00087 if (!isset($this->_cacheManager)) { 00088 $this->_cacheManager = new PHPTAL_Cache(); 00089 } 00090 } 00091 00100 function setOutputMode($mode) 00101 { 00102 $this->_outputMode = $mode; 00103 } 00104 00110 function setAll($hash) 00111 { 00112 $this->_ctx = new PHPTAL_Context($hash); 00113 } 00114 00121 function set($name, $value) 00122 { 00123 $this->_ctx->set($name, $value); 00124 } 00125 00132 function setRef($name, &$value) 00133 { 00134 $this->_ctx->setRef($name, $value); 00135 } 00136 00142 function &getContext() 00143 { 00144 return $this->_ctx; 00145 } 00146 00152 function setContext(&$ctx) 00153 { 00154 $this->_ctx =& $ctx; 00155 } 00156 00163 function setCacheManager(&$mngr) 00164 { 00165 $this->_cacheManager =& $mngr; 00166 } 00167 00173 function &getCacheManager() 00174 { 00175 return $this->_cacheManager; 00176 } 00177 00183 function setTranslator(&$tr) 00184 { 00185 $this->_translator =& $tr; 00186 } 00187 00193 function &getTranslator() 00194 { 00195 return $this->_translator; 00196 } 00197 00203 function fileExists() 00204 { 00205 return $this->isValid(); 00206 } 00207 00213 function isValid() 00214 { 00215 if (isset($this->_locator)) { 00216 return true; 00217 } 00218 00219 // use template resolvers to locate template source data 00220 // in most cases, there will be only one resolver in the 00221 // resolvers list (the default one) which look on the file 00222 // system. 00223 00224 $i = $this->_resolvers->getNewIterator(); 00225 while ($i->isValid()) { 00226 $resolver =& $i->value(); 00227 $locator =& $resolver->resolve($this->_sourceFile, 00228 $this->_repository, 00229 $this->_parentPath); 00230 if ($locator && !PEAR::isError($locator)) { 00231 $this->_locator =& $locator; 00232 $this->_real_path = $this->_locator->realPath(); 00233 return true; 00234 } 00235 $i->next(); 00236 } 00237 return false; 00238 } 00239 00246 function addSourceResolver(&$resolver) 00247 { 00248 $this->_resolvers->pushRef($resolver); 00249 } 00250 00257 function addInputFilter(&$filter) 00258 { 00259 $this->_inputFilters->pushRef($filter); 00260 } 00261 00268 function addOutputFilter(&$filter) 00269 { 00270 $this->_outputFilters->pushRef($filter); 00271 } 00272 00289 function realpath($file=false) 00290 { 00291 // real template path 00292 if (!$file) { 00293 if ($this->isValid()) { 00294 return $this->_real_path; 00295 } else { 00296 $ex = new FileNotFound($this->_sourceFile . ' not found'); 00297 return PEAR::raiseError($ex); 00298 } 00299 } 00300 00301 // 00302 // path to some file relative to this template 00303 // 00304 $i = $this->_resolvers->getNewIterator(); 00305 while ($i->isValid()) { 00306 $resolver =& $i->value(); 00307 $locator =& $resolver->resolve($file, 00308 $this->_repository, 00309 $this->_real_path); 00310 if ($locator) { 00311 return $locator->realPath(); 00312 } 00313 $i->next(); 00314 } 00315 00316 $ex = new FileNotFound($file . ' not found'); 00317 return PEAR::raiseError($ex); 00318 } 00319 00334 function setEncoding($enc) 00335 { 00336 $this->_encoding = $enc; 00337 } 00338 00344 function getEncoding() 00345 { 00346 return $this->_encoding; 00347 } 00348 00349 // ---------------------------------------------------------------------- 00350 // private / protected methods 00351 // ---------------------------------------------------------------------- 00352 00358 function setParent(&$tpl) 00359 { 00360 $this->_parent =& $tpl; 00361 $this->_resolvers = $tpl->_resolvers; 00362 $this->_inputFilters = $tpl->_inputFilters; 00363 $this->_parentPath = $tpl->realPath(); 00364 $this->_cacheManager =& $tpl->getCacheManager(); 00365 $this->_translator =& $tpl->_translator; 00366 $this->setOutputMode($tpl->_outputMode); 00367 } 00368 00374 function _prepare() 00375 { 00376 if ($this->_prepared) return; 00377 $this->_sourceFile = $this->realpath(); 00378 00379 // ensure that no error remain 00380 if (PEAR::isError($this->_sourceFile)) { 00381 return $this->_sourceFile; 00382 } 00383 $this->_funcName = "tpl_" . PHPTAL_MARK . md5($this->_sourceFile); 00384 $this->_codeFile = $this->_cacheDir . $this->_funcName . '.php'; 00385 $this->_prepared = true; 00386 } 00387 00394 function _generateCode() 00395 { 00396 require_once _phptal_os_path_join(dirname(__FILE__), 'Parser.php'); 00397 00398 $parser = new PHPTAL_Parser(); 00399 $parser->_outputMode($this->_outputMode); 00400 $data = $this->_locator->data(); 00401 00402 // activate prefilters on data 00403 $i = $this->_inputFilters->getNewIterator(); 00404 while ($i->isValid()){ 00405 $filter =& $i->value(); 00406 $data = $filter->filter($data); 00407 $i->next(); 00408 } 00409 00410 // parse source 00411 $result = $parser->parse($this->_real_path, $data); 00412 if (PEAR::isError($result)) { 00413 return $result; 00414 } 00415 00416 // generate and store intermediate php code 00417 $this->_code = $parser->generateCode($this->_funcName); 00418 if (PEAR::isError($this->_code)) { 00419 return $this->_code; 00420 } 00421 } 00422 00428 function _loadCachedCode() 00429 { 00430 include_once($this->_codeFile); 00431 $this->_code = "#loaded"; 00432 } 00433 00439 function _cacheCode() 00440 { 00441 $fp = @fopen($this->_codeFile, "w"); 00442 if (!$fp) { 00443 return PEAR::raiseError($php_errormsg); 00444 } 00445 fwrite($fp, $this->_code); 00446 fclose($fp); 00447 } 00448 00454 function _load() 00455 { 00456 if (isset($this->_code) && !PEAR::isError($this->_code)) { 00457 return; 00458 } 00459 00460 if (!defined('PHPTAL_NO_CACHE') 00461 && file_exists($this->_codeFile) 00462 && filemtime($this->_codeFile) >= $this->_locator->lastModified()) { 00463 return $this->_loadCachedCode(); 00464 } 00465 00466 $err = $this->_generateCode(); 00467 if (PEAR::isError($err)) { 00468 return $err; 00469 } 00470 00471 $err = $this->_cacheCode(); 00472 if (PEAR::isError($err)) { 00473 return $err; 00474 } 00475 00476 $err = $this->_loadCachedCode(); 00477 if (PEAR::isError($err)) { 00478 return $err; 00479 } 00480 } 00481 00490 function execute() 00491 { 00492 $err = $this->_prepare(); 00493 if (PEAR::isError($err)) { 00494 $this->_ctx->_errorRaised = true; 00495 return $err; 00496 } 00497 return $this->_cacheManager->template($this, 00498 $this->_sourceFile, 00499 $this->_ctx); 00500 } 00501 00513 function _process() 00514 { 00515 $err = $this->_load(); 00516 if (PEAR::isError($err)) { 00517 $this->_ctx->_errorRaised = true; 00518 return $err; 00519 } 00520 00521 $this->_ctx->_errorRaised = false; 00522 $func = $this->_funcName; 00523 if (!function_exists($func)) { 00524 $err = "Template function '$func' not found (template source : $this->_sourceFile"; 00525 return PEAR::raiseError($err); 00526 } 00527 00528 // ensure translator exists 00529 if (!isset($this->_translator)) { 00530 $this->_translator = new PHPTAL_I18N(); 00531 } 00532 00533 $res = $func($this); 00534 if ($this->_headers) { 00535 $res = $this->_headers . $res; 00536 } 00537 00538 // activate post filters 00539 $i = $this->_outputFilters->getNewIterator(); 00540 while ($i->isValid()) { 00541 $filter =& $i->value(); 00542 $res = $filter->filter($this, $res, PHPTAL_POST_FILTER); 00543 $i->next(); 00544 } 00545 return $res; 00546 } 00547 00548 function _translate($key) 00549 { 00550 return $this->_translator->translate($key); 00551 } 00552 00553 function _setTranslateVar($name, $value) 00554 { 00555 if (is_object($value)) { 00556 $value = $value->toString(); 00557 } 00558 $this->_translator->set($name, $value); 00559 } 00560 } 00561 00562 ?>

Generated on Tue Jun 29 23:40:07 2004 for Mediawiki by doxygen 1.3.7