smarty = $smarty; if (is_object($_parent)) { // when object set up back pointer $this->parent = $_parent; } elseif (is_array($_parent)) { // set up variable values foreach ($_parent as $_key => $_val) { $this->assign($_key, $_val); } } elseif ($_parent !== null) { throw new Exception('Wrong type for template variables'); } } /** * assigns a Smarty variable * * @param array|string $tpl_var the template variable name(s) * @param mixed $value the value to assign * @param boolean $nocache if true any output of this variable will be not cached * @param int $scope one of self::SCOPE_* constants * * @return Data current Data (or Smarty or \Smarty\Template) instance for * chaining */ public function assign($tpl_var, $value = null, $nocache = false, $scope = null) { if (is_array($tpl_var)) { foreach ($tpl_var as $_key => $_val) { $this->assign($_key, $_val, $nocache, $scope); } return $this; } switch ($scope ?? $this->getDefaultScope()) { case self::SCOPE_GLOBAL: case self::SCOPE_SMARTY: $this->getSmarty()->assign($tpl_var, $value); break; case self::SCOPE_TPL_ROOT: $ptr = $this; while (isset($ptr->parent) && ($ptr->parent instanceof Template)) { $ptr = $ptr->parent; } $ptr->assign($tpl_var, $value); break; case self::SCOPE_ROOT: $ptr = $this; while (isset($ptr->parent) && !($ptr->parent instanceof Smarty)) { $ptr = $ptr->parent; } $ptr->assign($tpl_var, $value); break; case self::SCOPE_PARENT: if ($this->parent) { $this->parent->assign($tpl_var, $value); } else { // assign local as fallback $this->assign($tpl_var, $value); } break; case self::SCOPE_LOCAL: default: if (isset($this->tpl_vars[$tpl_var])) { $this->tpl_vars[$tpl_var]->setValue($value); if ($nocache) { $this->tpl_vars[$tpl_var]->setNocache(true); } } else { $this->tpl_vars[$tpl_var] = new Variable($value, $nocache); } } return $this; } /** * appends values to template variables * * @param array|string $tpl_var the template variable name(s) * @param mixed $value the value to append * @param bool $merge flag if array elements shall be merged * @param bool $nocache if true any output of this variable will * be not cached * * @return Data * @api Smarty::append() */ public function append($tpl_var, $value = null, $merge = false, $nocache = false) { if (is_array($tpl_var)) { foreach ($tpl_var as $_key => $_val) { $this->append($_key, $_val, $merge, $nocache); } } else { $newValue = $this->getValue($tpl_var) ?? []; if (!is_array($newValue)) { $newValue = (array) $newValue; } if ($merge && is_array($value)) { foreach ($value as $_mkey => $_mval) { $newValue[$_mkey] = $_mval; } } else { $newValue[] = $value; } $this->assign($tpl_var, $newValue, $nocache); } return $this; } /** * assigns a global Smarty variable * * @param string $varName the global variable name * @param mixed $value the value to assign * @param boolean $nocache if true any output of this variable will be not cached * * @return Data * @deprecated since 5.0 */ public function assignGlobal($varName, $value = null, $nocache = false) { trigger_error(__METHOD__ . " is deprecated. Use \\Smarty\\Smarty::assign() to assign a variable " . " at the Smarty level.", E_USER_DEPRECATED); return $this->getSmarty()->assign($varName, $value, $nocache); } /** * Returns a single or all template variables * * @param string $varName variable name or null * @param bool $searchParents include parent templates? * * @return mixed variable value or or array of variables * @api Smarty::getTemplateVars() * */ public function getTemplateVars($varName = null, $searchParents = true) { if (isset($varName)) { return $this->getValue($varName, $searchParents); } return array_merge( $this->parent && $searchParents ? $this->parent->getTemplateVars() : [], array_map(function(Variable $var) { return $var->getValue(); }, $this->tpl_vars) ); } /** * Wrapper for ::getVariable() * * @deprecated since 5.0 * * @param $varName * @param $searchParents * @param $errorEnable * * @return void */ public function _getVariable($varName, $searchParents = true, $errorEnable = true) { trigger_error('Using ::_getVariable() to is deprecated and will be ' . 'removed in a future release. Use getVariable() instead.', E_USER_DEPRECATED); return $this->getVariable($varName, $searchParents, $errorEnable); } /** * Gets the object of a Smarty variable * * @param string $varName the name of the Smarty variable * @param bool $searchParents search also in parent data * @param bool $errorEnable * * @return Variable */ public function getVariable($varName, $searchParents = true, $errorEnable = true) { if (isset($this->tpl_vars[$varName])) { return $this->tpl_vars[$varName]; } if ($searchParents && $this->parent) { return $this->parent->getVariable($varName, $searchParents, $errorEnable); } if ($errorEnable && $this->getSmarty()->error_unassigned) { // force a notice $x = $$varName; } return new UndefinedVariable(); } /** * Directly sets a complete Variable object in the variable with the given name. * @param $varName * @param Variable $variableObject * * @return void */ public function setVariable($varName, Variable $variableObject) { $this->tpl_vars[$varName] = $variableObject; } /** * Indicates if given variable has been set. * @param $varName * * @return bool */ public function hasVariable($varName): bool { return !($this->getVariable($varName, true, false) instanceof UndefinedVariable); } /** * Returns the value of the Smarty\Variable given by $varName, or null if the variable does not exist. * * @param $varName * @param bool $searchParents * * @return mixed|null */ public function getValue($varName, $searchParents = true) { $variable = $this->getVariable($varName, $searchParents); return isset($variable) ? $variable->getValue() : null; } /** * load config variables into template object * * @param array $new_config_vars */ public function assignConfigVars($new_config_vars, array $sections = []) { // copy global config vars foreach ($new_config_vars['vars'] as $variable => $value) { if ($this->getSmarty()->config_overwrite || !isset($this->config_vars[$variable])) { $this->config_vars[$variable] = $value; } else { $this->config_vars[$variable] = array_merge((array)$this->config_vars[$variable], (array)$value); } } foreach ($sections as $tpl_section) { if (isset($new_config_vars['sections'][$tpl_section])) { foreach ($new_config_vars['sections'][$tpl_section]['vars'] as $variable => $value) { if ($this->getSmarty()->config_overwrite || !isset($this->config_vars[$variable])) { $this->config_vars[$variable] = $value; } else { $this->config_vars[$variable] = array_merge((array)$this->config_vars[$variable], (array)$value); } } } } } /** * Get Smarty object * * @return Smarty */ public function getSmarty() { return $this->smarty; } /** * clear the given assigned template variable(s). * * @param string|array $tpl_var the template variable(s) to clear * * @return Data * * @api Smarty::clearAssign() */ public function clearAssign($tpl_var) { if (is_array($tpl_var)) { foreach ($tpl_var as $curr_var) { unset($this->tpl_vars[ $curr_var ]); } } else { unset($this->tpl_vars[ $tpl_var ]); } return $this; } /** * clear all the assigned template variables. * * @return Data * * @api Smarty::clearAllAssign() */ public function clearAllAssign() { $this->tpl_vars = array(); return $this; } /** * clear a single or all config variables * * @param string|null $name variable name or null * * @return Data * * @api Smarty::clearConfig() */ public function clearConfig($name = null) { if (isset($name)) { unset($this->config_vars[ $name ]); } else { $this->config_vars = array(); } return $this; } /** * Gets a config variable value * * @param string $varName the name of the config variable * * @return mixed the value of the config variable * @throws Exception */ public function getConfigVariable($varName) { if (isset($this->config_vars[$varName])) { return $this->config_vars[$varName]; } $returnValue = $this->parent ? $this->parent->getConfigVariable($varName) : null; if ($returnValue === null && $this->getSmarty()->error_unassigned) { throw new Exception("Undefined variable $varName"); } return $returnValue; } public function hasConfigVariable($varName): bool { try { return $this->getConfigVariable($varName) !== null; } catch (Exception $e) { return false; } } /** * Returns a single or all config variables * * @param string $varname variable name or null * * @return mixed variable value or or array of variables * @throws Exception * * @api Smarty::getConfigVars() */ public function getConfigVars($varname = null) { if (isset($varname)) { return $this->getConfigVariable($varname); } return array_merge($this->parent ? $this->parent->getConfigVars() : [], $this->config_vars); } /** * load a config file, optionally load just selected sections * * @param string $config_file filename * @param mixed $sections array of section names, single * section or null * @returns $this * @throws \Exception * * @api Smarty::configLoad() */ public function configLoad($config_file, $sections = null) { $template = $this->getSmarty()->doCreateTemplate($config_file, null, null, $this, null, null, true); $template->caching = Smarty::CACHING_OFF; $template->assign('sections', (array) $sections ?? []); // trigger a call to $this->assignConfigVars $template->fetch(); return $this; } /** * Sets the default scope for new variables assigned in this template. * @param int $scope * * @return void */ protected function setDefaultScope(int $scope) { $this->defaultScope = $scope; } /** * Returns the default scope for new variables assigned in this template. * @return int */ public function getDefaultScope(): int { return $this->defaultScope; } /** * @return Data|Smarty|null */ public function getParent() { return $this->parent; } /** * @param Data|Smarty|null $parent */ public function setParent($parent): void { $this->parent = $parent; } public function pushStack(): void { $stackList = []; foreach ($this->tpl_vars as $name => $variable) { $stackList[$name] = clone $variable; // variables are stored in Variable objects } $this->_var_stack[] = $this->tpl_vars; $this->tpl_vars = $stackList; $this->_config_stack[] = $this->config_vars; } public function popStack(): void { $this->tpl_vars = array_pop($this->_var_stack); $this->config_vars = array_pop($this->_config_stack); } }