File: /var/www/html/wp-content/plugins/content-egg/application/WooIntegrator.php
<?php
namespace ContentEgg\application;
defined('\ABSPATH') || exit;
use ContentEgg\application\components\ContentManager;
use ContentEgg\application\components\FeaturedImage;
use ContentEgg\application\helpers\TextHelper;
use ContentEgg\application\helpers\CurrencyHelper;
use ContentEgg\application\admin\GeneralConfig;
use ContentEgg\application\components\ModuleManager;
use ContentEgg\application\helpers\TemplateHelper;
use ContentEgg\application\components\ContentProduct;
use ContentEgg\application\Translator;
/**
* WooIntegrator class file
*
* @author keywordrush.com <support@keywordrush.com>
* @link https://www.keywordrush.com
* @copyright Copyright © 2025 keywordrush.com
*/
class WooIntegrator
{
const META_WOO_SYNC_MODULE_UNIQUE_ID = '_cegg_woo_sync_muid';
private static $attributes_list;
public static function initAction()
{
if (!class_exists('\WooCommerce'))
return;
\add_action('woocommerce_before_single_product', array(__CLASS__, 'touchEmptyPost'), 10);
\add_action('content_egg_save_data', array(__CLASS__, 'wooHandler'), 13, 4);
if (GeneralConfig::getInstance()->option('woocommerce_echo_update_date'))
\add_action('woocommerce_single_product_summary', array(__CLASS__, 'echoUpdateDate'), 25);
if (GeneralConfig::getInstance()->option('woocommerce_echo_price_per_unit'))
\add_action('woocommerce_single_product_summary', array(__CLASS__, 'echoPricePerUnit'), 20);
if (GeneralConfig::getInstance()->option('outofstock_woo') == 'hide_price')
\add_filter('woocommerce_get_price_html', array(__CLASS__, 'hideOutOfStockPrice'), 10, 2);
if (GeneralConfig::getInstance()->option('woocommerce_btn_text'))
{
\add_filter('woocommerce_product_single_add_to_cart_text', array(__CLASS__, 'customButtonText'), 10, 2);
\add_filter('woocommerce_product_add_to_cart_text', array(__CLASS__, 'customButtonText'), 10, 2);
}
if (GeneralConfig::getInstance()->option('woocommerce_shortcode_single'))
{
\add_action('woocommerce_single_product_summary', array(__CLASS__, 'addShortcodeSingle'), 20);
}
if (GeneralConfig::getInstance()->option('woocommerce_shortcode_archive'))
{
\add_action('woocommerce_after_shop_loop_item', array(__CLASS__, 'addShortcodeArchive'), 20);
}
}
public static function touchEmptyPost()
{
global $post;
if (!$post->post_content)
$post->post_content = apply_filters('the_content', $post->post_content);
}
public static function wooHandler($data, $module_id, $post_id, $is_last_iteration)
{
if (!$is_last_iteration)
return;
if (\get_post_type($post_id) != 'product' || !$product = \wc_get_product($post_id))
return;
// Get all post data
$affiliate_modules = ModuleManager::getInstance()->getAffiliteModulesList(true);
$modules_data = array();
foreach ($affiliate_modules as $module_id => $module_name)
{
if (!$data = ContentManager::getViewData($module_id, $post_id))
continue;
$modules_data[$module_id] = $data;
}
// Check for Manual sync
$is_product_sync = false;
$is_attr_sync = false;
foreach ($modules_data as $module_id => $data)
{
foreach ($data as $item)
{
if (!$is_product_sync && !empty($item['woo_sync']) && filter_var($item['woo_sync'], FILTER_VALIDATE_BOOLEAN))
{
self::wooSync($item, $module_id, $post_id);
$is_product_sync = true;
}
if (!$is_attr_sync && !empty($item['woo_attr']) && filter_var($item['woo_attr'], FILTER_VALIDATE_BOOLEAN))
{
self::wooCreateAttr($item, $module_id, $post_id);
$is_attr_sync == true;
}
if ($is_product_sync && $is_attr_sync)
return;
}
}
if ($is_product_sync)
return;
/**
* Automatic sync
*/
$woocommerce_product_sync = GeneralConfig::getInstance()->option('woocommerce_product_sync');
$woocommerce_modules = GeneralConfig::getInstance()->option('woocommerce_modules');
if (!$woocommerce_modules || $woocommerce_product_sync == 'manually')
return;
$modules_data = array_intersect_key($modules_data, $woocommerce_modules);
if ($item = ContentManager::getMainProduct($modules_data, $woocommerce_product_sync))
{
self::wooSync($item, $item['module_id'], $post_id);
// also sync attr if not exist
if (!$product->get_attributes() && GeneralConfig::getInstance()->option('woocommerce_attributes_sync'))
self::wooCreateAttr($item, $item['module_id'], $post_id);
}
}
public static function wooSync(array $item, $module_id, $post_id)
{
if (!$product = \wc_get_product($post_id))
return false;
$item = \apply_filters('cegg_before_woo_sync', $item, $module_id, $post_id);
// set price
if (!empty($item['price']))
{
$currency_rate = 1;
$woo_currency = \get_woocommerce_currency();
if ($item['currencyCode'] && $item['currencyCode'] != $woo_currency)
{
$currency_rate = CurrencyHelper::getCurrencyRate($item['currencyCode'], $woo_currency);
if (!$currency_rate)
$currency_rate = 1;
}
$product->set_price($item['price'] * $currency_rate);
if ($item['priceOld'])
{
if (\apply_filters('cegg_dont_sync_sale_price', false))
{
$product->set_regular_price($item['price'] * $currency_rate);
}
else
{
if (!\apply_filters('cegg_dont_touch_retail_price', false))
$product->set_regular_price($item['priceOld'] * $currency_rate);
if (!\apply_filters('cegg_dont_touch_sale_price', false))
$product->set_sale_price($item['price'] * $currency_rate);
}
}
else
{
if ($product->get_regular_price() && \apply_filters('cegg_dont_touch_retail_price', false))
{
$product->set_sale_price($item['price'] * $currency_rate);
}
else
{
$product->set_regular_price($item['price'] * $currency_rate);
if (!\apply_filters('cegg_dont_touch_sale_price', false))
$product->set_sale_price(null);
}
}
}
else
{
$product->set_price(null);
$product->set_regular_price(null);
$product->set_sale_price(null);
}
// External products cannot be stock managed.
if ($product->get_type() == 'simple' && isset($item['stock_status']))
{
if ($item['stock_status'] == ContentProduct::STOCK_STATUS_OUT_OF_STOCK)
$product->set_stock_status('outofstock');
else
$product->set_stock_status('instock');
}
$sync_description = GeneralConfig::getInstance()->option('woocommerce_sync_description');
if ($item['description'] && $sync_description && !\apply_filters('cegg_disable_description_sync', false))
{
if ($sync_description == 'full' && !$product->get_description() && \apply_filters('cegg_sync_full_description', true))
$product->set_description($item['description']);
elseif ($sync_description == 'short' && !$product->get_short_description() && !\apply_filters('cegg_dont_touch_short_description', false))
$product->set_short_description($item['description']);
}
if (empty($item['short_description']) && !\apply_filters('cegg_auto_short_description', false))
{
$item['short_description'] = TextHelper::trimExcerpt($item['description']);
}
if (!empty($item['short_description']) && $sync_description == 'full' && !\apply_filters('cegg_dont_touch_short_description', false))
{
$product->set_short_description($item['short_description']);
}
$product->set_date_modified(time());
// image
FeaturedImage::doAction($post_id, $item);
GalleryScheduler::maybeSchedulePendingImages($post_id, $item);
if ($product->get_type() == 'external' && \apply_filters('cegg_sync_woo_url_allowed', true))
{
$product->set_product_url($item['url']);
}
// brand taxonomy (Rehub feature)
if (self::isRehubTheme())
{
$sync_brand = GeneralConfig::getInstance()->option('sync_brand');
if ($sync_brand == 'brand' && \apply_filters('cegg_sync_brand', true) && $item['manufacturer'])
\wp_set_object_terms($post_id, \sanitize_text_field($item['manufacturer']), 'store', true);
elseif ($sync_brand == 'store' && \apply_filters('cegg_sync_store', true) && $item['domain'])
\wp_set_object_terms($post_id, \sanitize_text_field($item['domain']), 'store', true);
}
// Map manufacturer or store to the WooCommerce product_brand taxonomy
$syncWooBrand = GeneralConfig::getInstance()->option('sync_woo_brand');
if (in_array($syncWooBrand, ['brand', 'store'], true))
{
$termValue = '';
if ('brand' === $syncWooBrand && ! empty($item['manufacturer']))
{
$termValue = $item['manufacturer'];
}
elseif ('store' === $syncWooBrand && ! empty($item['domain']))
{
$termValue = $item['domain'];
}
if ($termValue)
{
$sanitizedTerm = sanitize_text_field($termValue);
wp_set_object_terms($post_id, $sanitizedTerm, 'product_brand', true);
}
}
if (isset($item['stock_status']))
{
$outofstock_woo = GeneralConfig::getInstance()->option('outofstock_woo');
if ($item['stock_status'] == ContentProduct::STOCK_STATUS_OUT_OF_STOCK && $outofstock_woo == 'hide_product')
$product->set_catalog_visibility('hidden');
elseif ($outofstock_woo == 'hide_product')
$product->set_catalog_visibility('visible');
}
// update meta
self::setMetaSyncUniqueId($post_id, $module_id, $item['unique_id']);
$res = $product->save();
if (GeneralConfig::getInstance()->option('sync_ean') == 'enabled' && self::isEanForWoocommerceActive())
{
$field = \apply_filters('cegg_alg_ean_field', '_alg_ean');
if (!empty($item['ean']))
\update_post_meta($post_id, $field, $item['ean']);
else
\delete_post_meta($post_id, $field);
}
if (GeneralConfig::getInstance()->option('sync_isbn') == 'enabled' && self::isEanForWoocommerceActive())
{
$field = \apply_filters('cegg_alg_isbn_field', '_alg_isbn');
if (!empty($item['isbn']))
\update_post_meta($post_id, $field, $item['isbn']);
else
\delete_post_meta($post_id, $field);
}
if (isset($item['stock_status']) && $item['stock_status'] == ContentProduct::STOCK_STATUS_OUT_OF_STOCK && $outofstock_woo == 'move_to_trash')
{
\wp_trash_post($product->get_id());
}
return $res;
}
public static function wooCreateAttr(array $item, $module_id, $post_id)
{
if (empty($item['features']) || !is_array($item['features']))
return;
if (!$product = \wc_get_product($post_id))
return false;
$attributes = $product->get_attributes();
$registered_taxonomy_count = 0;
$taxonomy_count = 0;
foreach ($item['features'] as $feature)
{
$feature['name'] = \wc_clean($feature['name']);
if (!\apply_filters('cegg_disable_attributes_modification', false))
{
$prepared = self::modifyAttribute($feature['name'], $feature['value']);
$feature['name'] = $prepared['name'];
$feature['value'] = $prepared['value'];
}
$f_name = \wc_clean($feature['name']);
$f_slug = self::getSlug($f_name);
// exists?
if (isset($attributes[$f_slug]) || isset($attributes['pa_' . $f_slug]))
continue;
$f_value = \wc_sanitize_term_text_based($feature['value']);
$term_ids = array();
$taxonomy = '';
$prepared = self::isTaxonomyAttribute($f_name, $f_value, $f_slug);
if ($prepared)
{
$taxonomy_count++;
$f_name = \wc_clean($prepared['name']);
// Taxonomy Attribute
// @see: class-wc-admin-attributes.php -> process_add_attribute()
$attr_data = array(
'attribute_label' => $f_name,
'attribute_name' => $f_slug,
'attribute_type' => 'text',
);
$attr_id = self::createTaxonomyAttribute($attr_data);
if ($attr_id)
{
$taxonomy = \wc_attribute_taxonomy_name_by_id($attr_id);
// Register the taxonomy now so that the import works!
if (!\taxonomy_exists($taxonomy))
{
$taxonomy = TextHelper::truncate($taxonomy, 32, '', 'UTF-8', true);
\register_taxonomy(
$taxonomy,
apply_filters('woocommerce_taxonomy_objects_' . $taxonomy, array('product')),
apply_filters('woocommerce_taxonomy_args_' . $taxonomy, array(
'hierarchical' => true,
'show_ui' => false,
'query_var' => true,
'rewrite' => false,
))
);
$registered_taxonomy_count++;
}
$f_value_array = self::value2Array($f_value);
// Creates the term and taxonomy relationship if it doesn't already exist.
// It may be confusing but the returned array consists of term_taxonomy_ids instead of term_ids.
\wp_set_object_terms($product->get_id(), $f_value_array, $taxonomy);
$term_ids = array();
foreach ($f_value_array as $term)
{
if ($term_info = \term_exists($term, $taxonomy))
{
if (is_array($term_info) && isset($term_info['term_id']))
$term_ids[] = $term_info['term_id'];
}
}
$term_ids = array_map('intval', $term_ids);
}
else
$attr_id = 0;
}
else
{
// Local Attribute
$attr_id = 0;
$f_value_array = self::value2Array($f_value);
}
$attribute = new \WC_Product_Attribute();
$attribute->set_id($attr_id); // 0 for product level attributes. ID for global attributes.
if ($taxonomy)
$attribute->set_name($taxonomy);
else
$attribute->set_name($f_name);
// attribute value or array of term ids/names.
if ($term_ids)
$attribute->set_options($term_ids);
else
$attribute->set_options($f_value_array);
$attribute->set_visible(true); // If visible on frontend.
$attributes[] = $attribute;
}
$product->set_attributes($attributes);
$res = $product->save();
if ($taxonomy_count)
\flush_rewrite_rules();
return $res;
}
public static function createTaxonomyAttribute($attribute)
{
global $wpdb;
if (empty($attribute['attribute_label']))
return false;
$attribute['attribute_label'] = \wc_clean($attribute['attribute_label']);
if (empty($attribute['attribute_name']))
$attribute['attribute_name'] = \wc_sanitize_taxonomy_name($attribute['attribute_label']);
if (empty($attribute['attribute_type']))
$attribute['attribute_type'] = 'text';
if (empty($attribute['attribute_orderby']))
$attribute['attribute_orderby'] = 'menu_order';
// validate slug
if (strlen($attribute['attribute_name']) >= 28 || \wc_check_if_attribute_name_is_reserved($attribute['attribute_name']))
return false;
if (\taxonomy_exists(\wc_attribute_taxonomy_name($attribute['attribute_name'])))
return \wc_attribute_taxonomy_id_by_name($attribute['attribute_name']);
// Create the taxonomy
$insert = $wpdb->insert($wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute);
if (\is_wp_error($insert))
return false;
$id = $wpdb->insert_id;
//\do_action('woocommerce_attribute_added', $id, $attribute);
\wp_schedule_single_event(time(), 'woocommerce_flush_rewrite_rules');
\delete_transient('wc_attribute_taxonomies');
return $id;
}
public static function getAttributesList()
{
if (self::$attributes_list === null)
{
$attributes_list = GeneralConfig::getInstance()->option('woocommerce_attributes_list');
$attributes_list = explode(',', $attributes_list);
$attributes_list = array_map('trim', $attributes_list);
$attributes_list = array_map('mb_strtolower', $attributes_list);
$attributes_list = array_filter($attributes_list);
self::$attributes_list = $attributes_list;
}
return self::$attributes_list;
}
public static function modifyAttribute($name, $value, $slug = '')
{
$ignore_names = array('model', 'wifi', 'version');
foreach ($ignore_names as $in)
{
if (mb_stristr($name, $in, true, 'utf-8') !== false)
return array('name' => $name, 'value' => $value);
}
/**
* Modifiers
*/
// 16 M; 8 GB; 1.5 GB; 8MP; 30 fps; 2 m; 0.5600 kg; 6,37 кг
if (preg_match('/^([0-9]*[.,]?[0-9]+)[\s+]?([\p{L}]+)$/u', $value, $matches))
{
$name = $name . ' (' . $matches[2] . ')';
$value = $matches[1];
}
return array('name' => $name, 'value' => $value);
}
public static function value2Array($value)
{
// arrays
$list = preg_split('/[,|;\/]\s/', $value);
$list = array_map('trim', $list);
$list = array_map('\wc_sanitize_term_text_based', $list);
return $list;
}
public static function isTaxonomyAttribute($name, $value, $slug = '')
{
/**
* Black / white list filter
*/
$attributes_filter = GeneralConfig::getInstance()->option('woocommerce_attributes_filter');
if ($attributes_filter)
{
if (in_array(mb_strtolower($name, 'utf-8'), self::getAttributesList()) || ($slug && in_array($slug, self::getAttributesList())))
$in_list = true;
else
$in_list = false;
if ($attributes_filter == 'whitelist' && $in_list)
return array('name' => $name, 'value' => $value);
elseif ($attributes_filter == 'blacklist' && !$in_list)
return array('name' => $name, 'value' => $value);
else
return false;
}
/**
* Default filter
*/
// ignore names
$ignore_names = array('depth', 'height', 'weight', 'package', 'model', 'pack of', 'warranty', 'title', 'of items', 'ean', 'department', 'dimensions', 'network type');
foreach ($ignore_names as $in)
{
if (mb_stristr($name, $in, true, 'utf-8') !== false)
return false;
}
if (strstr($name, '(') && strstr($name, ')') && is_numeric($value))
{
return array('name' => $name, 'value' => $value);
}
// Yes/No/0/1
$yes_array = array('yes');
foreach ($yes_array as $yes)
{
if (mb_strtolower($value, 'utf-8') == $yes)
return array('name' => $name, 'value' => ucfirst($value));
}
$no_array = array('no', '0', '-');
foreach ($no_array as $no)
{
if (mb_strtolower($value, 'utf-8') == $no)
return false;
}
// arrays
$list = preg_split('/[,|;\/]\s/', $value);
if (count($list) > 1 && count($list) <= 5)
{
foreach ($list as $l)
{
if (mb_strlen($l, 'utf-8') > 20)
return false;
}
return array('name' => $name, 'value' => $value);
}
// short string value
if (mb_strlen($value, 'utf-8') < 20)
return array('name' => $name, 'value' => $value);
return false;
}
public static function getSlug($name)
{
// already exists?
$taxonomies = \wc_get_attribute_taxonomies();
foreach ($taxonomies as $taxonomie)
{
if ($taxonomie->attribute_label == $name)
return $taxonomie->attribute_name;
}
$slug = strtolower(TextHelper::sluggable($name));
if (strlen($slug) >= 28)
$slug = substr($slug, 0, 27);
$slug = \wc_sanitize_taxonomy_name($slug);
return $slug;
}
public static function setMetaSyncUniqueId($post_id, $module_id, $unique_id)
{
if (!$unique_id)
\delete_post_meta($post_id, self::META_WOO_SYNC_MODULE_UNIQUE_ID);
else
\update_post_meta($post_id, self::META_WOO_SYNC_MODULE_UNIQUE_ID, $module_id . '[&]' . $unique_id);
}
public static function getMetaSyncUniqueId($post_id)
{
return \get_post_meta($post_id, self::META_WOO_SYNC_MODULE_UNIQUE_ID, true);
}
public static function getSyncItem($post_id)
{
if (!$muids = self::getMetaSyncUniqueId($post_id))
return null;
$ids = explode('[&]', $muids);
if (count($ids) != 2)
return null;
$module_id = $ids[0];
$unique_id = $ids[1];
$item = ContentManager::getProductbyUniqueId($unique_id, $module_id, $post_id);
if ($item)
$item['module_id'] = $module_id;
return $item;
}
public static function echoUpdateDate()
{
global $post;
if (!$echo_update_date = GeneralConfig::getInstance()->option('woocommerce_echo_update_date'))
return;
if (\is_product() && $post->ID)
{
if (!$item = self::getSyncItem($post->ID))
return;
if ($echo_update_date == 'amazon' && ($item['module_id'] != 'Amazon' && !strstr($item['module_id'], 'AE__amazon')))
return;
if (empty($item['last_update']))
return;
$date = TemplateHelper::dateFormatFromGmt($item['last_update'], true);
echo '<span class="price_updated">';
echo esc_html(sprintf(Translator::__('Last updated on %s'), $date));
echo '</span>';
}
}
public static function echoPricePerUnit()
{
global $post;
if (!$woocommerce_echo_price_per_unit = GeneralConfig::getInstance()->option('woocommerce_echo_price_per_unit'))
return;
if (\is_product() && $post->ID)
{
if (!$item = self::getSyncItem($post->ID))
return;
if (empty($item['extra']['pricePerUnitDisplay']))
return;
echo '<div class="cegg_price_per_unit">';
echo esc_html(sprintf(Translator::__('Price per unit: %s'), $item['extra']['pricePerUnitDisplay']));
echo '</div>';
}
}
public static function customButtonText($default, $product)
{
if ($product->get_type() != 'external')
return $default;
if (!$item = self::getSyncItem($product->get_id()))
return $default;
return TemplateHelper::btnText('woocommerce_btn_text', $default, false, $item);
}
public static function isRehubTheme()
{
return (in_array(basename(\get_template_directory()), array('rehub', 'rehub-theme'))) ? true : false;
}
public static function isEanForWoocommerceActive()
{
$active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
if (
in_array('ean-for-woocommerce/ean-for-woocommerce.php', $active_plugins)
|| in_array('ean-for-woocommerce-pro/ean-for-woocommerce-pro.php', $active_plugins)
)
return true;
else
return false;
}
public static function hideOutOfStockPrice($price, $that)
{
global $post;
if (\is_product() && $post->ID)
{
if (!$item = self::getSyncItem($post->ID))
return $price;
if (isset($item['stock_status']) && $item['stock_status'] == ContentProduct::STOCK_STATUS_OUT_OF_STOCK)
return '';
}
return $price;
}
public static function addShortcodeSingle()
{
if (!$shortcode = GeneralConfig::getInstance()->option('woocommerce_shortcode_single'))
return;
echo \do_shortcode($shortcode);
}
public static function addShortcodeArchive()
{
if (!$shortcode = GeneralConfig::getInstance()->option('woocommerce_shortcode_archive'))
return;
echo \do_shortcode($shortcode);
}
}