<?php

if (MH_PLATFORM_GAMBIO >= 2.0) {
    if (method_exists('MainFactory', 'load_origin_class')) {
        MainFactory::load_origin_class('Smarty');
    }
}


if (!class_exists('Smarty')) {

    if (version_compare(phpversion(), '7.2.0') >= 0) {
        require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/Smarty_5/libs/Smarty.class.php'); // include smarty
        if (!class_exists('Smarty') && class_exists('Smarty\Smarty')) {
            class_alias('Smarty\Smarty', 'Smarty');
        }
    }
    else if (version_compare(phpversion(), '7.1.0') >= 0) {
        // load smarty 4+ if not exists
        require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/Smarty_4/libs/Smarty.class.php'); // include smarty
    } else {
        // load smarty 3.1+ if not exists
        require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/Smarty_3/SmartyBC.class.php'); // include smarty
    }


}
class mh_Smarty extends Smarty
{

    var $wrapper_version;
    public $mh_htmlCouponTemplate;
    public $mh_htmlCouponTemplate_mtime;

    public $mh_subjectTemplate;
    public $mh_subjectTemplate_mtime;
    public $mh_preheaderTemplate;
    public $mh_preheaderTemplate_mtime;
    public $mh_htmlTemplate;
    public $mh_htmlTemplate_mtime;
    public $mh_txtTemplate;
    public $mh_txtTemplate_mtime;
    public $mh_htmlBodyTemplate;
    public $mh_htmlBodyTemplate_mtime;
    public $mh_txtBodyTemplate;
    public $mh_txtBodyTemplate_mtime;

    public $template_dir;
    public $compile_dir;
    public $config_dir;
    public $cache_dir;
    public $plugins_dir;
    public $left_delimiter = '{';
    public $right_delimiter = '}';
    public $compile_id;
    public $compile_check;

    var $caching = null;

    var $legacy_init_done = false;

    public function __set($name, $value)
    {
        if ($this->wrapper_version == 'S5') {
            switch ($name) {
                case 'left_delimiter':
                    $this->setLeftDelimiter($value);
                    return;
                case 'right_delimiter':
                    $this->setRightDelimiter($value);
                    return;
                case 'template_dir':
                    $this->setTemplateDir($value);
                    return;
                case 'compile_dir':
                    $this->setCompileDir($value);
                    return;
                case 'config_dir':
                    $this->setConfigDir($value);
                    return;
                case 'cache_dir':
                    $this->setCacheDir($value);
                    return;
                case 'plugins_dir':
                    $this->setPluginsDir($value);
                    return;
            }
        }
        $this->$name = $value;
    }

    public function __get($name)
    {
        if ($this->wrapper_version == 'S5') {
            switch ($name) {
                case 'left_delimiter':
                    return $this->getLeftDelimiter();
                case 'right_delimiter':
                    return $this->getRightDelimiter();
                case 'template_dir':
                    return $this->getTemplateDir();
                case 'compile_dir':
                    return $this->getCompileDir();
                case 'config_dir':
                    return $this->getConfigDir();
                case 'cache_dir':
                    return $this->getCacheDir();
                case 'plugins_dir':
                    return $this->getPluginsDir();
            }
        }
        return $this->$name;
    }

