* @copyright Since 2013 Ovidiu Cimpean * @license Do not edit, modify or copy this file * * @version Release: 4 */ class NewsletterProTemplateDynamicVariables { private $html; private $user; private $variables_data; public function __construct($html, $user) { $this->html = $html; $this->user = $user; } public static function newInstance($html, $user) { return new self($html, $user); } public function render() { $this->initVariablesData(); $render = $this->html; foreach ($render as $id_lang => $html) { if (preg_match('/\{\$\w+\}/', $html)) { $current_encode = mb_detect_encoding($html, 'UTF-8, ISO-8859-1, ISO-8859-15, HTML-ENTITIES', true); // this will solve the trim last row bug in phpQuery plugin $html = html_entity_decode($html, ENT_COMPAT | ENT_HTML401 | ENT_HTML5, $current_encode); $html = mb_convert_encoding($html, 'UTF-8', $current_encode); $doc = NewsletterProphpQuery::newDocumentHTML($html); $dom_products = pq_newsletterpro('.newsletter-pro-product'); // this part is not required on the send email process but at the moment is working $dom_body = pq_newsletterpro('body'); $dom_container = pq_newsletterpro('.newsletter-pro-container'); if (count($dom_container) > 0 && count($dom_body) > 0) { $style = $dom_container->attr('style'); $exp = explode(';', $style); $gr = preg_grep('/background-color|background/', $exp); if (count($gr) > 0) { $bg = trim($gr[key($gr)]); $last_char = Tools::substr($bg, -1); if (';' != $last_char) { $bg .= ';'; } } if (isset($bg)) { $body_style = trim($dom_body->attr('style')); $last_char = Tools::substr($body_style, -1); if (';' != $last_char) { $body_style .= ';'; } $body_style .= $bg; $dom_body->attr('style', ltrim($body_style, ';')); } } foreach ($dom_products as $dom_product) { $id_product = (int) pq_newsletterpro($dom_product)->attr('data-id'); $html_product = pq_newsletterpro($dom_product)->html(); preg_match_all('/\{(?P\$[^}]+)\}/', $html_product, $available_vars); $variables = $this->variables($id_product, $available_vars['var'], $id_lang); // if the id_product doesn't exist in database, the template variables will become an empty string if (empty($variables) && !empty($available_vars['var'])) { $html_product_replace = preg_replace('/\{(?P\$[^}]+)\}/', '', $html_product); } else { $html_product_replace = str_replace($this->getVariablesKyes($variables), array_values($variables), $html_product); } pq_newsletterpro($dom_product)->html($html_product_replace); } $html = $doc->htmlOuter(); $html = html_entity_decode(str_replace(['%7B', '%7D', '%7C', '%2A'], ['{', '}', '|', '*'], $html)); $render[$id_lang] = $html; } } return $render; } private function variables($id_product, $available_vars, $id_lang) { $module = NewsletterPro::getInstance(); $variables = []; if (!empty($available_vars)) { if (!isset($this->variables_data)) { throw new NewsletterProTemplateDynamicVariablesException(sprintf('The variabl "%s" is not defined.', 'variables_data')); } $dinamyc_vars = []; foreach ($available_vars as $value) { $len = 250; $end = '...'; $exp_currency = explode('|', Tools::strtoupper($value)); array_shift($exp_currency); $exp_language = explode('|', Tools::strtolower($value)); array_shift($exp_language); $exp = explode('|', $value); $var = array_shift($exp); if (preg_match('/(\d+)(\(.*\))?/', implode('', $exp), $match)) { if (isset($match[1])) { $len = (int) $match[1]; } if (isset($match[2])) { $end = str_replace(['(', ')'], '', $match[2]); } } $current_currency = array_intersect($this->variables_data['currencies_iso'], $exp_currency); $dinamyc_vars[$value]['replace'] = $value; $dinamyc_vars[$value]['var'] = $var; $dinamyc_vars[$value]['id_currency'] = $this->variables_data['id_currency']; $dinamyc_vars[$value]['id_lang'] = $id_lang; if (!empty($current_currency)) { $dinamyc_vars[$value]['type'] = 'price'; $current_currency = array_values($current_currency); $iso_code = $current_currency[0]; $get_currency = array_search($iso_code, $this->variables_data['currencies_iso']); $dinamyc_vars[$value]['id_currency'] = (false !== $get_currency ? (int) $get_currency : $this->variables_data['id_currency']); $dinamyc_vars[$value]['type'] = null; } else { $dinamyc_vars[$value]['type'] = 'string'; $dinamyc_vars[$value]['trim_length'] = $len; $dinamyc_vars[$value]['trim_end'] = $end; } $current_lang = array_intersect($this->variables_data['languages_iso'], $exp_language); if (!empty($current_lang)) { $current_lang = array_values($current_lang); $iso_code = $current_lang[0]; $get_lang = array_search($iso_code, $this->variables_data['languages_iso']); $dinamyc_vars[$value]['id_lang'] = (false !== $get_lang ? (int) $get_lang : $id_lang); } } $product = $module->getProductById($id_product, $id_lang, true); if ($product && isset($product['dynamic_vars'])) { $product_lang = $this->getProductLang($id_product, $this->variables_data, $product); $variables = &$product['dynamic_vars']; $variables['$currency'] = $this->variables_data['currencies_key_ids'][$this->variables_data['id_currency']]['sign']; $variables['$price_convert'] = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $product['price'], $this->variables_data['id_currency']) : (float) $product['price'] ); $variables['$price_display'] = Tools::displayPrice((float) $variables['$price_convert'], $this->variables_data['id_currency']); $variables['$price_without_reduction'] = $product['price_without_reduction']; $variables['$price_without_reduction_convert'] = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$price_without_reduction'], (int) $this->variables_data['id_currency']) : (float) $variables['$price_without_reduction'] ); $variables['$price_without_reduction_display'] = Tools::displayPrice((float) $variables['$price_without_reduction_convert'], (int) $this->variables_data['id_currency']); $variables['$price_tax_exc'] = $product['price_tax_exc']; $variables['$price_tax_exc_convert'] = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$price_tax_exc'], (int) $this->variables_data['id_currency']) : (float) $variables['$price_tax_exc'] ); $variables['$price_tax_exc_display'] = Tools::displayPrice((float) $variables['$price_tax_exc_convert'], (int) $this->variables_data['id_currency']); $variables['$wholesale_price'] = $product['wholesale_price']; $variables['$wholesale_price_convert'] = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$wholesale_price'], (int) $this->variables_data['id_currency']) : (float) $variables['$wholesale_price'] ); $variables['$wholesale_price_display'] = Tools::displayPrice((float) $variables['$wholesale_price_convert'], (int) $this->variables_data['id_currency']); $variables['$discount'] = ''; $variables['$discount_decimals'] = ''; $variables['$reduction'] = ''; $variables['$reduction_display'] = ''; if (isset($product['specific_prices']['reduction_type'])) { $specificPrice = $product['specific_prices']; $reductionType = $specificPrice['reduction_type']; $reduction = $specificPrice['reduction']; if (pqnp_ini_config('price_convert')) { $reduction = Tools::convertPrice($reduction, (int) $this->variables_data['id_currency']); } if ('percentage' === $reductionType) { $discount = number_format(abs($reduction * 100), 0).'%'; $discount_decimals = number_format(abs($reduction * 100), $this->decimals).'%'; $reduction_amount = $product['price_without_reduction'] * $reduction; } elseif ('amount' === $reductionType) { $discount = number_format(abs((($reduction / $product['price_without_reduction']) * 100)), 0).'%'; $discount_decimals = number_format(abs((($reduction / $product['price_without_reduction']) * 100)), $this->decimals).'%'; $reduction_amount = $reduction; } $variables['$discount'] = $discount; $variables['$discount_decimals'] = $discount_decimals; $variables['$reduction'] = $reduction_amount; $variables['$reduction_display'] = Tools::displayPrice($reduction_amount); } $decimal = 2; foreach ($dinamyc_vars as $replace => $settings) { $target = $settings['var']; switch ($target) { case '$currency': $variables[$replace] = $this->variables_data['currencies_key_ids'][$settings['id_currency']]['sign']; break; case '$price_convert': $variables[$replace] = number_format( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $product['price'], $settings['id_currency']) : (float) $product['price'], $decimal ); break; case '$price_display': $price_convert = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $product['price'], $settings['id_currency']) : (float) $product['price'] ); $variables[$replace] = Tools::displayPrice((float) $price_convert, $settings['id_currency']); break; case '$price_without_reduction_convert': $variables[$replace] = number_format( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$price_without_reduction'], (int) $settings['id_currency']) : (float) $variables['$price_without_reduction'], $decimal ); break; case '$price_without_reduction_display': $price_without_reduction_convert = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$price_without_reduction'], (int) $settings['id_currency']) : (float) $variables['$price_without_reduction'] ); $variables[$replace] = Tools::displayPrice((float) $price_without_reduction_convert, (int) $settings['id_currency']); break; case '$price_tax_exc_convert': $variables[$replace] = number_format( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$price_tax_exc'], (int) $settings['id_currency']) : (float) $variables['$price_tax_exc'], $decimal ); break; case '$price_tax_exc_display': $price_tax_exc_convert = Tools::convertPrice((float) $variables['$price_tax_exc'], (int) $settings['id_currency']); $variables[$replace] = Tools::displayPrice((float) $price_tax_exc_convert, (int) $settings['id_currency']); break; case '$wholesale_price_convert': $variables[$replace] = number_format( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$wholesale_price'], (int) $settings['id_currency']) : (float) $variables['$wholesale_price'], $decimal ); break; case '$wholesale_price_display': $wholesale_price_convert = ( pqnp_ini_config('price_convert') ? Tools::convertPrice((float) $variables['$wholesale_price'], (int) $settings['id_currency']) : (float) $variables['$wholesale_price'] ); $variables[$replace] = Tools::displayPrice((float) $wholesale_price_convert, (int) $settings['id_currency']); break; case '$name': $this->setVariablesString($replace, 'name', $variables, $product_lang, $settings); break; case '$description': $this->setVariablesString($replace, 'description', $variables, $product_lang, $settings); break; case '$description_short': $this->setVariablesString($replace, 'description_short', $variables, $product_lang, $settings); break; case '$manufacturer_name': $this->setVariablesString($replace, 'manufacturer_name', $variables, $product_lang, $settings); break; default: break; } } } } return $variables; } private function initVariablesData() { $module = NewsletterPro::getInstance(); $context = Context::getContext(); $id_currency = (int) pqnp_config('CURRENCY'); $id_lang = (int) pqnp_config('LANG'); $id_shop = (int) $context->shop->id; if (property_exists($context, 'customer') && isset($context->customer) && $context->customer) { if (property_exists($context->customer, 'id_lang') && isset($this->customer->id_lang)) { $id_lang = (int) $context->customer->id_lang; } else { $c_id_lang = $module->getCustomerIdLang($context->customer->id); if ($c_id_lang) { $id_lang = $c_id_lang; } } $id_shop = (int) $context->customer->id_shop; } // override the id lang $id_lang = (int) $this->user->id_lang; // override the id shop $id_shop = (int) $this->user->id_shop; $currencies = NewsletterPro::getCurrenciesByIdShop($context->shop->id); $currencies_iso = []; $currencies_key_ids = []; foreach ($currencies as $currency) { $currencies_iso[$currency['id_currency']] = $currency['iso_code']; $currencies_key_ids[$currency['id_currency']] = $currency; } $languages = Language::getLanguages(false); $languages_iso = []; $languages_key_ids = []; foreach ($languages as $language) { $languages_iso[$language['id_lang']] = $language['iso_code']; $languages_key_ids[$language['id_lang']] = $language; } $this->variables_data = [ 'id_currency' => $id_currency, 'id_shop' => $id_shop, 'currencies' => $currencies, 'currencies_iso' => $currencies_iso, 'currencies_key_ids' => $currencies_key_ids, 'languages' => $languages, 'languages_iso' => $languages_iso, 'languages_key_ids' => $languages_key_ids, ]; return $this; } private function getProductLang($id_product, $product) { $product_db_lang = Db::getInstance()->executeS(' SELECT p.`id_product`, pl.`id_lang`, pl.`name`, pl.`description`, pl.`description_short`, m.`name` AS manufacturer_name FROM `'._DB_PREFIX_.'product` p LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product`) LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (p.`id_manufacturer` = m.`id_manufacturer`) WHERE p.`id_product` = '.(int) $id_product.' AND pl.`id_shop` = '.(int) $this->variables_data['id_shop'].' '); $product_lang = []; if (!empty($product_db_lang)) { foreach ($product_db_lang as $pl) { $product_lang[$pl['id_lang']] = $pl; } } else { foreach ($this->variables_data['languages_key_ids'] as $pl) { $product_lang[$pl['id_lang']] = [ 'name' => $product['name'], 'description' => $product['description'], 'description_short' => $product['description_short'], 'manufacturer_name' => $product['manufacturer_name'], ]; } } return $product_lang; } private function getVariablesKyes($variables) { $result = []; foreach (array_keys($variables) as $var_name) { $result[] = '{'.$var_name.'}'; } return $result; } public function setVariablesString($name, $product_name, &$variables, $product_lang, $settings) { $variables[$name] = strip_tags($product_lang[$settings['id_lang']][$product_name]); if ('string' == $settings['type']) { $init_name = $variables[$name]; if (isset($settings['trim_length'])) { $variables[$name] = Tools::substr($variables[$name], 0, $settings['trim_length']); } if (Tools::strlen($init_name) >= $settings['trim_length']) { $variables[$name] = $variables[$name].$settings['trim_end']; } } } }