/** * Render_Product Init * * @version 1.0.1 * @package 'datalayer' */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! class_exists( 'Render_Product' ) ) : class Render_Product { /** * Product impressions (shop, category, tag, search, etc.) */ public static function mount_measuring_product_impressions_data_layer( array $products ) { $data_layer = array(); /* ----------------------------------------------------------------- * 1. UA – impressions (legacy) * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ua() ) { $impressions = array(); $count = 1; foreach ( $products as $product ) { $venarticle = self::get_venarticle( $product ); $category = self::get_first_category( $product ); $list = self::get_current_list_name(); $impressions[] = array( 'name' => $product->get_name(), 'id' => $product->get_sku(), // <-- SKU for UA 'venarticle' => $venarticle, // <-- custom for Emarsys 'sku' => $product->get_sku(), 'price' => $product->get_price(), 'category' => $category, 'list' => $list, 'position' => $count, ); $count++; } $data_layer = array( 'ecommerce' => array( 'currencyCode' => get_option( 'woocommerce_currency' ), 'impressions' => $impressions, ), ); } /* ----------------------------------------------------------------- * 2. GA4 – view_item_list * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ga4() ) { $impressions = array(); $count = 1; foreach ( $products as $product ) { $venarticle = self::get_venarticle( $product ); $category = self::get_first_category( $product ); $list = self::get_current_list_name(); $impressions[] = array( 'item_name' => $product->get_name(), 'item_id' => $product->get_sku(), // <-- SKU for GA4 'item_venarticle' => $venarticle, // <-- Emarsys 'price' => $product->get_price(), 'item_category' => $category, 'item_list_name' => $list, 'index' => $count, ); $count++; } $currency = get_option( 'woocommerce_currency' ); $data_layer = array( 'event' => 'view_item_list', 'event_id' => Controller_Data_Layer::generate_event_id_datalayer(), 'ecommerce' => array( 'currency' => $currency, 'items' => $impressions, ), ); } Controller_Data_Layer::push_to_data_layer( $data_layer ); } /** * Product detail page + related products */ public static function mount_measuring_views_of_product_details_data_layer( $product, $products_related ) { $data_layer = array(); /* ----------------------------------------------------------------- * 1. UA – detail + related impressions * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ua() ) { $category = self::get_first_category( $product ); // ---- Related products (impressions) ---- $impressions = array(); $count = 1; foreach ( $products_related as $related ) { $venarticle = self::get_venarticle( $related ); $cat = self::get_first_category( $related ); $impressions[] = array( 'name' => $related->get_name(), 'id' => $related->get_sku(), // SKU 'venarticle' => $venarticle, // Emarsys 'sku' => $related->get_sku(), 'price' => $related->get_price(), 'category' => $cat, 'list' => 'Related Products', 'position' => $count, ); $count++; } $data_layer = array( 'ecommerce' => array( 'currencyCode' => get_option( 'woocommerce_currency' ), 'impressions' => $impressions, 'detail' => array( 'products' => array( 'name' => $product->get_name(), 'id' => $product->get_id(), // detail uses internal ID (UA spec) 'sku' => $product->get_sku(), 'price' => $product->get_price(), 'category' => $category, ), ), ), ); } /* ----------------------------------------------------------------- * 2. GA4 – view_item (detail only) * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ga4() ) { $category = self::get_first_category( $product ); $data_layer = array( 'event' => 'view_item', 'event_id' => Controller_Data_Layer::generate_event_id_datalayer(), 'ecommerce' => array( 'currency' => get_option( 'woocommerce_currency' ), 'items' => array( array( 'item_name' => $product->get_name(), 'item_id' => $product->get_id(), // GA4 detail uses internal ID 'price' => $product->get_price(), 'item_category' => $category, ), ), ), ); } Controller_Data_Layer::push_to_data_layer( $data_layer ); } /** * Add-to-cart (non-AJAX) */ public static function mount_adding_a_product_to_a_shopping_cart_data_layer_without_ajax( $cart_item_data, $product_id, $variation_id, $quantity ) { $product = wc_get_product( $product_id ); $category = self::get_first_category( $product ); $venarticle = self::get_venarticle( $product ); $data_layer = array(); /* ----------------------------------------------------------------- * 1. UA – addToCart * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ua() ) { $variant = ''; if ( $product->is_type( 'variable' ) ) { $variant_obj = new WC_Product_Variation( $variation_id ); $attrs = $variant_obj->get_attributes(); foreach ( $attrs as $key => $val ) { if ( 'pa_color' === $key ) { $variant = $val; break; } } } $data_layer = array( 'event' => 'addToCart', 'event_id' => Controller_Data_Layer::generate_event_id_datalayer(), 'ecommerce' => array( 'currencyCode' => get_option( 'woocommerce_currency' ), 'add' => array( 'actionField' => array( 'list' => 'Product Detail' ), 'products' => array( 'name' => $product->get_name(), 'id' => $product->get_sku(), // SKU 'venarticle' => $venarticle, // Emarsys 'sku' => $product->get_sku(), 'price' => $product->get_price(), 'category' => $category, 'variant' => $variant, 'quantity' => $quantity, ), ), ), ); } /* ----------------------------------------------------------------- * 2. GA4 – add_to_cart * ----------------------------------------------------------------- */ if ( Controller_Data_Layer::is_data_layer_ga4() ) { $variant = ''; if ( $product->is_type( 'variable' ) ) { $variant_obj = new WC_Product_Variation( $variation_id ); $attrs = $variant_obj->get_attributes(); foreach ( $attrs as $key => $val ) { if ( 'pa_color' === $key ) { $variant = $val; break; } } } $data_layer = array( 'event' => 'add_to_cart', 'event_id' => Controller_Data_Layer::generate_event_id_datalayer(), 'ecommerce' => array( 'currency' => get_option( 'woocommerce_currency' ), 'items' => array( 'item_name' => $product->get_name(), 'item_id' => $product->get_sku(), // SKU 'item_venarticle' => $venarticle, // Emarsys 'price' => $product->get_price(), 'item_category' => $category, 'item_variant' => $variant, 'item_list_name' => 'Product Detail', 'index' => 1, 'quantity' => $quantity, ), ), ); } Controller_Data_Layer::push_to_data_layer( $data_layer ); } /* ----------------------------------------------------------------- * Helper methods – keep code DRY * ----------------------------------------------------------------- */ private static function get_venarticle( $product ) { $ven = get_post_meta( $product->get_id(), '_venarticle', true ); return ( $ven === 'Array' || is_array( $ven ) ) ? '' : $ven; } private static function get_first_category( $product ) { $ids = $product->get_category_ids(); return ! empty( $ids ) ? get_the_category_by_ID( $ids[0] ) : ''; } private static function get_current_list_name() { if ( is_shop() ) return 'Main Shop'; if ( is_search() ) return 'Search'; if ( is_product_category() ) { $term = get_queried_object(); return $term ? $term->name : 'Category'; } if ( is_product_tag() ) { $term = get_queried_object(); return $term ? $term->name : 'Tag'; } return 'Unknown List'; } } endif; /* ----------------------------------------------------------------- * LIST META – merged from your functions.php snippet * ----------------------------------------------------------------- */ add_action( 'wp_head', function() { if ( ! ( is_shop() || is_product_category() || is_product_tag() || is_front_page() ) ) { return; } $list_id = 'unknown'; $list_name = 'Unknown List'; if ( is_shop() ) { $list_id = 'shop'; $list_name = 'Main Shop'; } elseif ( is_product_category() ) { $term = get_queried_object(); $list_id = 'category-' . $term->slug; $list_name = $term->name; } elseif ( is_product_tag() ) { $term = get_queried_object(); $list_id = 'tag-' . $term->slug; $list_name = $term->name; } elseif ( is_front_page() ) { global $post; if ( $post && has_shortcode( $post->post_content, 'fusion_woo_featured_products_slider' ) ) { $list_id = 'homepage-featured'; $list_name = 'Featured Products'; } else { $list_id = 'homepage'; $list_name = 'Homepage'; } } $GLOBALS['tf_item_list_meta'] = [ 'item_list_id' => $list_id, 'item_list_name' => $list_name, ]; }, 5 ); add_filter( 'wc_datalayer_view_item_list_payload', function( $payload ) { if ( empty( $GLOBALS['tf_item_list_meta'] ) ) { return $payload; } $meta = $GLOBALS['tf_item_list_meta']; // GA4 – add top-level + per-item fields if ( isset( $payload['ecommerce']['items'] ) ) { $payload['ecommerce']['item_list_id'] = $meta['item_list_id']; $payload['ecommerce']['item_list_name'] = $meta['item_list_name']; foreach ( $payload['ecommerce']['items'] as &$item ) { $item['item_list_id'] = $meta['item_list_id']; $item['item_list_name'] = $meta['item_list_name']; } unset( $item ); } return $payload; } ); https://dischemlivingfit.co.za/post-sitemap1.xml 2025-11-12T14:57:13+00:00 https://dischemlivingfit.co.za/post-sitemap2.xml 2025-11-03T09:06:31+00:00 https://dischemlivingfit.co.za/post-sitemap3.xml 2025-11-03T08:00:31+00:00 https://dischemlivingfit.co.za/post-sitemap4.xml 2025-11-03T07:53:55+00:00 https://dischemlivingfit.co.za/post-sitemap5.xml 2025-11-03T07:53:02+00:00 https://dischemlivingfit.co.za/post-sitemap6.xml 2025-10-03T07:00:31+00:00 https://dischemlivingfit.co.za/page-sitemap.xml 2025-11-10T08:06:48+00:00 https://dischemlivingfit.co.za/product-sitemap1.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product-sitemap2.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product-sitemap3.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product-sitemap4.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product-sitemap5.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product-sitemap6.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/avada_portfolio-sitemap.xml 2025-01-17T13:26:51+00:00 https://dischemlivingfit.co.za/category-sitemap.xml 2025-11-12T14:57:13+00:00 https://dischemlivingfit.co.za/product_cat-sitemap.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/product_tag-sitemap.xml 2025-11-13T13:52:04+00:00 https://dischemlivingfit.co.za/portfolio_category-sitemap.xml 2025-01-17T13:26:51+00:00