00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00075
00076 $this->_ctx =
new PHPTAL_Context();
00077
00078
00079 $this->_resolvers =
new OArray();
00080 $this->_resolvers->push(
new PHPTAL_SourceResolver());
00081
00082
00083 $this->_inputFilters =
new OArray();
00084 $this->_outputFilters =
new OArray();
00085
00086
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
00220
00221
00222
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
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
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
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
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
00403
$i = $this->_inputFilters->getNewIterator();
00404
while (
$i->isValid()){
00405 $filter =&
$i->value();
00406 $data = $filter->filter($
data);
00407
$i->next();
00408 }
00409
00410
00411 $result = $parser->parse($this->_real_path, $
data);
00412
if (PEAR::isError($result)) {
00413
return $result;
00414 }
00415
00416
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
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
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 ?>