1 : <?php
2 :
3 : if (!defined('DIR_SEP')) {
4 : define('DIR_SEP', DIRECTORY_SEPARATOR);
5 : }
6 :
7 : if (!defined('SMARTY_PHP_PASSTHRU')) {
8 : define('SMARTY_PHP_PASSTHRU', 0);
9 : define('SMARTY_PHP_QUOTE', 1);
10 : define('SMARTY_PHP_REMOVE', 2);
11 : define('SMARTY_PHP_ALLOW', 3);
12 : }
13 :
14 : if (class_exists('Dwoo_Compiler', false) === false) {
15 : require dirname(dirname(__FILE__)) . '/Compiler.php';
16 : }
17 :
18 : /**
19 : * a Smarty compatibility layer for Dwoo
20 : *
21 : * This software is provided 'as-is', without any express or implied warranty.
22 : * In no event will the authors be held liable for any damages arising from the use of this software.
23 : *
24 : * @author Jordi Boggiano <j.boggiano@seld.be>
25 : * @copyright Copyright (c) 2008, Jordi Boggiano
26 : * @license http://dwoo.org/LICENSE Modified BSD License
27 : * @link http://dwoo.org/
28 : * @version 1.1.0
29 : * @date 2009-07-18
30 : * @package Dwoo
31 : */
32 : class Dwoo_Smarty__Adapter extends Dwoo
33 : {
34 : // magic get/set/call functions that handle unsupported features
35 : public function __set($p, $v)
36 : {
37 0 : if ($p==='scope') {
38 0 : $this->scope = $v;
39 0 : return;
40 : }
41 0 : if ($p==='data') {
42 0 : $this->data = $v;
43 0 : return;
44 : }
45 0 : if (array_key_exists($p, $this->compat['properties']) !== false) {
46 0 : if ($this->show_compat_errors) {
47 0 : $this->triggerError('Property '.$p.' is not available in the Dwoo_Smarty_Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
48 0 : }
49 0 : $this->compat['properties'][$p] = $v;
50 0 : } else {
51 0 : if ($this->show_compat_errors) {
52 0 : $this->triggerError('Property '.$p.' is not available in the Dwoo_Smarty_Adapter, but it is not listed as such, so you might want to tell me about it at j.boggiano@seld.be', E_USER_NOTICE);
53 0 : }
54 : }
55 0 : }
56 :
57 : public function __get($p)
58 : {
59 0 : if (array_key_exists($p, $this->compat['properties']) !== false) {
60 0 : if ($this->show_compat_errors) {
61 0 : $this->triggerError('Property '.$p.' is not available in the Dwoo_Smarty_Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
62 0 : }
63 0 : return $this->compat['properties'][$p];
64 : } else {
65 0 : if ($this->show_compat_errors) {
66 0 : $this->triggerError('Property '.$p.' is not available in the Dwoo_Smarty_Adapter, but it is not listed as such, so you might want to tell me about it at j.boggiano@seld.be', E_USER_NOTICE);
67 0 : }
68 : }
69 0 : }
70 :
71 : public function __call($m, $a)
72 : {
73 1 : if (method_exists($this->dataProvider, $m)) {
74 1 : call_user_func_array(array($this->dataProvider, $m), $a);
75 1 : } elseif ($this->show_compat_errors) {
76 0 : if (array_search($m, $this->compat['methods']) !== false) {
77 0 : $this->triggerError('Method '.$m.' is not available in the Dwoo_Smarty_Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
78 0 : } else {
79 0 : $this->triggerError('Method '.$m.' is not available in the Dwoo_Smarty_Adapter, but it is not listed as such, so you might want to tell me about it at j.boggiano@seld.be', E_USER_NOTICE);
80 : }
81 0 : }
82 1 : }
83 :
84 : // list of unsupported properties and methods
85 : protected $compat = array
86 : (
87 : 'methods' => array
88 : (
89 : 'register_resource', 'unregister_resource', 'load_filter', 'clear_compiled_tpl',
90 : 'clear_config', 'get_config_vars', 'config_load'
91 : ),
92 : 'properties' => array
93 : (
94 : 'cache_handler_func' => null,
95 : 'debugging' => false,
96 : 'error_reporting' => null,
97 : 'debugging_ctrl' => 'NONE',
98 : 'request_vars_order' => 'EGPCS',
99 : 'request_use_auto_globals' => true,
100 : 'use_sub_dirs' => false,
101 : 'autoload_filters' => array(),
102 : 'default_template_handler_func' => '',
103 : 'debug_tpl' => '',
104 : 'cache_modified_check' => false,
105 : 'default_modifiers' => array(),
106 : 'default_resource_type' => 'file',
107 : 'config_overwrite' => true,
108 : 'config_booleanize' => true,
109 : 'config_read_hidden' => false,
110 : 'config_fix_newlines' => true,
111 : 'config_class' => 'Config_File',
112 : ),
113 : );
114 :
115 : // security vars
116 : public $security = false;
117 : public $trusted_dir = array();
118 : public $secure_dir = array();
119 : public $php_handling = SMARTY_PHP_PASSTHRU;
120 : public $security_settings = array
121 : (
122 : 'PHP_HANDLING' => false,
123 : 'IF_FUNCS' => array
124 : (
125 : 'list', 'empty', 'count', 'sizeof',
126 : 'in_array', 'is_array',
127 : ),
128 : 'INCLUDE_ANY' => false,
129 : 'PHP_TAGS' => false,
130 : 'MODIFIER_FUNCS' => array(),
131 : 'ALLOW_CONSTANTS' => false
132 : );
133 :
134 : // paths
135 : public $template_dir = 'templates';
136 : public $compile_dir = 'templates_c';
137 : public $config_dir = 'configs';
138 : public $cache_dir = 'cache';
139 : public $plugins_dir = array();
140 :
141 : // misc options
142 : public $left_delimiter = '{';
143 : public $right_delimiter = '}';
144 : public $compile_check = true;
145 : public $force_compile = false;
146 : public $caching = 0;
147 : public $cache_lifetime = 3600;
148 : public $compile_id = null;
149 : public $compiler_file = null;
150 : public $compiler_class = null;
151 :
152 : // dwoo/smarty compat layer
153 : public $show_compat_errors = false;
154 : protected $dataProvider;
155 : protected $_filters = array('pre'=>array(), 'post'=>array(), 'output'=>array());
156 : protected static $tplCache = array();
157 : protected $compiler = null;
158 :
159 : public function __construct()
160 : {
161 0 : parent::__construct();
162 0 : $this->charset = 'iso-8859-1';
163 0 : $this->dataProvider = new Dwoo_Data();
164 0 : $this->compiler = new Dwoo_Compiler();
165 0 : }
166 :
167 : public function display($filename, $cacheId=null, $compileId=null)
168 : {
169 0 : $this->fetch($filename, $cacheId, $compileId, true);
170 0 : }
171 :
172 : public function fetch($filename, $cacheId=null, $compileId=null, $display=false)
173 : {
174 1 : $this->setCacheDir($this->cache_dir);
175 1 : $this->setCompileDir($this->compile_dir);
176 :
177 1 : if ($this->security) {
178 0 : $policy = new Dwoo_Security_Policy();
179 0 : $policy->addPhpFunction(array_merge($this->security_settings['IF_FUNCS'], $this->security_settings['MODIFIER_FUNCS']));
180 :
181 0 : $phpTags = $this->security_settings['PHP_HANDLING'] ? SMARTY_PHP_ALLOW : $this->php_handling;
182 0 : if ($this->security_settings['PHP_TAGS']) {
183 0 : $phpTags = SMARTY_PHP_ALLOW;
184 0 : }
185 : switch($phpTags) {
186 0 : case SMARTY_PHP_ALLOW:
187 0 : case SMARTY_PHP_PASSTHRU:
188 0 : $phpTags = Dwoo_Security_Policy::PHP_ALLOW;
189 0 : break;
190 0 : case SMARTY_PHP_QUOTE:
191 0 : $phpTags = Dwoo_Security_Policy::PHP_ENCODE;
192 0 : break;
193 0 : case SMARTY_PHP_REMOVE:
194 0 : default:
195 0 : $phpTags = Dwoo_Security_Policy::PHP_REMOVE;
196 0 : break;
197 0 : }
198 0 : $policy->setPhpHandling($phpTags);
199 :
200 0 : $policy->setConstantHandling($this->security_settings['ALLOW_CONSTANTS']);
201 :
202 0 : if ($this->security_settings['INCLUDE_ANY']) {
203 0 : $policy->allowDirectory(preg_replace('{^((?:[a-z]:)?[\\\\/]).*}i', '$1', __FILE__));
204 0 : } else {
205 0 : $policy->allowDirectory($this->secure_dir);
206 : }
207 :
208 0 : $this->setSecurityPolicy($policy);
209 0 : }
210 :
211 1 : if (!empty($this->plugins_dir)) {
212 0 : foreach ($this->plugins_dir as $dir) {
213 0 : $this->getLoader()->addDirectory(rtrim($dir, '\\/'));
214 0 : }
215 0 : }
216 :
217 1 : $tpl = $this->makeTemplate($filename, $cacheId, $compileId);
218 1 : if ($this->force_compile) {
219 0 : $tpl->forceCompilation();
220 0 : }
221 :
222 1 : if ($this->caching > 0) {
223 0 : $this->cacheTime = $this->cache_lifetime;
224 0 : } else {
225 1 : $this->cacheTime = 0;
226 : }
227 :
228 1 : if ($this->compiler_class !== null) {
229 0 : if ($this->compiler_file !== null && !class_exists($this->compiler_class, false)) {
230 0 : include $this->compiler_file;
231 0 : }
232 0 : $this->compiler = new $this->compiler_class;
233 0 : } else {
234 1 : $this->compiler->addPreProcessor('smarty_compat', true);
235 1 : $this->compiler->setLooseOpeningHandling(true);
236 : }
237 :
238 1 : $this->compiler->setDelimiters($this->left_delimiter, $this->right_delimiter);
239 :
240 1 : return $this->get($tpl, $this->dataProvider, $this->compiler, $display===true);
241 : }
242 :
243 : public function get($_tpl, $data = array(), $_compiler = null, $_output = false)
244 : {
245 1 : if ($_compiler === null) {
246 0 : $_compiler = $this->compiler;
247 0 : }
248 1 : return parent::get($_tpl, $data, $_compiler, $_output);
249 : }
250 :
251 : public function register_function($name, $callback, $cacheable=true, $cache_attrs=null)
252 : {
253 0 : if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_FUNCTION) {
254 0 : throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
255 : }
256 0 : $this->plugins[$name] = array('type'=>self::SMARTY_FUNCTION, 'callback'=>$callback);
257 0 : }
258 :
259 : public function unregister_function($name)
260 : {
261 0 : unset($this->plugins[$name]);
262 0 : }
263 :
264 : public function register_block($name, $callback, $cacheable=true, $cache_attrs=null)
265 : {
266 0 : if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_BLOCK) {
267 0 : throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
268 : }
269 0 : $this->plugins[$name] = array('type'=>self::SMARTY_BLOCK, 'callback'=>$callback);
270 0 : }
271 :
272 : public function unregister_block($name)
273 : {
274 0 : unset($this->plugins[$name]);
275 0 : }
276 :
277 : public function register_modifier($name, $callback)
278 : {
279 0 : if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_MODIFIER) {
280 0 : throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
281 : }
282 0 : $this->plugins[$name] = array('type'=>self::SMARTY_MODIFIER, 'callback'=>$callback);
283 0 : }
284 :
285 : public function unregister_modifier($name)
286 : {
287 0 : unset($this->plugins[$name]);
288 0 : }
289 :
290 : public function register_prefilter($callback)
291 : {
292 0 : $processor = new Dwoo_SmartyProcessorAdapter($this->compiler);
293 0 : $processor->registerCallback($callback);
294 0 : $this->_filters['pre'][] = $processor;
295 0 : $this->compiler->addPreProcessor($processor);
296 0 : }
297 :
298 : public function unregister_prefilter($callback)
299 : {
300 0 : foreach ($this->_filters['pre'] as $index => $processor)
301 0 : if ($processor->callback === $callback) {
302 0 : $this->compiler->removePostProcessor($processor);
303 0 : unset($this->_filters['pre'][$index]);
304 0 : }
305 0 : }
306 :
307 : public function register_postfilter($callback)
308 : {
309 0 : $processor = new Dwoo_SmartyProcessorAdapter($this->compiler);
310 0 : $processor->registerCallback($callback);
311 0 : $this->_filters['post'][] = $processor;
312 0 : $this->compiler->addPostProcessor($processor);
313 0 : }
314 :
315 : public function unregister_postfilter($callback)
316 : {
317 0 : foreach ($this->_filters['post'] as $index => $processor)
318 0 : if ($processor->callback === $callback) {
319 0 : $this->compiler->removePostProcessor($processor);
320 0 : unset($this->_filters['post'][$index]);
321 0 : }
322 0 : }
323 :
324 : public function register_outputfilter($callback)
325 : {
326 0 : $filter = new Dwoo_SmartyFilterAdapter($this);
327 0 : $filter->registerCallback($callback);
328 0 : $this->_filters['output'][] = $filter;
329 0 : $this->addFilter($filter);
330 0 : }
331 :
332 : public function unregister_outputfilter($callback)
333 : {
334 0 : foreach ($this->_filters['output'] as $index => $filter)
335 0 : if ($filter->callback === $callback) {
336 0 : $this->removeOutputFilter($filter);
337 0 : unset($this->_filters['output'][$index]);
338 0 : }
339 0 : }
340 :
341 : function register_object($object, $object_impl, $allowed = array(), $smarty_args = false, $block_methods = array())
342 : {
343 0 : settype($allowed, 'array');
344 0 : settype($block_methods, 'array');
345 0 : settype($smarty_args, 'boolean');
346 :
347 0 : if (!empty($allowed) && $this->show_compat_errors) {
348 0 : $this->triggerError('You can register objects but can not restrict the method/properties used, this is PHP5, you have proper OOP access restrictions so use them.', E_USER_NOTICE);
349 0 : }
350 :
351 0 : if ($smarty_args) {
352 0 : $this->triggerError('You can register objects but methods will be called using method($arg1, $arg2, $arg3), not as an argument array like smarty did.', E_USER_NOTICE);
353 0 : }
354 :
355 0 : if (!empty($block_methods)) {
356 0 : $this->triggerError('You can register objects but can not use methods as being block methods, you have to build a plugin for that.', E_USER_NOTICE);
357 0 : }
358 :
359 0 : $this->dataProvider->assign($object, $object_impl);
360 0 : }
361 :
362 : function unregister_object($object)
363 : {
364 0 : $this->dataProvider->clear($object);
365 0 : }
366 :
367 : function get_registered_object($name) {
368 0 : $data = $this->dataProvider->getData();
369 0 : if (isset($data[$name]) && is_object($data[$name])) {
370 0 : return $data[$name];
371 : } else {
372 0 : trigger_error('Dwoo_Compiler: object "'.$name.'" was not registered or is not an object', E_USER_ERROR);
373 : }
374 0 : }
375 :
376 : public function template_exists($filename)
377 : {
378 0 : if (!is_array($this->template_dir)) {
379 0 : return file_exists($this->template_dir.DIRECTORY_SEPARATOR.$filename);
380 : } else {
381 0 : foreach ($this->template_dir as $tpl_dir) {
382 0 : if (file_exists($tpl_dir.DIRECTORY_SEPARATOR.$filename)) {
383 0 : return true;
384 : }
385 0 : }
386 0 : return false;
387 : }
388 : }
389 :
390 : public function is_cached($tpl, $cacheId = null, $compileId = null)
391 : {
392 0 : return $this->isCached($this->makeTemplate($tpl, $cacheId, $compileId));
393 : }
394 :
395 : public function append_by_ref($var, &$value, $merge=false)
396 : {
397 0 : $this->dataProvider->appendByRef($var, $value, $merge);
398 0 : }
399 :
400 : public function assign_by_ref($name, &$val)
401 : {
402 0 : $this->dataProvider->assignByRef($name, $val);
403 0 : }
404 :
405 : public function clear_assign($var)
406 : {
407 0 : $this->dataProvider->clear($var);
408 0 : }
409 :
410 : public function clear_all_assign()
411 : {
412 0 : $this->dataProvider->clear();
413 0 : }
414 :
415 : public function get_template_vars($name=null)
416 : {
417 0 : if ($this->show_compat_errors) {
418 0 : trigger_error('get_template_vars does not return values by reference, if you try to modify the data that way you should modify your code.', E_USER_NOTICE);
419 0 : }
420 :
421 0 : $data = $this->dataProvider->getData();
422 0 : if ($name === null)
423 0 : return $data;
424 0 : elseif (isset($data[$name]))
425 0 : return $data[$name];
426 0 : return null;
427 : }
428 :
429 : public function clear_all_cache($olderThan = 0)
430 : {
431 0 : $this->clearCache($olderThan);
432 0 : }
433 :
434 : public function clear_cache($template, $cacheId = null, $compileId = null, $olderThan = 0)
435 : {
436 0 : $this->makeTemplate($template, $cacheId, $compileId)->clearCache($olderThan);
437 0 : }
438 :
439 : public function trigger_error($error_msg, $error_type = E_USER_WARNING)
440 : {
441 0 : $this->triggerError($error_msg, $error_type);
442 0 : }
443 :
444 : protected function initGlobals()
445 : {
446 0 : parent::initGlobals();
447 0 : $this->globals['ldelim'] = '{';
448 0 : $this->globals['rdelim'] = '}';
449 0 : }
450 :
451 : protected function makeTemplate($file, $cacheId, $compileId)
452 : {
453 1 : if ($compileId === null)
454 1 : $compileId = $this->compile_id;
455 :
456 1 : $hash = bin2hex(md5($file.$cacheId.$compileId, true));
457 1 : if (!isset(self::$tplCache[$hash])) {
458 : // abs path
459 1 : if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
460 0 : self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId);
461 1 : } elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
462 1 : self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId, $this->template_dir);
463 1 : } else {
464 0 : throw new Exception('Unable to load "'.$file.'", check the template_dir');
465 : }
466 1 : }
467 1 : return self::$tplCache[$hash];
468 : }
469 :
470 : public function triggerError($message, $level=E_USER_NOTICE)
471 : {
472 0 : if (is_object($this->template)) {
473 0 : return parent::triggerError($message, $level);
474 : }
475 0 : trigger_error('Dwoo error : '.$message, $level);
476 0 : }
477 : }
478 :
479 : class Dwoo_Smarty_Filter_Adapter extends Dwoo_Filter
480 : {
481 : public $callback;
482 :
483 : public function process($input)
484 : {
485 0 : return call_user_func($this->callback, $input);
486 : }
487 :
488 : public function registerCallback($callback)
489 : {
490 0 : $this->callback = $callback;
491 0 : }
492 : }
493 :
494 : class Dwoo_Smarty_Processor_Adapter extends Dwoo_Processor
495 : {
496 : public $callback;
497 :
498 : public function process($input)
499 : {
500 0 : return call_user_func($this->callback, $input);
501 : }
502 :
503 : public function registerCallback($callback)
504 : {
505 0 : $this->callback = $callback;
506 0 : }
507 : }
508 :
509 : // cloaks the adapter if possible with the smarty name to fool type-hinted plugins
510 : if (class_exists('Smarty', false) === false)
511 : {
512 : interface Smarty {}
513 : class Dwoo_Smarty_Adapter extends Dwoo_Smarty__Adapter implements Smarty {}
514 : }
515 : else
516 : {
517 : class Dwoo_Smarty_Adapter extends Dwoo_Smarty__Adapter {}
518 : }
|