source: branches/0.4/web/addons/job_monarch/dwoo/Dwoo/Smarty/Adapter.php @ 755

Last change on this file since 755 was 755, checked in by ramonb, 11 years ago
  • add Dwoo
File size: 15.2 KB
Line 
1<?php
2
3if (!defined('DIR_SEP')) {
4        define('DIR_SEP', DIRECTORY_SEPARATOR);
5}
6
7if (!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
14if (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 */
32class Dwoo_Smarty__Adapter extends Dwoo_Core
33{
34        // magic get/set/call functions that handle unsupported features
35        public function __set($p, $v)
36        {
37                if ($p==='scope') {
38                        $this->scope = $v;
39                        return;
40                }
41                if ($p==='data') {
42                        $this->data = $v;
43                        return;
44                }
45                if (array_key_exists($p, $this->compat['properties']) !== false) {
46                        if ($this->show_compat_errors) {
47                                $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                        }
49                        $this->compat['properties'][$p] = $v;
50                } else {
51                        if ($this->show_compat_errors) {
52                                $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                        }
54                }
55        }
56
57        public function __get($p)
58        {
59                if (array_key_exists($p, $this->compat['properties']) !== false) {
60                        if ($this->show_compat_errors) {
61                                $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                        }
63                        return $this->compat['properties'][$p];
64                } else {
65                        if ($this->show_compat_errors) {
66                                $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                        }
68                }
69        }
70
71        public function __call($m, $a)
72        {
73                if (method_exists($this->dataProvider, $m)) {
74                        call_user_func_array(array($this->dataProvider, $m), $a);
75                } elseif ($this->show_compat_errors) {
76                        if (array_search($m, $this->compat['methods']) !== false) {
77                                $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                        } else {
79                                $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                }
82        }
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                parent::__construct();
162                $this->charset = 'iso-8859-1';
163                $this->dataProvider = new Dwoo_Data();
164                $this->compiler = new Dwoo_Compiler();
165        }
166
167        public function display($filename, $cacheId=null, $compileId=null)
168        {
169                $this->fetch($filename, $cacheId, $compileId, true);
170        }
171
172        public function fetch($filename, $cacheId=null, $compileId=null, $display=false)
173        {
174                $this->setCacheDir($this->cache_dir);
175                $this->setCompileDir($this->compile_dir);
176
177                if ($this->security) {
178                        $policy = new Dwoo_Security_Policy();
179                        $policy->addPhpFunction(array_merge($this->security_settings['IF_FUNCS'], $this->security_settings['MODIFIER_FUNCS']));
180
181                        $phpTags = $this->security_settings['PHP_HANDLING'] ? SMARTY_PHP_ALLOW : $this->php_handling;
182                        if ($this->security_settings['PHP_TAGS']) {
183                                $phpTags = SMARTY_PHP_ALLOW;
184                        }
185                        switch($phpTags) {
186                                case SMARTY_PHP_ALLOW:
187                                case SMARTY_PHP_PASSTHRU:
188                                        $phpTags = Dwoo_Security_Policy::PHP_ALLOW;
189                                        break;
190                                case SMARTY_PHP_QUOTE:
191                                        $phpTags = Dwoo_Security_Policy::PHP_ENCODE;
192                                        break;
193                                case SMARTY_PHP_REMOVE:
194                                default:
195                                        $phpTags = Dwoo_Security_Policy::PHP_REMOVE;
196                                        break;
197                        }
198                        $policy->setPhpHandling($phpTags);
199
200                        $policy->setConstantHandling($this->security_settings['ALLOW_CONSTANTS']);
201
202                        if ($this->security_settings['INCLUDE_ANY']) {
203                                $policy->allowDirectory(preg_replace('{^((?:[a-z]:)?[\\\\/]).*}i', '$1', __FILE__));
204                        } else {
205                                $policy->allowDirectory($this->secure_dir);
206                        }
207
208                        $this->setSecurityPolicy($policy);
209                }
210
211                if (!empty($this->plugins_dir)) {
212                        foreach ($this->plugins_dir as $dir) {
213                                $this->getLoader()->addDirectory(rtrim($dir, '\\/'));
214                        }
215                }
216
217                $tpl = $this->makeTemplate($filename, $cacheId, $compileId);
218                if ($this->force_compile) {
219                        $tpl->forceCompilation();
220                }
221
222                if ($this->caching > 0) {
223                        $this->cacheTime = $this->cache_lifetime;
224                } else {
225                        $this->cacheTime = 0;
226                }
227
228                if ($this->compiler_class !== null) {
229                        if ($this->compiler_file !== null && !class_exists($this->compiler_class, false)) {
230                                include $this->compiler_file;
231                        }
232                        $this->compiler = new $this->compiler_class;
233                } else {
234                        $this->compiler->addPreProcessor('smarty_compat', true);
235                        $this->compiler->setLooseOpeningHandling(true);
236                }
237
238                $this->compiler->setDelimiters($this->left_delimiter, $this->right_delimiter);
239
240                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                if ($_compiler === null) {
246                        $_compiler = $this->compiler;
247                }
248                return parent::get($_tpl, $data, $_compiler, $_output);
249        }
250
251        public function register_function($name, $callback, $cacheable=true, $cache_attrs=null)
252        {
253                if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_FUNCTION) {
254                        throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
255                }
256                $this->plugins[$name] = array('type'=>self::SMARTY_FUNCTION, 'callback'=>$callback);
257        }
258
259        public function unregister_function($name)
260        {
261                unset($this->plugins[$name]);
262        }
263
264        public function register_block($name, $callback, $cacheable=true, $cache_attrs=null)
265        {
266                if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_BLOCK) {
267                        throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
268                }
269                $this->plugins[$name] = array('type'=>self::SMARTY_BLOCK, 'callback'=>$callback);
270        }
271
272        public function unregister_block($name)
273        {
274                unset($this->plugins[$name]);
275        }
276
277        public function register_modifier($name, $callback)
278        {
279                if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_MODIFIER) {
280                        throw new Dwoo_Exception('Multiple plugins of different types can not share the same name');
281                }
282                $this->plugins[$name] = array('type'=>self::SMARTY_MODIFIER, 'callback'=>$callback);
283        }
284
285        public function unregister_modifier($name)
286        {
287                unset($this->plugins[$name]);
288        }
289
290        public function register_prefilter($callback)
291        {
292                $processor = new Dwoo_SmartyProcessorAdapter($this->compiler);
293                $processor->registerCallback($callback);
294                $this->_filters['pre'][] = $processor;
295                $this->compiler->addPreProcessor($processor);
296        }
297
298        public function unregister_prefilter($callback)
299        {
300                foreach ($this->_filters['pre'] as $index => $processor)
301                        if ($processor->callback === $callback) {
302                                $this->compiler->removePostProcessor($processor);
303                                unset($this->_filters['pre'][$index]);
304                        }
305        }
306
307        public function register_postfilter($callback)
308        {
309                $processor = new Dwoo_SmartyProcessorAdapter($this->compiler);
310                $processor->registerCallback($callback);
311                $this->_filters['post'][] = $processor;
312                $this->compiler->addPostProcessor($processor);
313        }
314
315        public function unregister_postfilter($callback)
316        {
317                foreach ($this->_filters['post'] as $index => $processor)
318                        if ($processor->callback === $callback) {
319                                $this->compiler->removePostProcessor($processor);
320                                unset($this->_filters['post'][$index]);
321                        }
322        }
323
324        public function register_outputfilter($callback)
325        {
326                $filter = new Dwoo_SmartyFilterAdapter($this);
327                $filter->registerCallback($callback);
328                $this->_filters['output'][] = $filter;
329                $this->addFilter($filter);
330        }
331
332        public function unregister_outputfilter($callback)
333        {
334                foreach ($this->_filters['output'] as $index => $filter)
335                        if ($filter->callback === $callback) {
336                                $this->removeOutputFilter($filter);
337                                unset($this->_filters['output'][$index]);
338                        }
339        }
340
341        function register_object($object, $object_impl, $allowed = array(), $smarty_args = false, $block_methods = array())
342        {
343                settype($allowed, 'array');
344                settype($block_methods, 'array');
345                settype($smarty_args, 'boolean');
346
347                if (!empty($allowed) && $this->show_compat_errors) {
348                        $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                }
350
351                if ($smarty_args) {
352                        $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                }
354
355                if (!empty($block_methods)) {
356                        $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                }
358
359                $this->dataProvider->assign($object, $object_impl);
360        }
361
362        function unregister_object($object)
363        {
364                $this->dataProvider->clear($object);
365        }
366
367        function get_registered_object($name) {
368                $data = $this->dataProvider->getData();
369                if (isset($data[$name]) && is_object($data[$name])) {
370                        return $data[$name];
371                } else {
372                        trigger_error('Dwoo_Compiler: object "'.$name.'" was not registered or is not an object', E_USER_ERROR);
373                }
374        }
375
376        public function template_exists($filename)
377        {
378                if (!is_array($this->template_dir)) {
379                        return file_exists($this->template_dir.DIRECTORY_SEPARATOR.$filename);
380                } else {
381                        foreach ($this->template_dir as $tpl_dir) {
382                                if (file_exists($tpl_dir.DIRECTORY_SEPARATOR.$filename)) {
383                                        return true;
384                                }
385                        }
386                        return false;
387                }
388        }
389
390        public function is_cached($tpl, $cacheId = null, $compileId = null)
391        {
392                return $this->isCached($this->makeTemplate($tpl, $cacheId, $compileId));
393        }
394
395        public function append_by_ref($var, &$value, $merge=false)
396        {
397                $this->dataProvider->appendByRef($var, $value, $merge);
398        }
399
400        public function assign_by_ref($name, &$val)
401        {
402                $this->dataProvider->assignByRef($name, $val);
403        }
404
405        public function clear_assign($var)
406        {
407                $this->dataProvider->clear($var);
408        }
409
410        public function clear_all_assign()
411        {
412                $this->dataProvider->clear();
413        }
414
415        public function get_template_vars($name=null)
416        {
417                if ($this->show_compat_errors) {
418                        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                }
420
421                $data = $this->dataProvider->getData();
422                if ($name === null)
423                        return $data;
424                elseif (isset($data[$name]))
425                        return $data[$name];
426                return null;
427        }
428
429        public function clear_all_cache($olderThan = 0)
430        {
431                $this->clearCache($olderThan);
432        }
433
434        public function clear_cache($template, $cacheId = null, $compileId = null, $olderThan = 0)
435        {
436                $this->makeTemplate($template, $cacheId, $compileId)->clearCache($olderThan);
437        }
438
439        public function trigger_error($error_msg, $error_type = E_USER_WARNING)
440        {
441                $this->triggerError($error_msg, $error_type);
442        }
443
444        protected function initGlobals()
445        {
446                parent::initGlobals();
447                $this->globals['ldelim'] = '{';
448                $this->globals['rdelim'] = '}';
449        }
450
451        protected function makeTemplate($file, $cacheId, $compileId)
452        {
453                if ($compileId === null)
454                        $compileId = $this->compile_id;
455
456                $hash = bin2hex(md5($file.$cacheId.$compileId, true));
457                if (!isset(self::$tplCache[$hash])) {
458                        // abs path
459                        if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
460                                self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId);
461                        } elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
462                                self::$tplCache[$hash] = new Dwoo_Template_File($file, null, $cacheId, $compileId, $this->template_dir);
463                        } else {
464                                throw new Exception('Unable to load "'.$file.'", check the template_dir');
465                        }
466                }
467                return self::$tplCache[$hash];
468        }
469
470        public function triggerError($message, $level=E_USER_NOTICE)
471        {
472                if (is_object($this->template)) {
473                        return parent::triggerError($message, $level);
474                }
475                trigger_error('Dwoo error : '.$message, $level);
476        }
477}
478
479class Dwoo_Smarty_Filter_Adapter extends Dwoo_Filter
480{
481        public $callback;
482
483        public function process($input)
484        {
485                return call_user_func($this->callback, $input);
486        }
487
488        public function registerCallback($callback)
489        {
490                $this->callback = $callback;
491        }
492}
493
494class Dwoo_Smarty_Processor_Adapter extends Dwoo_Processor
495{
496        public $callback;
497
498        public function process($input)
499        {
500                return call_user_func($this->callback, $input);
501        }
502
503        public function registerCallback($callback)
504        {
505                $this->callback = $callback;
506        }
507}
508
509// cloaks the adapter if possible with the smarty name to fool type-hinted plugins
510if (class_exists('Smarty', false) === false)
511{
512        interface Smarty {}
513        class Dwoo_Smarty_Adapter extends Dwoo_Smarty__Adapter implements Smarty {}
514}
515else
516{
517        class Dwoo_Smarty_Adapter extends Dwoo_Smarty__Adapter {}
518}
Note: See TracBrowser for help on using the repository browser.