1<?php
2/**
3 * Smarty Internal Plugin Compile Modifier
4 * Compiles code for modifier execution
5 *
6 * @package    Smarty
7 * @subpackage Compiler
8 * @author     Uwe Tews
9 */
10
11/**
12 * Smarty Internal Plugin Compile Modifier Class
13 *
14 * @package    Smarty
15 * @subpackage Compiler
16 */
17class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase
18{
19    /**
20     * Compiles code for modifier execution
21     *
22     * @param array                                 $args      array with attributes from parser
23     * @param \Smarty_Internal_TemplateCompilerBase $compiler  compiler object
24     * @param array                                 $parameter array with compilation parameter
25     *
26     * @return string compiled code
27     * @throws \SmartyCompilerException
28     * @throws \SmartyException
29     */
30    public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
31    {
32        // check and get attributes
33        $_attr = $this->getAttributes($compiler, $args);
34        $output = $parameter[ 'value' ];
35        // loop over list of modifiers
36        foreach ($parameter[ 'modifierlist' ] as $single_modifier) {
37            /* @var string $modifier */
38            $modifier = $single_modifier[ 0 ];
39            $single_modifier[ 0 ] = $output;
40            $params = implode(',', $single_modifier);
41            // check if we know already the type of modifier
42            if (isset($compiler->known_modifier_type[ $modifier ])) {
43                $modifier_types = array($compiler->known_modifier_type[ $modifier ]);
44            } else {
45                $modifier_types = array(1, 2, 3, 4, 5, 6);
46            }
47            foreach ($modifier_types as $type) {
48                switch ($type) {
49                    case 1:
50                        // registered modifier
51                        if (isset($compiler->smarty->registered_plugins[ Smarty::PLUGIN_MODIFIER ][ $modifier ])) {
52                            if (is_callable($compiler->smarty->registered_plugins[ Smarty::PLUGIN_MODIFIER ][ $modifier ][ 0 ])) {
53                                $output =
54                                    sprintf(
55                                        'call_user_func_array($_smarty_tpl->registered_plugins[ \'%s\' ][ %s ][ 0 ], array( %s ))',
56                                        Smarty::PLUGIN_MODIFIER,
57                                        var_export($modifier, true),
58                                        $params
59                                    );
60                                $compiler->known_modifier_type[ $modifier ] = $type;
61                                break 2;
62                            }
63                        }
64                        break;
65                    case 2:
66                        // registered modifier compiler
67                        if (isset($compiler->smarty->registered_plugins[ Smarty::PLUGIN_MODIFIERCOMPILER ][ $modifier ][ 0 ])) {
68                            $output =
69                                call_user_func(
70                                    $compiler->smarty->registered_plugins[ Smarty::PLUGIN_MODIFIERCOMPILER ][ $modifier ][ 0 ],
71                                    $single_modifier,
72                                    $compiler->smarty
73                                );
74                            $compiler->known_modifier_type[ $modifier ] = $type;
75                            break 2;
76                        }
77                        break;
78                    case 3:
79                        // modifiercompiler plugin
80                        if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
81                            // check if modifier allowed
82                            if (!is_object($compiler->smarty->security_policy)
83                                || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
84                            ) {
85                                $plugin = 'smarty_modifiercompiler_' . $modifier;
86                                $output = $plugin($single_modifier, $compiler);
87                            }
88                            $compiler->known_modifier_type[ $modifier ] = $type;
89                            break 2;
90                        }
91                        break;
92                    case 4:
93                        // modifier plugin
94                        if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
95                            // check if modifier allowed
96                            if (!is_object($compiler->smarty->security_policy)
97                                || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
98                            ) {
99                                $output = "{$function}({$params})";
100                            }
101                            $compiler->known_modifier_type[ $modifier ] = $type;
102                            break 2;
103                        }
104                        break;
105                    case 5:
106                        // PHP function
107                        if (is_callable($modifier)) {
108                            // check if modifier allowed
109                            if (!is_object($compiler->smarty->security_policy)
110                                || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)
111                            ) {
112                                $output = "{$modifier}({$params})";
113                            }
114                            $compiler->known_modifier_type[ $modifier ] = $type;
115                            break 2;
116                        }
117                        break;
118                    case 6:
119                        // default plugin handler
120                        if (isset($compiler->default_handler_plugins[ Smarty::PLUGIN_MODIFIER ][ $modifier ])
121                            || (is_callable($compiler->smarty->default_plugin_handler_func)
122                                && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))
123                        ) {
124                            $function = $compiler->default_handler_plugins[ Smarty::PLUGIN_MODIFIER ][ $modifier ][ 0 ];
125                            // check if modifier allowed
126                            if (!is_object($compiler->smarty->security_policy)
127                                || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)
128                            ) {
129                                if (!is_array($function)) {
130                                    $output = "{$function}({$params})";
131                                } else {
132                                    if (is_object($function[ 0 ])) {
133                                        $output = $function[ 0 ] . '->' . $function[ 1 ] . '(' . $params . ')';
134                                    } else {
135                                        $output = $function[ 0 ] . '::' . $function[ 1 ] . '(' . $params . ')';
136                                    }
137                                }
138                            }
139                            if (isset($compiler->required_plugins[ 'nocache' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ])
140                                ||
141                                isset($compiler->required_plugins[ 'compiled' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ])
142                            ) {
143                                // was a plugin
144                                $compiler->known_modifier_type[ $modifier ] = 4;
145                            } else {
146                                $compiler->known_modifier_type[ $modifier ] = $type;
147                            }
148                            break 2;
149                        }
150                }
151            }
152            if (!isset($compiler->known_modifier_type[ $modifier ])) {
153                $compiler->trigger_template_error("unknown modifier '{$modifier}'", null, true);
154            }
155        }
156        return $output;
157    }
158}
159