<?php

/*
  MailBeez Automatic Trigger Email Campaigns
  http://www.mailbeez.com

  Copyright (c) 2010, 2011 MailBeez

  inspired and in parts based on
  Copyright (c) 2003 osCommerce

  Released under the GNU General Public License

  v2.9.4

  template functions
 */

///////////////////////////////////////////////////////////////////////////////
///																																					 //
///                 MailBeez Core file - do not edit                         //
///                                                                          //
///////////////////////////////////////////////////////////////////////////////
// path to smarty library


require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/class.html2text.php');
mh_define('MH_TEMPLATE_ENGINE_LOGFILE', MH_DIR_FS_LOGS . 'template_engine_failed.log');


if (!class_exists('Smarty')) {
    if (mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_SMARTY_PATH')) {
        require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/' . mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_SMARTY_PATH') . '/Smarty.class.php'); // include smarty
    } else {
        //trigger_error("configuration error - Smarty not found", E_USER_ERROR);
    }
}

mh_define('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CACHING', false);
mh_define('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_TEMPLATE_DIR', MH_DIR_FS_CATALOG . 'mailhive');
mh_define('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR', MH_DIR_FS_WORK);
mh_define('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CACHE_DIR', MH_DIR_FS_CACHE);
mh_define('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_CONFIG_DIR', '');


function mh_template_check_writeable()
{
    $test_folder = mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR');
    $test_file = 'template_c_write_test.txt';
    if (!file_exists($test_folder . $test_file)) {
        @chmod($test_folder, 0777);
        @touch($test_folder . $test_file);
        @chmod($test_folder, 0755);
        if (!file_exists($test_folder . $test_file)) {
            return false;
        }
    }

    return is_writable($test_folder . $test_file);
}

function mh_template_convert($text, $replace_variables)
{
    // deprec
    return $text;
    // make old template compatible with smarty
    /*
    if (is_array($replace_variables)) {
        uksort($replace_variables, "sortbykeylength");
        foreach ($replace_variables as $key => $value) {
            $text = str_replace('$' . $key, $value, $text);
        }
    }
    return $text;
    */
}

function mh_template_bypass_smarty($text, $replace_variables, $left = '{', $right = '}')
{
    // make old template compatible with smarty
    if (is_array($replace_variables)) {
        uksort($replace_variables, "sortbykeylength");
        foreach ($replace_variables as $key => $value) {
            $text = str_replace($left . '$' . $key . $right, $value ?? '', $text);
        }
    }
    return $text;
}

function mh_template_parse_css_tags($text, $replace_variables, $del = array('left' => '[##', 'right' => '##]'))
{
    // replace e.g. [##$catalog_server##] in css
    if (is_array($replace_variables)) {
        uksort($replace_variables, "sortbykeylength");
        foreach ($replace_variables as $key => $value) {

            if (is_array($value)) {
                continue;
            }



            $replace = $del['left'] . '$' . $key . $del['right'];


            $text = str_replace(
                $replace,
                $value ?? '',
                $text
            );


        }
    }


    // remove empty css tags
    $text = str_replace((string)$del['left'] . (string)$del['right'], '', $text);

    return $text;
}

function mh_smarty_compile_dir_info()
{
    if ($dir = @opendir(MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR)) {
        $c_counter = 0;
        while (false !== ($c_file = readdir($dir))) {
            $c_counter++;
        }
        closedir($dir);
    }
    $c_counter -= 2; // in order to exclude '.' and '..'
    $c_counter = ($c_counter < 0) ? 0 : $c_counter;
    return $c_counter;
}

function mh_smarty_template_exists($smarty, $template)
{
    $smarty_version = mh_smarty_get_version($smarty);

    $templ_exists = false;


    // keep for backwards compatiblity
    if (method_exists($smarty, 'templateExists')) {
        $templ_exists = $smarty->templateExists($template);
    } else {
        die("smarty compatibility issue in mh_smarty_template_exists()");
    }

    /*
    if ($smarty_version == 2) {
        $templ_exists = $smarty->template_exists($template);
    } elseif ($smarty_version == 3) {
        $templ_exists = $smarty->templateExists($template);
    }

    */


    return $templ_exists;
}


