|
1 <?php |
|
2 /** |
|
3 * Smarty Resource Plugin |
|
4 * |
|
5 * @package Smarty |
|
6 * @subpackage TemplateResources |
|
7 * @author Rodney Rehm |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Smarty Resource Plugin |
|
12 * |
|
13 * Base implementation for resource plugins |
|
14 * |
|
15 * @package Smarty |
|
16 * @subpackage TemplateResources |
|
17 */ |
|
18 abstract class Smarty_Resource { |
|
19 /** |
|
20 * cache for Smarty_Template_Source instances |
|
21 * @var array |
|
22 */ |
|
23 public static $sources = array(); |
|
24 /** |
|
25 * cache for Smarty_Template_Compiled instances |
|
26 * @var array |
|
27 */ |
|
28 public static $compileds = array(); |
|
29 /** |
|
30 * cache for Smarty_Resource instances |
|
31 * @var array |
|
32 */ |
|
33 public static $resources = array(); |
|
34 /** |
|
35 * resource types provided by the core |
|
36 * @var array |
|
37 */ |
|
38 protected static $sysplugins = array( |
|
39 'file' => true, |
|
40 'string' => true, |
|
41 'extends' => true, |
|
42 'stream' => true, |
|
43 'eval' => true, |
|
44 'php' => true |
|
45 ); |
|
46 |
|
47 /** |
|
48 * Name of the Class to compile this resource's contents with |
|
49 * @var string |
|
50 */ |
|
51 public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; |
|
52 |
|
53 /** |
|
54 * Name of the Class to tokenize this resource's contents with |
|
55 * @var string |
|
56 */ |
|
57 public $template_lexer_class = 'Smarty_Internal_Templatelexer'; |
|
58 |
|
59 /** |
|
60 * Name of the Class to parse this resource's contents with |
|
61 * @var string |
|
62 */ |
|
63 public $template_parser_class = 'Smarty_Internal_Templateparser'; |
|
64 |
|
65 /** |
|
66 * Load template's source into current template object |
|
67 * |
|
68 * {@internal The loaded source is assigned to $_template->source->content directly.}} |
|
69 * |
|
70 * @param Smarty_Template_Source $source source object |
|
71 * @return string template source |
|
72 * @throws SmartyException if source cannot be loaded |
|
73 */ |
|
74 public abstract function getContent(Smarty_Template_Source $source); |
|
75 |
|
76 /** |
|
77 * populate Source Object with meta data from Resource |
|
78 * |
|
79 * @param Smarty_Template_Source $source source object |
|
80 * @param Smarty_Internal_Template $_template template object |
|
81 */ |
|
82 public abstract function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null); |
|
83 |
|
84 /** |
|
85 * populate Source Object with timestamp and exists from Resource |
|
86 * |
|
87 * @param Smarty_Template_Source $source source object |
|
88 */ |
|
89 public function populateTimestamp(Smarty_Template_Source $source) |
|
90 { |
|
91 // intentionally left blank |
|
92 } |
|
93 |
|
94 |
|
95 /** |
|
96 * modify resource_name according to resource handlers specifications |
|
97 * |
|
98 * @param Smarty $smarty Smarty instance |
|
99 * @param string $resource_name resource_name to make unique |
|
100 * @return string unique resource name |
|
101 */ |
|
102 protected function buildUniqueResourceName(Smarty $smarty, $resource_name) |
|
103 { |
|
104 return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name; |
|
105 } |
|
106 |
|
107 /** |
|
108 * populate Compiled Object with compiled filepath |
|
109 * |
|
110 * @param Smarty_Template_Compiled $compiled compiled object |
|
111 * @param Smarty_Internal_Template $_template template object |
|
112 */ |
|
113 public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) |
|
114 { |
|
115 $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null; |
|
116 $_filepath = $compiled->source->uid; |
|
117 // if use_sub_dirs, break file into directories |
|
118 if ($_template->smarty->use_sub_dirs) { |
|
119 $_filepath = substr($_filepath, 0, 2) . DS |
|
120 . substr($_filepath, 2, 2) . DS |
|
121 . substr($_filepath, 4, 2) . DS |
|
122 . $_filepath; |
|
123 } |
|
124 $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^'; |
|
125 if (isset($_compile_id)) { |
|
126 $_filepath = $_compile_id . $_compile_dir_sep . $_filepath; |
|
127 } |
|
128 // caching token |
|
129 if ($_template->caching) { |
|
130 $_cache = '.cache'; |
|
131 } else { |
|
132 $_cache = ''; |
|
133 } |
|
134 $_compile_dir = $_template->smarty->getCompileDir(); |
|
135 // set basename if not specified |
|
136 $_basename = $this->getBasename($compiled->source); |
|
137 if ($_basename === null) { |
|
138 $_basename = basename( preg_replace('![^\w\/]+!', '_', $compiled->source->name) ); |
|
139 } |
|
140 // separate (optional) basename by dot |
|
141 if ($_basename) { |
|
142 $_basename = '.' . $_basename; |
|
143 } |
|
144 |
|
145 $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php'; |
|
146 } |
|
147 |
|
148 /** |
|
149 * Normalize Paths "foo/../bar" to "bar" |
|
150 * |
|
151 * @param string $_path path to normalize |
|
152 * @param boolean $ds respect windows directory separator |
|
153 * @return string normalized path |
|
154 */ |
|
155 protected function normalizePath($_path, $ds=true) |
|
156 { |
|
157 if ($ds) { |
|
158 // don't we all just love windows? |
|
159 $_path = str_replace('\\', '/', $_path); |
|
160 } |
|
161 |
|
162 $offset = 0; |
|
163 |
|
164 // resolve simples |
|
165 $_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path); |
|
166 // resolve parents |
|
167 while (true) { |
|
168 $_parent = strpos($_path, '/../', $offset); |
|
169 if (!$_parent) { |
|
170 break; |
|
171 } else if ($_path[$_parent - 1] === '.') { |
|
172 $offset = $_parent + 3; |
|
173 continue; |
|
174 } |
|
175 |
|
176 $_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1); |
|
177 if ($_pos === false) { |
|
178 // don't we all just love windows? |
|
179 $_pos = $_parent; |
|
180 } |
|
181 |
|
182 $_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos); |
|
183 } |
|
184 |
|
185 if ($ds && DS != '/') { |
|
186 // don't we all just love windows? |
|
187 $_path = str_replace('/', '\\', $_path); |
|
188 } |
|
189 |
|
190 return $_path; |
|
191 } |
|
192 |
|
193 /** |
|
194 * build template filepath by traversing the template_dir array |
|
195 * |
|
196 * @param Smarty_Template_Source $source source object |
|
197 * @param Smarty_Internal_Template $_template template object |
|
198 * @return string fully qualified filepath |
|
199 * @throws SmartyException if default template handler is registered but not callable |
|
200 */ |
|
201 protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) |
|
202 { |
|
203 $file = $source->name; |
|
204 if ($source instanceof Smarty_Config_Source) { |
|
205 $_directories = $source->smarty->getConfigDir(); |
|
206 $_default_handler = $source->smarty->default_config_handler_func; |
|
207 } else { |
|
208 $_directories = $source->smarty->getTemplateDir(); |
|
209 $_default_handler = $source->smarty->default_template_handler_func; |
|
210 } |
|
211 |
|
212 // go relative to a given template? |
|
213 $_file_is_dotted = $file[0] == '.' && ($file[1] == '.' || $file[1] == '/' || $file[1] == "\\"); |
|
214 if ($_template && $_template->parent instanceof Smarty_Internal_Template && $_file_is_dotted) { |
|
215 if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) { |
|
216 throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'"); |
|
217 } |
|
218 $file = dirname($_template->parent->source->filepath) . DS . $file; |
|
219 $_file_exact_match = true; |
|
220 if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { |
|
221 // the path gained from the parent template is relative to the current working directory |
|
222 // as expansions (like include_path) have already been done |
|
223 $file = getcwd() . DS . $file; |
|
224 } |
|
225 } |
|
226 |
|
227 // resolve relative path |
|
228 if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { |
|
229 // don't we all just love windows? |
|
230 $_path = str_replace('\\', '/', $file); |
|
231 $_path = DS . trim($file, '/'); |
|
232 $_was_relative = true; |
|
233 } else { |
|
234 // don't we all just love windows? |
|
235 $_path = str_replace('\\', '/', $file); |
|
236 } |
|
237 $_path = $this->normalizePath($_path, false); |
|
238 if (DS != '/') { |
|
239 // don't we all just love windows? |
|
240 $_path = str_replace('/', '\\', $_path); |
|
241 } |
|
242 // revert to relative |
|
243 if (isset($_was_relative)) { |
|
244 $_path = substr($_path, 1); |
|
245 } |
|
246 |
|
247 // this is only required for directories |
|
248 $file = rtrim($_path, '/\\'); |
|
249 |
|
250 // files relative to a template only get one shot |
|
251 if (isset($_file_exact_match)) { |
|
252 return $this->fileExists($source, $file) ? $file : false; |
|
253 } |
|
254 |
|
255 // template_dir index? |
|
256 if (preg_match('#^\[(?P<key>[^\]]+)\](?P<file>.+)$#', $file, $match)) { |
|
257 $_directory = null; |
|
258 // try string indexes |
|
259 if (isset($_directories[$match['key']])) { |
|
260 $_directory = $_directories[$match['key']]; |
|
261 } else if (is_numeric($match['key'])) { |
|
262 // try numeric index |
|
263 $match['key'] = (int) $match['key']; |
|
264 if (isset($_directories[$match['key']])) { |
|
265 $_directory = $_directories[$match['key']]; |
|
266 } else { |
|
267 // try at location index |
|
268 $keys = array_keys($_directories); |
|
269 $_directory = $_directories[$keys[$match['key']]]; |
|
270 } |
|
271 } |
|
272 |
|
273 if ($_directory) { |
|
274 $_file = substr($file, strpos($file, ']') + 1); |
|
275 $_filepath = $_directory . $_file; |
|
276 if ($this->fileExists($source, $_filepath)) { |
|
277 return $_filepath; |
|
278 } |
|
279 } |
|
280 } |
|
281 |
|
282 $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); |
|
283 |
|
284 // relative file name? |
|
285 if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { |
|
286 foreach ($_directories as $_directory) { |
|
287 $_filepath = $_directory . $file; |
|
288 if ($this->fileExists($source, $_filepath)) { |
|
289 return $this->normalizePath($_filepath); |
|
290 } |
|
291 if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { |
|
292 // try PHP include_path |
|
293 if ($_stream_resolve_include_path) { |
|
294 $_filepath = stream_resolve_include_path($_filepath); |
|
295 } else { |
|
296 $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); |
|
297 } |
|
298 |
|
299 if ($_filepath !== false) { |
|
300 if ($this->fileExists($source, $_filepath)) { |
|
301 return $this->normalizePath($_filepath); |
|
302 } |
|
303 } |
|
304 } |
|
305 } |
|
306 } |
|
307 |
|
308 // try absolute filepath |
|
309 if ($this->fileExists($source, $file)) { |
|
310 return $file; |
|
311 } |
|
312 |
|
313 // no tpl file found |
|
314 if ($_default_handler) { |
|
315 if (!is_callable($_default_handler)) { |
|
316 if ($source instanceof Smarty_Config_Source) { |
|
317 throw new SmartyException("Default config handler not callable"); |
|
318 } else { |
|
319 throw new SmartyException("Default template handler not callable"); |
|
320 } |
|
321 } |
|
322 $_return = call_user_func_array($_default_handler, |
|
323 array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty)); |
|
324 if (is_string($_return)) { |
|
325 $source->timestamp = @filemtime($_return); |
|
326 $source->exists = !!$source->timestamp; |
|
327 return $_return; |
|
328 } elseif ($_return === true) { |
|
329 $source->content = $_content; |
|
330 $source->timestamp = $_timestamp; |
|
331 $source->exists = true; |
|
332 return $_filepath; |
|
333 } |
|
334 } |
|
335 |
|
336 // give up |
|
337 return false; |
|
338 } |
|
339 |
|
340 /** |
|
341 * test is file exists and save timestamp |
|
342 * |
|
343 * @param Smarty_Template_Source $source source object |
|
344 * @param string $file file name |
|
345 * @return bool true if file exists |
|
346 */ |
|
347 protected function fileExists(Smarty_Template_Source $source, $file) |
|
348 { |
|
349 $source->timestamp = @filemtime($file); |
|
350 return $source->exists = !!$source->timestamp; |
|
351 |
|
352 } |
|
353 |
|
354 /** |
|
355 * Determine basename for compiled filename |
|
356 * |
|
357 * @param Smarty_Template_Source $source source object |
|
358 * @return string resource's basename |
|
359 */ |
|
360 protected function getBasename(Smarty_Template_Source $source) |
|
361 { |
|
362 return null; |
|
363 } |
|
364 |
|
365 /** |
|
366 * Load Resource Handler |
|
367 * |
|
368 * @param Smarty $smarty smarty object |
|
369 * @param string $type name of the resource |
|
370 * @return Smarty_Resource Resource Handler |
|
371 */ |
|
372 public static function load(Smarty $smarty, $type) |
|
373 { |
|
374 // try smarty's cache |
|
375 if (isset($smarty->_resource_handlers[$type])) { |
|
376 return $smarty->_resource_handlers[$type]; |
|
377 } |
|
378 |
|
379 // try registered resource |
|
380 if (isset($smarty->registered_resources[$type])) { |
|
381 if ($smarty->registered_resources[$type] instanceof Smarty_Resource) { |
|
382 $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type]; |
|
383 // note registered to smarty is not kept unique! |
|
384 return $smarty->_resource_handlers[$type]; |
|
385 } |
|
386 |
|
387 if (!isset(self::$resources['registered'])) { |
|
388 self::$resources['registered'] = new Smarty_Internal_Resource_Registered(); |
|
389 } |
|
390 if (!isset($smarty->_resource_handlers[$type])) { |
|
391 $smarty->_resource_handlers[$type] = self::$resources['registered']; |
|
392 } |
|
393 |
|
394 return $smarty->_resource_handlers[$type]; |
|
395 } |
|
396 |
|
397 // try sysplugins dir |
|
398 if (isset(self::$sysplugins[$type])) { |
|
399 if (!isset(self::$resources[$type])) { |
|
400 $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); |
|
401 self::$resources[$type] = new $_resource_class(); |
|
402 } |
|
403 return $smarty->_resource_handlers[$type] = self::$resources[$type]; |
|
404 } |
|
405 |
|
406 // try plugins dir |
|
407 $_resource_class = 'Smarty_Resource_' . ucfirst($type); |
|
408 if ($smarty->loadPlugin($_resource_class)) { |
|
409 if (isset(self::$resources[$type])) { |
|
410 return $smarty->_resource_handlers[$type] = self::$resources[$type]; |
|
411 } |
|
412 |
|
413 if (class_exists($_resource_class, false)) { |
|
414 self::$resources[$type] = new $_resource_class(); |
|
415 return $smarty->_resource_handlers[$type] = self::$resources[$type]; |
|
416 } else { |
|
417 $smarty->registerResource($type, array( |
|
418 "smarty_resource_{$type}_source", |
|
419 "smarty_resource_{$type}_timestamp", |
|
420 "smarty_resource_{$type}_secure", |
|
421 "smarty_resource_{$type}_trusted" |
|
422 )); |
|
423 |
|
424 // give it another try, now that the resource is registered properly |
|
425 return self::load($smarty, $type); |
|
426 } |
|
427 } |
|
428 |
|
429 // try streams |
|
430 $_known_stream = stream_get_wrappers(); |
|
431 if (in_array($type, $_known_stream)) { |
|
432 // is known stream |
|
433 if (is_object($smarty->security_policy)) { |
|
434 $smarty->security_policy->isTrustedStream($type); |
|
435 } |
|
436 if (!isset(self::$resources['stream'])) { |
|
437 self::$resources['stream'] = new Smarty_Internal_Resource_Stream(); |
|
438 } |
|
439 return $smarty->_resource_handlers[$type] = self::$resources['stream']; |
|
440 } |
|
441 |
|
442 // TODO: try default_(template|config)_handler |
|
443 |
|
444 // give up |
|
445 throw new SmartyException("Unkown resource type '{$type}'"); |
|
446 } |
|
447 |
|
448 /** |
|
449 * extract resource_type and resource_name from template_resource and config_resource |
|
450 * |
|
451 * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). |
|
452 * @param string $resource_name template_resource or config_resource to parse |
|
453 * @param string $default_resource the default resource_type defined in $smarty |
|
454 * @param string &$name the parsed resource name |
|
455 * @param string &$type the parsed resource type |
|
456 * @return void |
|
457 */ |
|
458 protected static function parseResourceName($resource_name, $default_resource, &$name, &$type) |
|
459 { |
|
460 $parts = explode(':', $resource_name, 2); |
|
461 if (!isset($parts[1]) || !isset($parts[0][1])) { |
|
462 // no resource given, use default |
|
463 // or single character before the colon is not a resource type, but part of the filepath |
|
464 $type = $default_resource; |
|
465 $name = $resource_name; |
|
466 } else { |
|
467 $type = $parts[0]; |
|
468 $name = $parts[1]; |
|
469 } |
|
470 } |
|
471 |
|
472 |
|
473 /** |
|
474 * modify resource_name according to resource handlers specifications |
|
475 * |
|
476 * @param Smarty $smarty Smarty instance |
|
477 * @param string $resource_name resource_name to make unique |
|
478 * @return string unique resource name |
|
479 */ |
|
480 |
|
481 /** |
|
482 * modify template_resource according to resource handlers specifications |
|
483 * |
|
484 * @param string $smarty Smarty instance |
|
485 * @param string $template_resource template_resource to extracate resource handler and name of |
|
486 * @return string unique resource name |
|
487 */ |
|
488 public static function getUniqueTemplateName($smarty, $template_resource) |
|
489 { |
|
490 self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); |
|
491 // TODO: optimize for Smarty's internal resource types |
|
492 $resource = Smarty_Resource::load($smarty, $type); |
|
493 return $resource->buildUniqueResourceName($smarty, $name); |
|
494 } |
|
495 |
|
496 /** |
|
497 * initialize Source Object for given resource |
|
498 * |
|
499 * Either [$_template] or [$smarty, $template_resource] must be specified |
|
500 * |
|
501 * @param Smarty_Internal_Template $_template template object |
|
502 * @param Smarty $smarty smarty object |
|
503 * @param string $template_resource resource identifier |
|
504 * @return Smarty_Template_Source Source Object |
|
505 */ |
|
506 public static function source(Smarty_Internal_Template $_template=null, Smarty $smarty=null, $template_resource=null) |
|
507 { |
|
508 if ($_template) { |
|
509 $smarty = $_template->smarty; |
|
510 $template_resource = $_template->template_resource; |
|
511 } |
|
512 |
|
513 // parse resource_name, load resource handler, identify unique resource name |
|
514 self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); |
|
515 $resource = Smarty_Resource::load($smarty, $type); |
|
516 $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name); |
|
517 |
|
518 // check runtime cache |
|
519 $_cache_key = 'template|' . $unique_resource_name; |
|
520 if ($smarty->compile_id) { |
|
521 $_cache_key .= '|'.$smarty->compile_id; |
|
522 } |
|
523 if (isset(self::$sources[$_cache_key])) { |
|
524 return self::$sources[$_cache_key]; |
|
525 } |
|
526 |
|
527 // create source |
|
528 $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name, $unique_resource_name); |
|
529 $resource->populate($source, $_template); |
|
530 |
|
531 // runtime cache |
|
532 self::$sources[$_cache_key] = $source; |
|
533 return $source; |
|
534 } |
|
535 |
|
536 /** |
|
537 * initialize Config Source Object for given resource |
|
538 * |
|
539 * @param Smarty_Internal_Config $_config config object |
|
540 * @return Smarty_Config_Source Source Object |
|
541 */ |
|
542 public static function config(Smarty_Internal_Config $_config) |
|
543 { |
|
544 static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); |
|
545 $config_resource = $_config->config_resource; |
|
546 $smarty = $_config->smarty; |
|
547 |
|
548 // parse resource_name |
|
549 self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type); |
|
550 |
|
551 // make sure configs are not loaded via anything smarty can't handle |
|
552 if (isset($_incompatible_resources[$type])) { |
|
553 throw new SmartyException ("Unable to use resource '{$type}' for config"); |
|
554 } |
|
555 |
|
556 // load resource handler, identify unique resource name |
|
557 $resource = Smarty_Resource::load($smarty, $type); |
|
558 $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name); |
|
559 |
|
560 // check runtime cache |
|
561 $_cache_key = 'config|' . $unique_resource_name; |
|
562 if (isset(self::$sources[$_cache_key])) { |
|
563 return self::$sources[$_cache_key]; |
|
564 } |
|
565 |
|
566 // create source |
|
567 $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name); |
|
568 $resource->populate($source, null); |
|
569 |
|
570 // runtime cache |
|
571 self::$sources[$_cache_key] = $source; |
|
572 return $source; |
|
573 } |
|
574 |
|
575 } |
|
576 |
|
577 /** |
|
578 * Smarty Resource Data Object |
|
579 * |
|
580 * Meta Data Container for Template Files |
|
581 * |
|
582 * @package Smarty |
|
583 * @subpackage TemplateResources |
|
584 * @author Rodney Rehm |
|
585 * |
|
586 * @property integer $timestamp Source Timestamp |
|
587 * @property boolean $exists Source Existance |
|
588 * @property boolean $template Extended Template reference |
|
589 * @property string $content Source Content |
|
590 */ |
|
591 class Smarty_Template_Source { |
|
592 |
|
593 /** |
|
594 * Name of the Class to compile this resource's contents with |
|
595 * @var string |
|
596 */ |
|
597 public $compiler_class = null; |
|
598 |
|
599 /** |
|
600 * Name of the Class to tokenize this resource's contents with |
|
601 * @var string |
|
602 */ |
|
603 public $template_lexer_class = null; |
|
604 |
|
605 /** |
|
606 * Name of the Class to parse this resource's contents with |
|
607 * @var string |
|
608 */ |
|
609 public $template_parser_class = null; |
|
610 |
|
611 /** |
|
612 * Unique Template ID |
|
613 * @var string |
|
614 */ |
|
615 public $uid = null; |
|
616 |
|
617 /** |
|
618 * Template Resource (Smarty_Internal_Template::$template_resource) |
|
619 * @var string |
|
620 */ |
|
621 public $resource = null; |
|
622 |
|
623 /** |
|
624 * Resource Type |
|
625 * @var string |
|
626 */ |
|
627 public $type = null; |
|
628 |
|
629 /** |
|
630 * Resource Name |
|
631 * @var string |
|
632 */ |
|
633 public $name = null; |
|
634 |
|
635 /** |
|
636 * Unique Resource Name |
|
637 * @var string |
|
638 */ |
|
639 public $unique_resource = null; |
|
640 |
|
641 /** |
|
642 * Source Filepath |
|
643 * @var string |
|
644 */ |
|
645 public $filepath = null; |
|
646 |
|
647 /** |
|
648 * Source is bypassing compiler |
|
649 * @var boolean |
|
650 */ |
|
651 public $uncompiled = null; |
|
652 |
|
653 /** |
|
654 * Source must be recompiled on every occasion |
|
655 * @var boolean |
|
656 */ |
|
657 public $recompiled = null; |
|
658 |
|
659 /** |
|
660 * The Components an extended template is made of |
|
661 * @var array |
|
662 */ |
|
663 public $components = null; |
|
664 |
|
665 /** |
|
666 * Resource Handler |
|
667 * @var Smarty_Resource |
|
668 */ |
|
669 public $handler = null; |
|
670 |
|
671 /** |
|
672 * Smarty instance |
|
673 * @var Smarty |
|
674 */ |
|
675 public $smarty = null; |
|
676 |
|
677 /** |
|
678 * create Source Object container |
|
679 * |
|
680 * @param Smarty_Resource $handler Resource Handler this source object communicates with |
|
681 * @param Smarty $smarty Smarty instance this source object belongs to |
|
682 * @param string $resource full template_resource |
|
683 * @param string $type type of resource |
|
684 * @param string $name resource name |
|
685 * @param string $unique_resource unqiue resource name |
|
686 */ |
|
687 public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource) |
|
688 { |
|
689 $this->handler = $handler; // Note: prone to circular references |
|
690 |
|
691 $this->compiler_class = $handler->compiler_class; |
|
692 $this->template_lexer_class = $handler->template_lexer_class; |
|
693 $this->template_parser_class = $handler->template_parser_class; |
|
694 $this->uncompiled = $this->handler instanceof Smarty_Resource_Uncompiled; |
|
695 $this->recompiled = $this->handler instanceof Smarty_Resource_Recompiled; |
|
696 |
|
697 $this->smarty = $smarty; |
|
698 $this->resource = $resource; |
|
699 $this->type = $type; |
|
700 $this->name = $name; |
|
701 $this->unique_resource = $unique_resource; |
|
702 } |
|
703 |
|
704 /** |
|
705 * get a Compiled Object of this source |
|
706 * |
|
707 * @param Smarty_Internal_Template $_template template objet |
|
708 * @return Smarty_Template_Compiled compiled object |
|
709 */ |
|
710 public function getCompiled(Smarty_Internal_Template $_template) |
|
711 { |
|
712 // check runtime cache |
|
713 $_cache_key = $this->unique_resource . '#' . $_template->compile_id; |
|
714 if (isset(Smarty_Resource::$compileds[$_cache_key])) { |
|
715 return Smarty_Resource::$compileds[$_cache_key]; |
|
716 } |
|
717 |
|
718 $compiled = new Smarty_Template_Compiled($this); |
|
719 $this->handler->populateCompiledFilepath($compiled, $_template); |
|
720 $compiled->timestamp = @filemtime($compiled->filepath); |
|
721 $compiled->exists = !!$compiled->timestamp; |
|
722 |
|
723 // runtime cache |
|
724 Smarty_Resource::$compileds[$_cache_key] = $compiled; |
|
725 |
|
726 return $compiled; |
|
727 } |
|
728 |
|
729 /** |
|
730 * render the uncompiled source |
|
731 * |
|
732 * @param Smarty_Internal_Template $_template template object |
|
733 */ |
|
734 public function renderUncompiled(Smarty_Internal_Template $_template) |
|
735 { |
|
736 return $this->handler->renderUncompiled($this, $_template); |
|
737 } |
|
738 |
|
739 /** |
|
740 * <<magic>> Generic Setter. |
|
741 * |
|
742 * @param string $property_name valid: timestamp, exists, content, template |
|
743 * @param mixed $value new value (is not checked) |
|
744 * @throws SmartyException if $property_name is not valid |
|
745 */ |
|
746 public function __set($property_name, $value) |
|
747 { |
|
748 switch ($property_name) { |
|
749 // regular attributes |
|
750 case 'timestamp': |
|
751 case 'exists': |
|
752 case 'content': |
|
753 // required for extends: only |
|
754 case 'template': |
|
755 $this->$property_name = $value; |
|
756 break; |
|
757 |
|
758 default: |
|
759 throw new SmartyException("invalid source property '$property_name'."); |
|
760 } |
|
761 } |
|
762 |
|
763 /** |
|
764 * <<magic>> Generic getter. |
|
765 * |
|
766 * @param string $property_name valid: timestamp, exists, content |
|
767 * @return mixed |
|
768 * @throws SmartyException if $property_name is not valid |
|
769 */ |
|
770 public function __get($property_name) |
|
771 { |
|
772 switch ($property_name) { |
|
773 case 'timestamp': |
|
774 case 'exists': |
|
775 $this->handler->populateTimestamp($this); |
|
776 return $this->$property_name; |
|
777 |
|
778 case 'content': |
|
779 return $this->content = $this->handler->getContent($this); |
|
780 |
|
781 default: |
|
782 throw new SmartyException("source property '$property_name' does not exist."); |
|
783 } |
|
784 } |
|
785 |
|
786 } |
|
787 |
|
788 /** |
|
789 * Smarty Resource Data Object |
|
790 * |
|
791 * Meta Data Container for Template Files |
|
792 * |
|
793 * @package Smarty |
|
794 * @subpackage TemplateResources |
|
795 * @author Rodney Rehm |
|
796 * |
|
797 * @property string $content compiled content |
|
798 */ |
|
799 class Smarty_Template_Compiled { |
|
800 |
|
801 /** |
|
802 * Compiled Filepath |
|
803 * @var string |
|
804 */ |
|
805 public $filepath = null; |
|
806 |
|
807 /** |
|
808 * Compiled Timestamp |
|
809 * @var integer |
|
810 */ |
|
811 public $timestamp = null; |
|
812 |
|
813 /** |
|
814 * Compiled Existance |
|
815 * @var boolean |
|
816 */ |
|
817 public $exists = false; |
|
818 |
|
819 /** |
|
820 * Compiled Content Loaded |
|
821 * @var boolean |
|
822 */ |
|
823 public $loaded = false; |
|
824 |
|
825 /** |
|
826 * Template was compiled |
|
827 * @var boolean |
|
828 */ |
|
829 public $isCompiled = false; |
|
830 |
|
831 /** |
|
832 * Source Object |
|
833 * @var Smarty_Template_Source |
|
834 */ |
|
835 public $source = null; |
|
836 |
|
837 /** |
|
838 * Metadata properties |
|
839 * |
|
840 * populated by Smarty_Internal_Template::decodeProperties() |
|
841 * @var array |
|
842 */ |
|
843 public $_properties = null; |
|
844 |
|
845 /** |
|
846 * create Compiled Object container |
|
847 * |
|
848 * @param Smarty_Template_Source $source source object this compiled object belongs to |
|
849 */ |
|
850 public function __construct(Smarty_Template_Source $source) |
|
851 { |
|
852 $this->source = $source; |
|
853 } |
|
854 |
|
855 } |
|
856 |
|
857 ?> |