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