    public function __construct(array $options = array())
    {

        $version = $this->getVersion($this);
        if (version_compare($version, '5', '>=')) {
            parent::__construct();
            $this->wrapper_version = 'S5';

            if (method_exists($this, 'muteUndefinedOrNullWarnings')) {
                $this->muteUndefinedOrNullWarnings();
            }

        } elseif (version_compare($version, '4', '>=')) {
            parent::__construct();
            $this->wrapper_version = 'S4';
            if (method_exists($this, 'muteUndefinedOrNullWarnings')) {
                $this->muteUndefinedOrNullWarnings();
            }

        } elseif (version_compare($version, '3.1.31', '>=')) {
            parent::__construct();
            $this->wrapper_version = 'S313';

        } elseif ((float)$version >= 3.1) {
            parent::__construct($options);
            // version 3.1
            $this->wrapper_version = 'S31';
        } elseif ((float)$version >= 3 && (float)$version < 3.1) {
            // not supported
            echo "Smarty 3.0 is not supported";
            mh_exit();

        } else {

            if (method_exists($this, 'Smarty')) {
                $this->Smarty();
            } else {
                parent::__construct();
            }

            $this->wrapper_version = 'S26';
        }
        $this->setErrorReporting(E_ALL & ~E_NOTICE & ~E_WARNING);

        $this->setCaching(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CACHING'));
        $this->setCompileDir(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR'));
        $this->setTemplateDir(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_TEMPLATE_DIR'));
        $this->setConfigDir(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CONFIG_DIR'));
        $this->setCacheDir(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CACHE_DIR'));
        $this->setCompileCheck(true);
        $this->load_plugins();

        // handle strange errors on estugo / hostkraft servern
        switch (MH_PLATFORM) {
            case 'xtc':
            case 'gambio':
                if ($this->wrapper_version != 'S26' && $this->wrapper_version != 'S4' && $this->wrapper_version != 'S5') {
                    if (method_exists($this, 'muteExpectedErrors')) {
                        $this->muteExpectedErrors();
                    }
                }
                break;
        }


        return $this;
    }

    static function getVersion($smarty_obj)
    {

        if (class_exists('Smarty') && defined('Smarty::SMARTY_VERSION')) {
            // smarty 3.1.x
            $version_string = self::SMARTY_VERSION;
        } else {
            // smarty 2.x, 3.0
            $version_string = $smarty_obj->_version;
        }

        return str_replace('Smarty-', '', $version_string);
    }


    #[\ReturnTypeWillChange]
    function setCacheDir($cacheDir)
    {
        if ($cacheDir === null) {
            return $this;
        }

        if ($this->wrapper_version == 'S26') {
            $this->cache_dir = $cacheDir;
            return $this;
        } else {
            return parent::setCacheDir($cacheDir);
        }
    }


    #[\ReturnTypeWillChange]
    function setConfigDir($configDir)
    {
        if ($configDir === null) {
            return $this;
        }

        if ($this->wrapper_version == 'S26') {
            $this->config_dir = $configDir;
            return $this;
        } else {
            return parent::setConfigDir($configDir);
        }
    }

    #[\ReturnTypeWillChange]
    function getConfigDir($index = null)
    {
        if ($this->wrapper_version == 'S26') {
            return $this->config_dir;
        } else {
            return parent::getConfigDir($index);
        }
    }

    #[\ReturnTypeWillChange]
    function getConfigVars($index = null, $searchParents = true)
    {
        if ($this->wrapper_version == 'S26') {
            return $this->get_config_vars($index);
        } elseif ($this->wrapper_version == 'S5') {
            return parent::getConfigVars($index);
        } else {
            return parent::getConfigVars($index, $searchParents);
        }
    }

    #[\ReturnTypeWillChange]
    function configLoad($config_file, $sections = null, $scope = null)
    {
        if ($this->wrapper_version == 'S26') {
            parent::config_load($config_file, $sections, $scope);
            return true;
        } elseif ($this->wrapper_version == 'S5') {
            parent::configLoad($config_file, $sections);
            return true;
        } else {
            return parent::configLoad($config_file, $sections, $scope);
        }
    }


    #[\ReturnTypeWillChange]
    function setCompileDir($compileDir)
    {
        if ($compileDir === null) {
            return $this;
        }

        if ($this->wrapper_version == 'S26') {
            $this->compile_dir = $compileDir;
            return $this;
        } else {
            return parent::setCompileDir($compileDir);
        }
    }


    #[\ReturnTypeWillChange]
    function getCompileDir($index = null)
    {
        if ($this->wrapper_version == 'S26') {
            return $this->compile_dir;
        } else {
            return parent::getCompileDir();
        }
    }


    #[\ReturnTypeWillChange]
    function setCaching($caching)
    {
        if ($caching === null) {
            return $this;
        }

        $this->caching = $caching;
        return $this;
    }


    #[\ReturnTypeWillChange]
    function getCaching()
    {
        return $this->caching;
    }


    #[\ReturnTypeWillChange]
    function setTemplateDir($templateDir, $isConfig = false)
    {
        if ($templateDir === null) {
            return $this;
        }

        if ($this->wrapper_version == 'S26') {
            $this->template_dir = $templateDir;
            return $this;
        } else {
            return parent::setTemplateDir($templateDir, $isConfig);
        }
    }


    #[\ReturnTypeWillChange]
    function getTemplateDir($index = null, $isConfig = false)
    {
        if ($this->wrapper_version == 'S26') {
            return $this->template_dir;
        } else {
            return parent::getTemplateDir($index, $isConfig);
        }
    }


    #[\ReturnTypeWillChange]
    function setCompileCheck($compile_check)
    {
        if ($compile_check === null) {
            return $this;
        }
        $this->compile_check = $compile_check;
        return $this;
    }


    function getCompileCheck(): int
    {
        return (int)$this->compile_check;
    }

    #[\ReturnTypeWillChange]
    function setCompileId($compile_id)
    {
        if ($compile_id === null) {
            return $this;
        }
        $this->compile_id = $compile_id;
        return $this;
    }

    #[\ReturnTypeWillChange]
    function getCompileId()
    {
        return $this->compile_id;
    }


    #[\ReturnTypeWillChange]
    function templateExists($template)
    {
        if ($this->wrapper_version == 'S26') {
            return parent::template_exists($template);
        } else {
            return parent::templateExists($template);
        }
    }


    function mh_getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
    {
        if ($this->wrapper_version == 'S26') {
            return parent::get_template_vars($varname);
        } else {
            return parent::getTemplateVars($varname, $_ptr, $search_parents);
        }
    }

    function mh_setLanguage($language)
    {
        list($smarty_config_dir) = $this->getConfigDir();
        if (stream_resolve_include_path($smarty_config_dir . $language . '.conf')) {
            $this->assign('language', $language);
        } else {
            $this->assign('language', 'english');
        }
    }


    #[\ReturnTypeWillChange]
    function assign($tpl_var, $value = null, $nocache = false, $scope = null)
    {
//        $this->init_legacy_attributes();
        if ($this->wrapper_version == 'S5') {
            return parent::assign($tpl_var, $value, $nocache, $scope);
        }
        return parent::assign($tpl_var, $value, $nocache);
    }


    #[\ReturnTypeWillChange]
    function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
    {
        $this->init_legacy_attributes();
        if (mh_cfg('MH_PLATFORM_GAMBIO_GX_CONFIGURATION')) {
            foreach ($this->getTemplateVars() as $templateVar => $templateVarValue) {
                $templateVarString = $this->getTemplateVars($templateVar);
                if (is_string($templateVarString)) {
                    if (stristr($templateVarString, '$smarty.const.')) {
                        $pattern = preg_quote('$smarty.const.') . '([0-9A-Za-z_]+)';
                        if (preg_match("/$pattern/", $templateVarString, $match)) {
                            $term = $match[0];
                            $constName = $match[1];
                            $templateVarString = str_replace('{' . $term . '}', '{mh_cfg key="' . $constName . '" default=""}', $templateVarString);
                            $templateVarString = str_replace($term, '{mh_cfg key="' . $constName . '" default=""}', $templateVarString);
                            $this->assign($templateVar, $templateVarString);
                        }
                    }
                }
            }
        }

        if ($this->wrapper_version == 'S5') {
            return parent::fetch($template, $cache_id, $compile_id);
        }
        if ($this->wrapper_version == 'S26') {
            return parent::fetch($template, $cache_id, $compile_id, $parent, $display, $merge_tpl_vars, $no_output_filter);
        }
        return parent::fetch($template, $cache_id, $compile_id, $parent);
    }


    /**
     * @param string $string
     * @param bool $auto_literal
     * @return string
     */
    public function fetchString($string, $auto_literal = true)
    {
        if ($auto_literal && function_exists('mh_smarty_auto_literal')) {
            $string = mh_smarty_auto_literal($string, $this->left_delimiter, $this->right_delimiter);
        }
        $this->assign('template_source', $string);
        return $this->fetch('eval:' . '{eval var=$template_source}');


        // @todo: check if still necessary
        // Gambio /inc/get_usermod.inc.php not compatible with string resource type
        // workaround
        /*
        if (MH_PLATFORM_GAMBIO >= 2.3) {
            $smarty_obj->setCompileId('process_v');
            $smarty_obj->setCaching(false);
            $smarty_obj->assign('template_source', mh_smarty_auto_literal($template_code, $smarty_obj->getLeftDelimiter(), $smarty_obj->getRightDelimiter()));
            $output = $smarty_obj->fetch(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/admin_application_plugins/templates/smarty_eval.tpl');
        }
        */

    }


    function init_legacy_attributes()
    {
        if (!$this->legacy_init_done) {
            $this->setCaching($this->caching);
            $this->setTemplateDir($this->template_dir);
            $this->setCompileDir($this->compile_dir);
            $this->setConfigDir($this->config_dir);
            $this->setCompileCheck($this->compile_check);
            $this->setCompileId($this->compile_id);
//            $this->legacy_init_done = true;
        }
        return true;
    }


    function load_plugins()
    {
        $mhPluginDir = array();
        $mhPluginDir[] = MH_DIR_CONFIG . 'config_editor/smarty_plugins/';
        $mhPluginDir[] = MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/functions/smarty_plugins/';

        if ($this->wrapper_version == 'S26') {
            foreach ($mhPluginDir as $pDir) {
                $this->plugins_dir[] = $pDir;
            }
        } elseif ($this->wrapper_version == 'S5') {
            foreach ($mhPluginDir as $pDir) {
                if (is_dir($pDir)) {
                    $handler = opendir($pDir);
                    while (false !== ($file = readdir($handler))) {
                        if (preg_match('/^(function|modifier|block)\.(.*)\.php$/', $file, $match)) {
                            $type = $match[1];
                            $name = $match[2];
                            if (!isset($this->registered_plugins[$type][$name])) {
                                require_once($pDir . $file);
                                $this->registerPlugin($type, $name, 'smarty_' . $type . '_' . $name);
                            }
                            if ($type == 'function' && !isset($this->registered_plugins['modifier'][$name]) && function_exists($name)) {
                                $this->registerPlugin('modifier', $name, $name);
                            }
                        }
                    }
                    closedir($handler);
                }
            }
        } else {
            foreach ($mhPluginDir as $pDir) {
                $this->addPluginsDir($pDir);
            }
        }
        return true;
    }

    #[\ReturnTypeWillChange]
    function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
    {
        if ($this->wrapper_version == 'S26') {
            $this->clear_compiled_tpl();
            return $this;
        } else {
            return parent::clearCompiledTemplate($resource_name, $compile_id, $exp_time);
        }
    }


    #[\ReturnTypeWillChange]
    public function setLeftDelimiter($left_delimiter)
    {
        if (method_exists(get_parent_class($this), 'setLeftDelimiter')) {
            return parent::setLeftDelimiter($left_delimiter);
        }
        $this->left_delimiter = $left_delimiter;
    }


    #[\ReturnTypeWillChange]
    public function setRightDelimiter($right_delimiter)
    {
        if (method_exists(get_parent_class($this), 'setRightDelimiter')) {
            return parent::setRightDelimiter($right_delimiter);
        }
        $this->right_delimiter = $right_delimiter;
    }


    public function mh_fetch($template)
    {

        // default template to avoid overwrite
        if (mh_smarty_template_exists($this, $template . '.tpl.html')) {
            $real_template = $template;
        } elseif (mh_smarty_template_exists($this, 'default_' . $template . '.tpl.html')) {
            $real_template = 'default_' . $template;
        } else {

            list($dir) = $this->getTemplateDir();
            return "template <b>$dir - $template</b> not found";
        }

        $output = $this->fetch($real_template . '.tpl.html');
        return $output;
    }

    #[\ReturnTypeWillChange]
    public function setErrorReporting($error_reporting)
    {
        if (method_exists(get_parent_class($this), 'setErrorReporting')) {
            return parent::setErrorReporting($error_reporting);
        }
        return null;
    }

}