function mh_smarty_clear_compile_dir()
{
    if ($dir = @opendir(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR'))) {
        while (false !== ($c_file = readdir($dir))) {
            if (preg_match('/.php/', $c_file)) {
                //if (preg_match('/.tpl.php/', $c_file)) {
                if (is_file(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR') . $c_file)) {
                    @unlink(mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMPILE_DIR') . $c_file);
                }
            }
        }
        closedir($dir);
    }
}

/*
function _dprec_mh_smarty_get_template($template_resource, &$tpl_source, &$smarty_obj)
{
    // populating $tpl_source
    $tmpl_res = 'mh_' . $template_resource;
    $tpl_source = $smarty_obj->$tmpl_res;

    return true;
}

function _dprec_mh_smarty_get_timestamp($template_resource, &$tpl_timestamp, &$smarty_obj)
{
    $tmpl_res = 'mh_' . $template_resource . '_mtime';
    $tpl_timestamp = $smarty_obj->$tmpl_res;
    return true;
}

function _dprec_mh_smarty_get_secure($tpl_name, &$smarty_obj)
{
    // assume all templates are secure
    return true;
}

function _dprec_mh_smarty_get_trusted($tpl_name, &$smarty_obj)
{
    // not used for templates
}


function _dprec_mh_smarty_register_resource(&$smarty_obj)
{
    $smarty_version = mh_smarty_get_version($smarty_obj);

    // smarty 2
    if ($smarty_version == 2) {
        $smarty_obj->register_resource("mh", array("mh_smarty_get_template",
            "mh_smarty_get_timestamp",
            "mh_smarty_get_secure",
            "mh_smarty_get_trusted"));
    } elseif ($smarty_version == 3) {
        if (class_exists('Smarty_Resource_Custom')) {
        } else {
            // smarty 3.0.5
            $smarty_obj->registerResource("mh", array("mh_smarty_get_template",
                "mh_smarty_get_timestamp",
                "mh_smarty_get_secure",
                "mh_smarty_get_trusted"));
        }
    }
}
*/


function mh_smarty_get_version($smarty_obj)
{
    if (defined('Smarty::SMARTY_VERSION')) {
        // smarty 3.1.x, 4.x
        $version_string = Smarty::SMARTY_VERSION;
    } elseif (class_exists('\\Smarty\\Smarty') && defined('\\Smarty\\Smarty::SMARTY_VERSION')) {
        // smarty 5.x
        $version_string = \Smarty\Smarty::SMARTY_VERSION;
    } else {
        // smarty 2.x, 3.0
        $version_string = isset($smarty_obj->_version) ? $smarty_obj->_version : 'unknown';
    }
    return (int)str_replace('Smarty-', '', $version_string);
}

function mh_smarty_process($smarty, $template_code)
{
    $smarty_obj = $smarty;
    $smarty_version = mh_smarty_get_version($smarty_obj);

    if ($smarty_version == 3 && class_exists('Smarty_Resource_Custom')) {
        // smarty 3.1

        // 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');
        } else {
            $output = $smarty_obj->fetch('string:' . mh_smarty_auto_literal($template_code, $smarty_obj->getLeftDelimiter(), $smarty_obj->getRightDelimiter()));
        }

    } else {
        // smarty 2 + 3.0
        if (method_exists($smarty_obj, 'setCompileId')) {
            // smarty 3
            $smarty_obj->setCompileId('process_v');
            $smarty_obj->setCaching(false);
        } else {
            $smarty_obj->compile_id = 'process_v';
            $smarty_obj->caching = 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');
    }

    return $output;
}

function mh_smarty_fetch($smarty, $resource, $smarty_tmpl_holder = null)
{
    $smarty_obj = $smarty;
    $resource_name = 'mh_' . $resource;

    if ($smarty_tmpl_holder != null && !trim((string)$smarty_tmpl_holder->$resource_name)) {
        return '';
    }

    /*
    $debug = ob_get_contents();
    ob_end_clean();
    echo "### $debug ###";
    */
    // backwards compatiblity for calls w/o $smarty_tmpl_holder
    if ($smarty_tmpl_holder == null) {

        if (method_exists($smarty_obj, 'setCompileId')) {
            // smarty 3
            $smarty_obj->setCompileId($resource_name . '_v');
            $smarty_obj->setCaching(false);
        } else {
            $smarty_obj->compile_id = $resource_name . '_v';
            $smarty_obj->caching = false;
        }
        $smarty_obj->assign('template_source', mh_smarty_auto_literal($smarty->$resource_name, $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');
        mh_check_template_data($output, 'mh_smarty_fetch 1');

        return $output;
    }

    $smarty_version = mh_smarty_get_version($smarty_obj);
    if ($smarty_version >= 4) {
        // smarty 4, 5
        // Gambio /inc/get_usermod.inc.php not compatible with string resource type
        // workaround
        if ((float)MH_PLATFORM_GAMBIO >= 2.3) {
            $smarty_obj->setCompileId($resource_name . '_v');
            $smarty_obj->setCaching(false);
            $smarty_obj->assign('template_source', mh_smarty_fix(mh_smarty_auto_literal($smarty_tmpl_holder->$resource_name, $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');

        } else {
            $output = $smarty_obj->fetch('string:' . $smarty_tmpl_holder->$resource_name);
        }
        mh_check_template_data($output, 'mh_smarty_fetch 2: ' . $resource_name . '|' . $smarty_tmpl_holder->$resource_name . '|' . (is_object($smarty_obj) ? get_class($smarty_obj) : 'not an object'));
        return $output;

    } else if ($smarty_version == 3 && class_exists('Smarty_Resource_Custom')) {
        // smarty 3.1
        // Gambio /inc/get_usermod.inc.php not compatible with string resource type
        // workaround
        if ((float)MH_PLATFORM_GAMBIO >= 2.3) {
            $smarty_obj->setCompileId($resource_name . '_v');
            $smarty_obj->setCaching(false);
            $smarty_obj->assign('template_source', mh_smarty_auto_literal($smarty_tmpl_holder->$resource_name, $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');

        } else {
            $output = $smarty_obj->fetch('string:' . $smarty_tmpl_holder->$resource_name);
        }
        mh_check_template_data($output, 'mh_smarty_fetch 2: ' . $resource_name . '|' . $smarty_tmpl_holder->$resource_name . '|' . print_r($smarty_obj, true));
        return $output;

    } else {
        // smarty 2 + 3.0
        foreach ($smarty_tmpl_holder as $key => $value) {
            $smarty_obj->$key = $value;
        }
        if (method_exists($smarty_obj, 'setCompileId')) {
            // smarty 3
            $smarty_obj->setCompileId($resource_name . '_v');
            $smarty_obj->setCaching(false);
        } else {
            $smarty_obj->compile_id = $resource_name . '_v';
            $smarty_obj->caching = false;
        }

        $smarty_obj->assign('template_source', mh_smarty_auto_literal($smarty_tmpl_holder->$resource_name, $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');

        mh_check_template_data($output, 'mh_smarty_fetch 3: ' . $resource_name . '|' . $smarty_tmpl_holder->$resource_name);
        return $output;
    }
}

function mh_smarty_generate_mail($obj, $mail, $mailbeez_module_path, $smarty, $strip_editor_codes = true, $preparse_template_codes = true)
{

    $smarty_generate = $smarty; // make a copy
    $smarty_generate->assign('shared_dir', MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'configbeez/config_editor/template_library/body/basic/shared/');

    $replace_variables_common = $GLOBALS['mh_template_replace_variables_common'];
    $smarty_version = mh_smarty_get_version($smarty_generate);

    $output_content_html = '';
    $output_content_txt = '';

    if ($obj->mailBee->is_preview) {
        $smarty_generate->compile_id = $smarty_generate->compile_id . $obj->mailBee->htmlTemplateResource;
    }
    if ($obj->mailBee->template_control) {
        $smarty_generate->compile_id .= 'tc-' . $mail['_iteration'];
    }


    //
    if (!$obj->mailBee->template_control) {
        list($obj,) = mhpi('template_engine_1', $obj, $mail); // -> magic_11
    }

    if ($smarty_version == 2) {
        $viewTemplateMode = $smarty_generate->get_template_vars('viewTemplate'); // smarty 2
        $stripTemplateEditorVarCodes = $smarty_generate->get_template_vars('stripTemplateEditorVarCodes'); // smarty 2
        $stripMainTemplateEditorCodes = $smarty_generate->get_template_vars('stripMainTemplateEditorCodes'); // smarty 2
        $stripEditorVarCodes = $smarty_generate->get_template_vars('stripEditorVarCodes'); // smarty 2
    } elseif ($smarty_version >= 3) {
        $viewTemplateMode = $smarty_generate->getTemplateVars('viewTemplate'); // smarty 3+
        $stripTemplateEditorVarCodes = $smarty_generate->getTemplateVars('stripTemplateEditorVarCodes'); // smarty 3+
        $stripMainTemplateEditorCodes = $smarty_generate->getTemplateVars('stripMainTemplateEditorCodes'); // smarty 3+
        $stripEditorVarCodes = $smarty_generate->getTemplateVars('stripEditorVarCodes'); // smarty 3+
    }
    $viewTemplateMode = ($viewTemplateMode == '') ? false : $viewTemplateMode;
    $stripTemplateEditorVarCodes = ($stripTemplateEditorVarCodes == '') ? false : $stripTemplateEditorVarCodes;
    $stripMainTemplateEditorCodes = ($stripMainTemplateEditorCodes == '') ? false : $stripMainTemplateEditorCodes;
    $stripEditorVarCodes = ($stripEditorVarCodes == '') ? false : $stripEditorVarCodes;

//    error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_STRICT & ~E_WARN);
//    error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_STRICT & ~E_WARN);
    ini_set('display_errors', 1);

    // put templates in object
    $smarty_tmpl_holder = new stdClass();
    $smarty_tmpl_holder->mh_subjectTemplate = $obj->mailBee->subjectTemplate;
    $smarty_tmpl_holder->mh_subjectTemplate_mtime = $obj->mailBee->subjectTemplate_mtime;
    $smarty_tmpl_holder->mh_preheaderTemplate = $obj->mailBee->preheaderTemplate;
    $smarty_tmpl_holder->mh_preheaderTemplate_mtime = $obj->mailBee->preheaderTemplate_mtime;
    $smarty_tmpl_holder->mh_htmlTemplate = $obj->mailBee->htmlTemplate;
    $smarty_tmpl_holder->mh_htmlTemplate_mtime = $obj->mailBee->htmlTemplate_mtime;
    $smarty_tmpl_holder->mh_txtTemplate = $obj->mailBee->txtTemplate;
    $smarty_tmpl_holder->mh_txtTemplate_mtime = $obj->mailBee->txtTemplate_mtime;
    $smarty_tmpl_holder->mh_htmlBodyTemplate = $obj->mailBee->htmlBodyTemplate;
    $smarty_tmpl_holder->mh_htmlBodyTemplate_mtime = $obj->mailBee->htmlBodyTemplate_mtime;
    $smarty_tmpl_holder->mh_txtBodyTemplate = $obj->mailBee->txtBodyTemplate;
    $smarty_tmpl_holder->mh_txtBodyTemplate_mtime = $obj->mailBee->txtBodyTemplate_mtime;


    $smarty_tmpl_holder->mh_htmlBodyTemplate = mh_preparser($smarty_tmpl_holder->mh_htmlBodyTemplate);
    $smarty_tmpl_holder->mh_htmlTemplate = mh_preparser($smarty_tmpl_holder->mh_htmlTemplate);

    // remove literal tags and add them automatically
    // use [[literal]] .. [[/literal]] for manual setting of literal tags
    $smarty_tmpl_holder->mh_subjectTemplate = mh_smarty_auto_literal($smarty_tmpl_holder->mh_subjectTemplate, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
    $smarty_tmpl_holder->mh_htmlTemplate = mh_smarty_auto_literal($smarty_tmpl_holder->mh_htmlTemplate, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
    $smarty_tmpl_holder->mh_htmlBodyTemplate = mh_smarty_auto_literal($smarty_tmpl_holder->mh_htmlBodyTemplate, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
    $smarty_tmpl_holder->mh_txtTemplate = mh_smarty_auto_literal($smarty_tmpl_holder->mh_txtTemplate, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
    $smarty_tmpl_holder->mh_txtBodyTemplate = mh_smarty_auto_literal($smarty_tmpl_holder->mh_txtBodyTemplate, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());


    if ($strip_editor_codes) {
        $smarty_tmpl_holder->mh_htmlTemplate_mtime = $smarty_tmpl_holder->mh_htmlTemplate_mtime * 2;
        $smarty_tmpl_holder->mh_htmlTemplate = $obj->mailbeez_editor->strip_editor_codes($smarty_tmpl_holder->mh_htmlTemplate);
        $smarty_tmpl_holder->mh_htmlBodyTemplate_mtime = $smarty_tmpl_holder->mh_htmlBodyTemplate_mtime * 2;
        $smarty_tmpl_holder->mh_htmlBodyTemplate = $obj->mailbeez_editor->strip_editor_codes($smarty_tmpl_holder->mh_htmlBodyTemplate);
    }

    if ($stripTemplateEditorVarCodes) {
        $smarty_tmpl_holder->mh_htmlBodyTemplate_mtime = $smarty_tmpl_holder->mh_htmlBodyTemplate_mtime * 2;
        $smarty_tmpl_holder->mh_htmlBodyTemplate = $obj->mailbeez_editor->strip_editor_var_codes($smarty_tmpl_holder->mh_htmlBodyTemplate);
    }

    if ($stripMainTemplateEditorCodes) {
        $smarty_tmpl_holder->mh_htmlTemplate_mtime = $smarty_tmpl_holder->mh_htmlTemplate_mtime * 2;
        $smarty_tmpl_holder->mh_htmlTemplate = $obj->mailbeez_editor->strip_editor_codes($smarty_tmpl_holder->mh_htmlTemplate);
    }

    if ($stripEditorVarCodes) {
        $smarty_tmpl_holder->mh_htmlTemplate_mtime = $smarty_tmpl_holder->mh_htmlTemplate_mtime * 2;
        $smarty_tmpl_holder->mh_htmlTemplate = $obj->mailbeez_editor->strip_editor_var_codes($smarty_tmpl_holder->mh_htmlTemplate);
    }


    if (!$strip_editor_codes) {
        // mark template vars
        $smarty_tmpl_holder->mh_preheaderTemplate = $obj->mailbeez_codes->mark_editor_vars($smarty_tmpl_holder->mh_preheaderTemplate);
    }

    if (!$strip_editor_codes) {
        // mark template vars in editor view
        $smarty_tmpl_holder->mh_htmlBodyTemplate = $obj->mailbeez_codes->mark_editor_vars($smarty_tmpl_holder->mh_htmlBodyTemplate);
    }

    if ($preparse_template_codes) {
        $smarty_tmpl_holder->mh_subjectTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_subjectTemplate);
        $smarty_tmpl_holder->mh_preheaderTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_preheaderTemplate);
        $smarty_tmpl_holder->mh_htmlTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_htmlTemplate);
        $smarty_tmpl_holder->mh_htmlBodyTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_htmlBodyTemplate);
        $smarty_tmpl_holder->mh_txtTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_txtTemplate);
        $smarty_tmpl_holder->mh_txtBodyTemplate = $obj->mailbeez_codes->pre_parse($smarty_tmpl_holder->mh_txtBodyTemplate);
    }

    $smarty_generate->assign('block_url', $obj->buildBlockUrl($mail, $mailbeez_module_path)); // generate block-link

    // todo
    // convert special characters in firstname, lastname
    // or convert all elements of mai


    //$mail['firstname'] = '';
    //$mail['lastname'] = '';

    if ($obj->mailBee->noblock) {
        $smarty_generate->assign('noblock', $obj->mailBee->noblock); // override
    }

    $smarty_generate->assign($mail); // might override noblock setting
    $smarty_generate->assign('module_code', $obj->mailBee->code);
    $smarty_generate->assign($replace_variables_common);

    if (isset($obj->mailBee->styling)) {
        $smarty->assign('stylevars', $obj->mailBee->styling);
    }


    $output_subject = mh_smarty_fetch($smarty_generate, 'subjectTemplate', $smarty_tmpl_holder);
    $output_subject = mh_template_convert($output_subject, array_merge($mail, $replace_variables_common));
    $smarty_generate->assign('subject', $output_subject);
    $output_preheader = mh_smarty_fetch($smarty_generate, 'preheaderTemplate', $smarty_tmpl_holder);
    $output_preheader = mh_template_convert($output_preheader, array_merge($mail, $replace_variables_common));
    $smarty_generate->assign('preheader', $output_preheader);
    if ($viewTemplateMode) {
        $body_content_html = $smarty_tmpl_holder->mh_htmlBodyTemplate;
        $body_content_txt = $smarty_tmpl_holder->mh_txtBodyTemplate;

        // replace common variables "manually" for e.g. preview of images
        $body_content_html = mh_template_bypass_smarty($body_content_html, $replace_variables_common, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
        $body_content_txt = mh_template_bypass_smarty($body_content_txt, $replace_variables_common, $smarty_generate->getLeftDelimiter(), $smarty_generate->getRightDelimiter());
    } else {
        $body_content_html = mh_smarty_fetch($smarty_generate, 'htmlBodyTemplate', $smarty_tmpl_holder);
        $body_content_txt = mh_smarty_fetch($smarty_generate, 'txtBodyTemplate', $smarty_tmpl_holder);
        if (mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_COMP_MODE') == 'True') {
            // compatibility mode
            $body_content_html = mh_template_convert($body_content_html, array_merge($mail, $replace_variables_common));
            $body_content_txt = mh_template_convert($body_content_txt, array_merge($mail, $replace_variables_common));
        }

        if (mh_cfg('MAILBEEZ_ANALYTICS_AUTOINSERT_PIX') == 'True') {
            $body_content_html .= $GLOBALS['mh_template_replace_variables_common']['MAILBEEZ_TRACKER_PIX'];
        }
    }

    if (isset($obj->mailBee->styling)) {
        // preparse CSS Styling parameters
        $body_content_html = mh_template_parse_css_tags($body_content_html, $obj->mailBee->styling, array('left' => '/*stylevar:', 'right' => '*/'));
        $smarty_tmpl_holder->mh_htmlTemplate = mh_template_parse_css_tags($smarty_tmpl_holder->mh_htmlTemplate, $obj->mailBee->styling, array('left' => '/*stylevar:', 'right' => '*/'));
        mh_check_template_data($body_content_html, 'mh_template_parse_css_tags 2');
    }
    /*
     *
     * following some encrypted but harmless code which places the copyright line into each email
     *
     * the copyright can be removed with any Pro-Plan
     *
     * The development of MailBeez has been a lot of work
     * and you will very likely increase your revenue by using it
     *
     * It is good to give something back
     *
     * If you have good ideas for mailbeez, lets work together!
     * drop me a line at fairplay@mailbeez.com
     *
     */
    /* following some valid, functional and harmless code which is encoded to protect the module licensing. Please contact license@mailbeez.com if you have any questions */

    @eval(base64_decode(' '));
    if (file_exists(MH_DIR_CONFIG . 'config_editor/template_library/common.css.tpl')) {
        $mailbeez_common_css = file_get_contents(MH_DIR_CONFIG . 'config_editor/template_library/common.css.tpl');
        if (isset($obj->mailBee->styling)) {
            // preparse CSS Styling parameters
            $mailbeez_common_css = mh_template_parse_css_tags($mailbeez_common_css, $obj->mailBee->styling, array('left' => '/*stylevar:', 'right' => '*/'));
        }

        $mailbeez_common_css = $smarty_generate->fetchString($mailbeez_common_css, false);

    } else {
        $mailbeez_common_css = '';
    }


    mh_check_template_data($output_content_html, 'init');

    // preparse tags in CSS with [##$var##] delimiters
    $output_content_html = mh_template_parse_css_tags($output_content_html, array('MAILBEEZ_COMMON_CSS' => $mailbeez_common_css));

    // complex elements: bypass issue with smarty variables in style
    $output_content_html = mh_template_parse_css_tags($output_content_html, array(
        'STYLEBLOCK_START' => '<style type="text/css">',
//        'STYLEBLOCK_CSS_OPEN' => '{literal}{{/literal}',
//        'STYLEBLOCK_CSS_CLOSE' => '{literal}}{/literal}',
        'STYLEBLOCK_CSS_OPEN' => '{',
        'STYLEBLOCK_CSS_CLOSE' => '}',
        'STYLEBLOCK_END' => '</style>',
    ));


    mh_check_template_data($output_content_html, 'mh_template_parse_css_tags 1');


    if (isset($obj->mailBee->styling)) {
        // preparse CSS Styling parameters
        $output_content_html = mh_template_parse_css_tags($output_content_html, $obj->mailBee->styling, array('left' => '/*stylevar:', 'right' => '*/'));
        mh_check_template_data($output_content_html, 'mh_template_parse_css_tags 2');
    }

    // preparse tags in CSS with [##$var##] delimiters
    $output_content_html = mh_template_parse_css_tags($output_content_html, $replace_variables_common);

//    $output_content_html = mh_template_parse_css_tags($output_content_html, array_merge($mail, $replace_variables_common));

    // process inline styles
    // replace & with &amp; (but not &amp; with &amp;amp;)
    // to avoid DOM warnings

    mh_check_template_data($output_content_html, 'mh_template_parse_css_tags 3');


    // clean up
    $output_content_html = str_replace('pxpx', 'px', $output_content_html);

    $output_content_html = preg_replace('/&(?![A-Za-z0-9#]{1,7};)/', '&amp;', $output_content_html);

    mh_check_template_data($output_content_html, 'clean up 1');


    // thanks to markdown
    // Remove UTF-8 BOM and marker character in input, if present.
    $output_content_html = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $output_content_html);
    mh_check_template_data($output_content_html, 'clean up 2');

    // moved to the end of the email generation process
    //$output_content_html = mh_template_emogrify($output_content_html);

    $output_content_html = mh_template_outlook_helper($output_content_html);
    mh_check_template_data($output_content_html, 'mh_template_outlook_helper');


    $output_subject = strip_tags($output_subject); // remove html tags from subject

    // convert complete subject

    if (!(isset($mail['subject_plain']) && $mail['subject_plain'] == true)) {
        if (mh_cfg('MAILBEEZ_CONFIG_EMAIL_ENCODE_SUBJECT') == 'True') {
            $output_subject = mh_convert_characters_subject_utf_8($output_subject);
        }
    }


    if ($output_content_txt == '') {
        // auto generate txt version if empty
        $h2t = new html2text($output_content_html);
        $output_content_txt = $h2t->get_text();
    }

    // preserve links
    $output_content_txt = preg_replace("#<a href=\"(([a-zA-Z]+://)([a-zA-Z0-9%.;:/=+_-]*[?]+[a-zA-Z0-9&%.;:/=+_-]*))\"#", "$1" . "\n<a", $output_content_txt);


    // make sure txt version is not containing any html
    $output_content_txt = strip_tags($output_content_txt);

    // remove multiple empty lines
//    $output_content_txt = preg_replace("/[\r\n]+/", "\n", $output_content_txt);
//    $output_content_txt = preg_replace("/[\n]+/", "\n", $output_content_txt);

// playmoa - issue: empty lines
//    $output_content_txt = preg_replace('/(?:(?:\r\n|\r|\n)\s*){2}/s', "\n\n", $output_content_txt);


    // replace quotes in content
    // depending on context

    $quote_substitute = defined('mailbeez_editor::QUOTE_SUBSTITUTE')
        ? \mailbeez_editor::QUOTE_SUBSTITUTE
        : '#QUOTE#';
    if ($preparse_template_codes) {
        $output_content_html = str_replace($quote_substitute, '"', $output_content_html);
    } else {
        $output_content_html = str_replace($quote_substitute, '"&quot;"', $output_content_html);
    }

    return array($output_subject, $output_content_html, $output_content_txt, $output_preheader);
}


function mh_smarty_auto_literal($content, $left = '{', $right = '}')
{
    // remove literal
    $content = str_replace($left . 'literal' . $right, '', $content);
    $content = str_replace($left . '/literal' . $right, '', $content);

    // and insert it from scratch
    $content = preg_replace('#(<style[^>]*>)([^<]*)(</style>)#', "$1" . $left . "literal" . $right . "$2" . $left . "/literal" . $right . "$3", $content);

    // doing some fixing as well - shouldn't be here, but for now...

    // fixing ' inside smarty code
    $content = str_replace('&#39;', "'", $content);


    // fixing ' inside smarty code
    $content = str_replace('&rsquo;', "'", $content);

    // fixing " inside smarty code
    $content = str_replace('&quot;', '"', $content);


    // fixing - inside smarty code
    $content = str_replace('&ndash; ', '-', $content);

    return $content;
}

function mh_smarty_fix($content)
{
    // smarty 4 incompatibility

    $content = preg_replace('#value="\[VAR_SELECT data-source="(.*)" #', "value\"[VAR_SELECT data-source='$1'", $content);
    // $content = str_replace('value="[VAR_SELECT data-source="display_mode" ', 'value="[VAR_SELECT data-source=\'display_mode\'', $content);
    return $content;
}

function mh_template_outlook_helper($output_content_html)
{
    // outlook requires some special treatment....


    $output_content_html_input = $output_content_html;

    // find all images
    if (preg_match_all('/<img[^>]+>/ims', $output_content_html, $matches)) {
        foreach ($matches[0] as $img_match) {
            // for each image find width and heights from style attribute
            preg_match('/[^-]width[: ]+([0-9%]+)/', $img_match, $width);
            preg_match('/[^-]height[: ]+([0-9%]+)/', $img_match, $height);
            $img_match_new = $img_match;
            if (!preg_match('/(width|height)=["\'\d%\s]+/ims', $img_match)) {
                // if not set, add width and height attributes


                // unwanted effect
//                if (!$height[1]) {
//                    $height[1] = '100%';
//                }

                $img_match_new = str_replace('>', ' width="' . mh_arr_val($width, 1) . '" height="' . mh_arr_val($height, 1) . '">', $img_match);
            }
            // Replace with result within html
            $output_content_html = str_replace($img_match, $img_match_new, $output_content_html);
        }
    }
    // fix invalid html causing broken layouts in outlook e.g. width="600px" => width="600"
    $output_content_html = preg_replace('/"([0-9]+)px"/', '"$1"', $output_content_html);

    //add !important to inline style colors
    // <span style="color:#FF0000;"> -> <span style="color:#FF0000 !important;">
    // <span style="background-color:#FF0000;"> -> <span style="background-color:#FF0000 !important;">
    $output_content_html = preg_replace('/<span style="([^>]*)color:[\s]?#([0-9a-fA-F]*);(.?)">/ims', '<span style="$1color:#$2 !important;$3">', $output_content_html);


    // remove all lines with up to 10 only empty cells to avoid layout issues on some email clients
    $regex_row = '<tr[^>]*>([^>]*>[\s]*?<\/td[^<]*){0,10}<\/tr>';
    $output_content_html = preg_replace('/' . $regex_row . '/sm', '', $output_content_html);

    // remove empty lines before table tag
    $regex_table = '<td ([^>]*)>\s*?<table';
    $output_content_html = preg_replace('/' . $regex_table . '/sm', '<td $1><table', $output_content_html);

    // add <font> tag into other tags to ensure font color
    // *? non-greedy match
    $regex_font = '(<(h1|h2|h3)(?! data-rawtag=\'true\')[^>]*>)(.*?)(<\/\2>)';
    $output_content_html = preg_replace('/' . $regex_font . '/ims', '$1<font >$3</font>$4', $output_content_html);

    // outlook 120 dpi hell...
    // https://litmus.com/community/discussions/151-mystery-solved-dpi-scaling-in-outlook-2007-2013
    // https://www.emailonacid.com/blog/article/email-development/dpi_scaling_in_outlook_2007-2013

    // make sure all tables / td with fixed width have both attribute and style setting set

    // todo


    if (!function_exists('mh_fixOutlookTable')) {
        function mh_fixOutlookTable($match)
        {
            $str = $match[0];
            $str_new = $str;

            // check if style="width: 123px" or style="width: 50%"
            preg_match('/width[: ]+([0-9%]+)/', $str, $css_width);

            // check if width="123" or width="50%"
            preg_match('/width[="]+([0-9%]+)"/', $str, $attr_width);

            $css_add = '';
            $attr_add = '';
            if (sizeof($css_width) == 0 && sizeof($attr_width) > 0) {

                if (!stristr($attr_width[1], '%')) {
                    // skip for %
                    $css_add = 'width: ' . $attr_width[1] . 'px; ';
                    if (stristr($str, 'style="')) {
                        $str_new = str_replace('style="', 'style="' . $css_add, $str_new);
                    }
                };
            }
            if (sizeof($css_width) > 0 && sizeof($attr_width) == 0) {
                $attr_add = 'width="' . $css_width[1] . '" ';
                $str_new = str_replace('>', $attr_add . '>', $str_new);
            }
            return $str_new; //str_replace($str, $str_new, $str);

        }
    }

    $regex_styles = '<(table|td)[^>]+width[^>]+>';
    $output_content_html = preg_replace_callback('/' . $regex_styles . '/', 'mh_fixOutlookTable', $output_content_html);


//echo $output_content_html; mh_exit();


    // failure backup
    if (trim((string)$output_content_html) == '') {
        return $output_content_html_input;
    }

    return $output_content_html;
}

function mh_preparser($string)
{
    // fix outlook issue with content block
    // fix faulty style in content block element

    /*
    [EDIT_COMPLEX title="Content Block"

    replace:"mso-line-height-rule:exactly;line-height: 0 !important;" -> ""

    [/EDIT_COMPLEX]

    */

    preg_match_all('#\[EDIT_COMPLEX title="Content Block" (.*)\[\/EDIT_COMPLEX\]#ismU', $string, $matches, PREG_SET_ORDER);

    $replace = array();

    if (count($matches) > 0) {
        foreach ($matches as $m) {
            $s = $m[0];
            $search[] = $s;
            $r = $s;
            $r = str_replace('mso-line-height-rule:exactly;line-height: 0 !important;', '', $r);
            $r = str_replace('mso-line-height-rule: exactly; line-height: 0;', '', $r);
            $replace[] = $r;
        }
        $string = str_replace($search, $replace, $string);
    }
    return $string;
}

if (!function_exists('mh_convert_characters_subject_utf_8')) {

    function mh_convert_characters_subject_utf_8($subject)
    {
        // very painful topic ahead!!!


        // arrrgh...
        // UTF-8 encoding of subject
        // http://stackoverflow.com/questions/341708/how-to-handle-utf-8-email-headers-like-subject-using-ruby
        // http://ncona.com/2011/06/using-utf-8-characters-on-an-e-mail-subject/
        //
        // doesnt work with sending through gmail reading on thunderbird, but shows on iphone
        // seems to work

        //$subject = str_replace('&amp;', '&', $subject);
        //$subject = html_entity_decode($subject);

        //    $subject = preg_replace_callback("/(&#[0-9]+;)/", create_function('$m', 'return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");' ), $subject);
        //    $subject = preg_replace_callback("/(&#[0-9]+;)/", create_function('$m', 'html_entity_decode(mb_convert_encoding($m[1], "UTF-8", "UTF-8"), ENT_COMPAT, "UTF-8");' ), $subject);

        //    $subject = html_entity_decode(mb_convert_encoding($subject, 'UTF-8', 'UTF-8'), ENT_COMPAT, "UTF-8");

        // todo
        // automatic db encoding detection
        if (false) {
            // works at valentin for all special characters / languages
            // PHP 8 incompatible - but not used anway
            // $subject = preg_replace_callback("/(&#[0-9]+;)/", create_function('$m', 'return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES");'), $subject);
            return "=?utf-8?B?" . base64_encode($subject) . "?=";
        } else {
            // works with � ...
            return mb_encode_mimeheader($subject, 'UTF-8');
        }
    }
}


function mh_convert_characters_table()
{
    // todo
    // http://php.net/manual/en/function.get-html-translation-table.php

    $convert_array = array('ï¿€' => '&Agrave;', 'ï¿ ' => '&agrave;', 'ï¿?' => '&Aacute;', 'ï¿¡' => '&aacute;', 'ï¿‚' => '&Acirc;', 'ï¿¢' => '&acirc;', '?' => '&Atilde;', '?' => '&atilde;', 'ï¿„' => '&Auml;', 'ï¿¤' => '&auml;', 'ï¿…' => '&Aring;', 'ï¿¥' => '&aring;', 'ï¿†' => '&AElig;', 'ï¿¦' => '&aelig;', 'ï¿‡' => '&Ccedil;', 'ï¿§' => '&ccedil;', '?' => '&ETH;', '?' => '&eth;', 'ï¿ˆ' => '&Egrave;', 'ï¿¨' => '&egrave;', 'ï¿‰' => '&Eacute;', 'ï¿©' => '&eacute;', 'ï¿?' => '&Ecirc;', 'ï¿ª' => '&ecirc;', 'ï¿‹' => '&Euml;', 'ï¿«' => '&euml;', '?' => '&Igrave;', '?' => '&igrave;', 'ï¿?' => '&Iacute;', 'ï¿­' => '&iacute;', 'ï¿?' => '&Icirc;', 'ï¿®' => '&icirc;', 'ï¿?' => '&Iuml;', 'ï¿¯' => '&iuml;', 'ï¿‘' => '&Ntilde;', 'ï¿±' => '&ntilde;', '?' => '&Ograve;', '?' => '&ograve;', 'ï¿“' => '&Oacute;', 'ï¿³' => '&oacute;', 'ï¿”' => '&Ocirc;', 'ï¿´' => '&ocirc;', '?' => '&Otilde;', '?' => '&otilde;', 'ï¿–' => '&Ouml;', 'ï¿¶' => '&ouml;', 'ï¿˜' => '&Oslash;', 'ï¿¸' => '&oslash;', 'ï¾Œ' => '&OElig;', 'ï¾œ' => '&oelig;', 'ß' => '&szlig;', '?' => '&THORN;', '?' => '&thorn;', 'ï¿™' => '&Ugrave;', 'ï¿¹' => '&ugrave;', 'ï¿?' => '&Uacute;', 'ï¿º' => '&uacute;', 'ï¿›' => '&Ucirc;', 'ï¿»' => '&ucirc;', 'ï¿œ' => '&Uuml;', 'ï¿¼' => '&uuml;', '?' => '&Yacute;', '?' => '&yacute;', 'ï¾Ÿ' => '&Yuml;', 'ï¿¿' => '&yuml;');
    return $convert_array;
}

if (!function_exists('mh_convert_characters')) {

    function mh_convert_characters($content)
    {
        // purpose of this function is to replace characters with their entity fully controlled

        // todo
        // automatic db encoding detection
        if (false) {
            // works at valentin for all special characters / languages
            return $content;
        } else {
            $convert_array = mh_convert_characters_table();

            // somehow special characters get lost in the code, so lets reconstruct them from their html entity
            $convert_array_trans = array();
            foreach ($convert_array as $key => $value) {
                $convert_array_trans[html_entity_decode($value)] = $value;
            }

            $convert_values = array_values($convert_array_trans);
            $convert_keys = array_keys($convert_array_trans);
            $content = str_replace($convert_keys, $convert_values, $content);

            return $content;
        }
    }
}

function mh_check_template_data($content, $step)
{
    if (!trim((string)$content)) {

        $msg = "*****\n";
        $msg .= "empty content $content";
        $msg .= "Step:" . $step;
        $msg .= "\n";
//        echo $msg . "<br>";
        mh_template_engine_error_log($msg);
    }
}

function mh_template_engine_error_log($msg)
{
    $filename = MH_TEMPLATE_ENGINE_LOGFILE;
    $stream = fopen($filename, 'a');
    $string = "[" . date("Y/m/d h:i:s", time()) . "] " . $msg;
    fwrite($stream, $string . PHP_EOL);
    fclose($stream);
}

function mh_template_emogrify($output_content_html)
{

    // should not happen - avoid exception thrown by emogrify();
    if ($output_content_html === '') {
        return $output_content_html;
    }

    list($output_content_html, $m) = mhpi('template_engine_2', $output_content_html);
    mh_check_template_data($output_content_html, 'template_engine_2');


    if (mh_cfg('MAILBEEZ_CONFIG_TEMPLATE_ENGINE_EMOGRIFY') == 'True') {
        // engine Emogrifier
        $output_content_html = mh_convert_characters($output_content_html);
        mh_check_template_data($output_content_html, 'mh_convert_characters');

        // http://classes.verkoyen.eu/css_to_inline_styles/docs
        // require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/css_to_inline_styles.php');
        // http://www.pelagodesign.com/sidecar/emogrifier/
        require_once(MH_DIR_FS_CATALOG . MH_ROOT_PATH . 'common/classes/mailbeez_emogrifier_wrapper.php');

        $emogrifier = new mh_Emogrifier($output_content_html);
        try {

            $output_content_html = $emogrifier->emogrify();
        } catch (InvalidArgumentException $e) {
//            print_r($e); exit();
            // ignore for now...
            // todo - handle exception
        }
        $output_content_html = str_replace('</title>', "</title>\n" . $m, $output_content_html);
        mh_check_template_data($output_content_html, 'emogrifier');

        // convert style font-color to attribute for font tag
        if (preg_match_all('/<font [^>]+>/ims', $output_content_html, $matches)) {
            foreach ($matches[0] as $font_match) {
                // for each font tag find color from style attribute
                preg_match('/color: (#[a-f0-9]+)/', $font_match, $color);
                $font_match_new = $font_match;
                if (isset($color[1])) {
                    if (!preg_match('/color="#[a-f0-9]+"/ims', $font_match)) {
                        // if not set, add color attribute
                        $font_match_new = str_replace('>', ' color="' . $color[1] . '">', $font_match);
                    }
                }
                // Replace with result within html
                $output_content_html = str_replace($font_match, $font_match_new, $output_content_html);
            }
        }

    }

    // remove !important from inline styles as this breaks some cases in outlook

    if (!function_exists('mh_replaceImportant')) {
        function mh_replaceImportant($match)
        {
            return str_replace(' !important', '', $match[0]);
        }
    }

    $regex_styles = 'style="[^"]*"';
    $output_content_html = preg_replace_callback('/' . $regex_styles . '/', 'mh_replaceImportant', $output_content_html);

    /*

    if (defined('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_STATUS') && (mh_get_conf('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_STATUS') == 'True')) {

        // moved from filter_layout_optimizer
        if (defined('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_TABLEFIX') && MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_TABLEFIX == 'True') {
            $output_content_html = preg_replace('#<tr [^>]*>\s*<td [^>]*><img [^>]*></td>\s*<td>\s*(<!--\s*-->\s*)?\s*</td>\s*</tr>#', "", $output_content_html);
        }
        if (defined('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_COMMENT') && MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_COMMENT == 'True') {
            // remove empty comments
            $output_content_html = preg_replace('#\s*(<!--\s*-->\s*)\s*#', " ", $output_content_html);
            $output_content_html = preg_replace('#\s*(<!---->\s*)\s*#', " ", $output_content_html);

            // remove comments
            $output_content_html = preg_replace('#<!--[^>]*-->#', " ", $output_content_html);
        }
        if (defined('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_WRAP') && MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_WRAP == 'True') {
            $output_content_html = wordwrap($output_content_html, 76, "\n");
        }
        if (defined('MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_WRAP') && MAILBEEZ_FILTER_LAYOUT_OPTIMIZER_WS == 'True') {
            $output_content_html = preg_replace('/\s\s+/', " ", $output_content_html);
            $output_content_html = str_replace("\n\n\n", "\n", $output_content_html);
            $output_content_html = str_replace("\n\n", "\n", $output_content_html);
        }
    }

    */

    return $output_content_html;
}