1<?php
2/**
3 * Smarty Internal Plugin Compile Print Expression
4 * Compiles any tag which will output an expression or variable
5 *
6 * @package    Smarty
7 * @subpackage Compiler
8 * @author     Uwe Tews
9 */
10
11/**
12 * Smarty Internal Plugin Compile Print Expression Class
13 *
14 * @package    Smarty
15 * @subpackage Compiler
16 */
17class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase
18{
19    /**
20     * Attribute definition: Overwrites base class.
21     *
22     * @var array
23     * @see Smarty_Internal_CompileBase
24     */
25    public $optional_attributes = array('assign');
26
27    /**
28     * Attribute definition: Overwrites base class.
29     *
30     * @var array
31     * @see Smarty_Internal_CompileBase
32     */
33    public $option_flags = array('nocache', 'nofilter');
34
35    /**
36     * Compiles code for generating output from any expression
37     *
38     * @param array                                 $args      array with attributes from parser
39     * @param \Smarty_Internal_TemplateCompilerBase $compiler  compiler object
40     * @param array                                 $parameter array with compilation parameter
41     *
42     * @return string
43     * @throws \SmartyException
44     */
45    public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
46    {
47        // check and get attributes
48        $_attr = $this->getAttributes($compiler, $args);
49        // nocache option
50        if ($_attr['nocache'] === true) {
51            $compiler->tag_nocache = true;
52        }
53        if (isset($_attr['assign'])) {
54            // assign output to variable
55            $output = "<?php \$_smarty_tpl->assign({$_attr['assign']},{$parameter['value']});?>";
56        } else {
57            // display value
58            $output = $parameter['value'];
59            // tag modifier
60            if (!empty($parameter['modifierlist'])) {
61                $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'],
62                                                                                   'value'        => $output));
63            }
64            if (!$_attr['nofilter']) {
65                // default modifier
66                if (!empty($compiler->smarty->default_modifiers)) {
67                    if (empty($compiler->default_modifier_list)) {
68                        $modifierlist = array();
69                        foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) {
70                            preg_match_all('/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', $single_default_modifier, $mod_array);
71                            for ($i = 0, $count = count($mod_array[0]); $i < $count; $i ++) {
72                                if ($mod_array[0][$i] != ':') {
73                                    $modifierlist[$key][] = $mod_array[0][$i];
74                                }
75                            }
76                        }
77                        $compiler->default_modifier_list = $modifierlist;
78                    }
79                    $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list,
80                                                                                       'value'        => $output));
81                }
82                // autoescape html
83                if ($compiler->template->smarty->escape_html) {
84                    $output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')";
85                }
86                // loop over registered filters
87                if (!empty($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE])) {
88                    foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key =>
89                             $function) {
90                        if (!is_array($function)) {
91                            $output = "{$function}({$output},\$_smarty_tpl)";
92                        } elseif (is_object($function[0])) {
93                            $output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE]['{$key}'][0]->{$function[1]}({$output},\$_smarty_tpl)";
94                        } else {
95                            $output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)";
96                        }
97                    }
98                }
99                // auto loaded filters
100                if (isset($compiler->smarty->autoload_filters[Smarty::FILTER_VARIABLE])) {
101                    foreach ((array) $compiler->template->smarty->autoload_filters[Smarty::FILTER_VARIABLE] as $name) {
102                        $result = $this->compile_output_filter($compiler, $name, $output);
103                        if ($result !== false) {
104                            $output = $result;
105                        } else {
106                            // not found, throw exception
107                            throw new SmartyException("Unable to load filter '{$name}'");
108                        }
109                    }
110                }
111                foreach ($compiler->variable_filters as $filter) {
112                    if (count($filter) == 1 &&
113                        ($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false
114                    ) {
115                        $output = $result;
116                    } else {
117                        $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter),
118                                                                                           'value'        => $output));
119                    }
120                }
121            }
122
123            $compiler->has_output = true;
124            $output = "<?php echo {$output};?>";
125        }
126
127        return $output;
128    }
129
130    /**
131     * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
132     * @param string                                $name     name of variable filter
133     * @param string                                $output   embedded output
134     *
135     * @return string
136     */
137    private function compile_output_filter(Smarty_Internal_TemplateCompilerBase $compiler, $name, $output)
138    {
139        $plugin_name = "smarty_variablefilter_{$name}";
140        $path = $compiler->smarty->loadPlugin($plugin_name, false);
141        if ($path) {
142            if ($compiler->template->caching) {
143                $compiler->parent_compiler->template->compiled->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
144                $compiler->parent_compiler->template->compiled->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
145            } else {
146                $compiler->parent_compiler->template->compiled->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path;
147                $compiler->parent_compiler->template->compiled->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name;
148            }
149        } else {
150            // not found
151            return false;
152        }
153
154        return "{$plugin_name}({$output},\$_smarty_tpl)";
155    }
156}
157