1<?php
2
3/**
4 * Smarty Method ConfigLoad
5 *
6 * Smarty::configLoad() method
7 *
8 * @package    Smarty
9 * @subpackage PluginsInternal
10 * @author     Uwe Tews
11 */
12class Smarty_Internal_Method_ConfigLoad
13{
14    /**
15     * Valid for all objects
16     *
17     * @var int
18     */
19    public $objMap = 7;
20
21    /**
22     * load a config file, optionally load just selected sections
23     *
24     * @api  Smarty::configLoad()
25     * @link http://www.smarty.net/docs/en/api.config.load.tpl
26     *
27     * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data
28     * @param string                                                  $config_file filename
29     * @param mixed                                                   $sections    array of section names, single
30     *                                                                             section or null
31     *
32     * @return \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template
33     * @throws \Exception
34     */
35    public function configLoad(Smarty_Internal_Data $data, $config_file, $sections = null)
36    {
37        $this->_loadConfigFile($data, $config_file, $sections, null);
38        return $data;
39    }
40
41    /**
42     * load a config file, optionally load just selected sections
43     *
44     * @api  Smarty::configLoad()
45     * @link http://www.smarty.net/docs/en/api.config.load.tpl
46     *
47     * @param \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template $data
48     * @param string                                                  $config_file filename
49     * @param mixed                                                   $sections    array of section names, single
50     *                                                                             section or null
51     * @param int                                                     $scope       scope into which config variables
52     *                                                                             shall be loaded
53     *
54     * @throws \Exception
55     */
56    public function _loadConfigFile(Smarty_Internal_Data $data, $config_file, $sections = null, $scope = 0)
57    {
58        /* @var \Smarty $smarty */
59        $smarty = $data->_getSmartyObj();
60        /* @var \Smarty_Internal_Template $confObj */
61        $confObj = new Smarty_Internal_Template($config_file, $smarty, $data, null, null, null, null, true);
62        $confObj->caching = Smarty::CACHING_OFF;
63        $confObj->source->config_sections = $sections;
64        $confObj->source->scope = $scope;
65        $confObj->compiled = Smarty_Template_Compiled::load($confObj);
66        $confObj->compiled->render($confObj);
67        if ($data->_isTplObj()) {
68            $data->compiled->file_dependency[ $confObj->source->uid ] =
69                array($confObj->source->filepath, $confObj->source->getTimeStamp(), $confObj->source->type);
70        }
71    }
72
73    /**
74     * load config variables into template object
75     *
76     * @param \Smarty_Internal_Template $tpl
77     * @param array                     $new_config_vars
78     */
79    public function _loadConfigVars(Smarty_Internal_Template $tpl, $new_config_vars)
80    {
81        $this->_assignConfigVars($tpl->parent->config_vars, $tpl, $new_config_vars);
82        $tagScope = $tpl->source->scope;
83        if ($tagScope >= 0) {
84            if ($tagScope === Smarty::SCOPE_LOCAL) {
85                $this->_updateVarStack($tpl, $new_config_vars);
86                $tagScope = 0;
87                if (!$tpl->scope) {
88                    return;
89                }
90            }
91            if ($tpl->parent->_isTplObj() && ($tagScope || $tpl->parent->scope)) {
92                $mergedScope = $tagScope | $tpl->scope;
93                if ($mergedScope) {
94                    // update scopes
95                    /* @var \Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $ptr */
96                    foreach ($tpl->smarty->ext->_updateScope->_getAffectedScopes($tpl->parent, $mergedScope) as $ptr) {
97                        $this->_assignConfigVars($ptr->config_vars, $tpl, $new_config_vars);
98                        if ($tagScope && $ptr->_isTplObj() && isset($tpl->_cache[ 'varStack' ])) {
99                            $this->_updateVarStack($tpl, $new_config_vars);
100                        }
101                    }
102                }
103            }
104        }
105    }
106
107    /**
108     * Assign all config variables in given scope
109     *
110     * @param array                     $config_vars     config variables in scope
111     * @param \Smarty_Internal_Template $tpl
112     * @param array                     $new_config_vars loaded config variables
113     */
114    public function _assignConfigVars(&$config_vars, Smarty_Internal_Template $tpl, $new_config_vars)
115    {
116        // copy global config vars
117        foreach ($new_config_vars[ 'vars' ] as $variable => $value) {
118            if ($tpl->smarty->config_overwrite || !isset($config_vars[ $variable ])) {
119                $config_vars[ $variable ] = $value;
120            } else {
121                $config_vars[ $variable ] = array_merge((array)$config_vars[ $variable ], (array)$value);
122            }
123        }
124        // scan sections
125        $sections = $tpl->source->config_sections;
126        if (!empty($sections)) {
127            foreach ((array)$sections as $tpl_section) {
128                if (isset($new_config_vars[ 'sections' ][ $tpl_section ])) {
129                    foreach ($new_config_vars[ 'sections' ][ $tpl_section ][ 'vars' ] as $variable => $value) {
130                        if ($tpl->smarty->config_overwrite || !isset($config_vars[ $variable ])) {
131                            $config_vars[ $variable ] = $value;
132                        } else {
133                            $config_vars[ $variable ] = array_merge((array)$config_vars[ $variable ], (array)$value);
134                        }
135                    }
136                }
137            }
138        }
139    }
140
141    /**
142     * Update config variables in template local variable stack
143     *
144     * @param \Smarty_Internal_Template $tpl
145     * @param array                     $config_vars
146     */
147    public function _updateVarStack(Smarty_Internal_Template $tpl, $config_vars)
148    {
149        $i = 0;
150        while (isset($tpl->_cache[ 'varStack' ][ $i ])) {
151            $this->_assignConfigVars($tpl->_cache[ 'varStack' ][ $i ][ 'config' ], $tpl, $config_vars);
152            $i++;
153        }
154    }
155
156    /**
157     * gets  a config variable value
158     *
159     * @param \Smarty|\Smarty_Internal_Data|\Smarty_Internal_Template $data
160     * @param string                                                  $varName the name of the config variable
161     * @param bool                                                    $errorEnable
162     *
163     * @return null|string  the value of the config variable
164     */
165    public function _getConfigVariable(Smarty_Internal_Data $data, $varName, $errorEnable = true)
166    {
167        $_ptr = $data;
168        while ($_ptr !== null) {
169            if (isset($_ptr->config_vars[ $varName ])) {
170                // found it, return it
171                return $_ptr->config_vars[ $varName ];
172            }
173            // not found, try at parent
174            $_ptr = $_ptr->parent;
175        }
176        if ($data->smarty->error_unassigned && $errorEnable) {
177            // force a notice
178            $x = $$varName;
179        }
180        return null;
181    }
182}
183