From bdf8a9e302dde34aabcce93c39024b4bfde4c792 Mon Sep 17 00:00:00 2001 From: Uros Rakic Date: Mon, 14 Jul 2025 14:54:53 +0200 Subject: [PATCH 1/4] Add admin settings to exclude emails, IPs, and admin purchases from Purchase events --- includes/Admin/Settings_Screens/Shops.php | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/includes/Admin/Settings_Screens/Shops.php b/includes/Admin/Settings_Screens/Shops.php index 96ebef237..9155fc21d 100644 --- a/includes/Admin/Settings_Screens/Shops.php +++ b/includes/Admin/Settings_Screens/Shops.php @@ -354,6 +354,30 @@ public static function get_settings_with_title_static( string $title ): array { 'desc_tip' => sprintf( __( 'Only enable this if you are experiencing problems with the plugin. Learn more.', 'facebook-for-woocommerce' ), 'https://woocommerce.com/document/facebook-for-woocommerce/#debug-tools' ), 'default' => 'no', ], + + [ + 'title' => __( 'Exclude Emails from Purchase Events', 'facebook-for-woocommerce' ), + 'desc' => __( 'Comma-separated list of email addresses. Orders from these will not trigger a Facebook Purchase event.', 'facebook-for-woocommerce' ), + 'id' => 'wc_facebook_excluded_emails', + 'type' => 'text', + 'default' => '', + ], + + [ + 'title' => __( 'Exclude IPs from Purchase Events', 'facebook-for-woocommerce' ), + 'desc' => __( 'Comma-separated list of IP addresses. Orders from these will not trigger a Facebook Purchase event.', 'facebook-for-woocommerce' ), + 'id' => 'wc_facebook_excluded_ips', + 'type' => 'text', + 'default' => '', + ], + + [ + 'title' => __( 'Exclude Admin User Purchases', 'facebook-for-woocommerce' ), + 'desc' => __( 'If enabled, orders placed by admin users will not trigger a Facebook Purchase event.', 'facebook-for-woocommerce' ), + 'id' => 'wc_facebook_exclude_admin_purchases', + 'type' => 'checkbox', + 'default' => 'no', + ], ]; if ( $offer_management_enabled_by_fb ) { $settings_without_title_and_type[] = [ From 1c0fd877323214d8d0ebb1d289bfb966817e63ec Mon Sep 17 00:00:00 2001 From: Uros Rakic Date: Mon, 14 Jul 2025 15:26:50 +0200 Subject: [PATCH 2/4] Skip Facebook Purchase events for admins, excluded emails and IPs based on plugin settings --- facebook-commerce-events-tracker.php | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index d38a6558f..79ff42554 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -43,7 +43,7 @@ class WC_Facebookcommerce_EventsTracker { private $tracked_events; /** @var array array with epnding events */ - private $pending_events = []; + private $pending_events = array(); /** @var AAMSettings aam settings instance, used to filter advanced matching fields*/ private $aam_settings; @@ -860,6 +860,35 @@ public function inject_purchase_event( $order_id ) { return; } + $exclude_admin = 'yes' === get_option( 'wc_facebook_exclude_admin_purchases', 'yes' ); + + if ( $exclude_admin && $order->get_user_id() ) { + $user = get_userdata( $order->get_user_id() ); + if ( $user && in_array( 'administrator', (array) $user->roles, true ) ) { + Logger::log( "Skipping Purchase event for admin user (user ID: {$order->get_user_id()})" ); + return; + } + } + + $billing_email = strtolower( $order->get_billing_email() ); + $order_ip = $order->get_customer_ip_address(); + + $excluded_emails_raw = get_option( 'wc_facebook_excluded_emails', '' ); + $excluded_ips_raw = get_option( 'wc_facebook_excluded_ips', '' ); + + $excluded_emails = array_map( 'trim', explode( ',', strtolower( $excluded_emails_raw ) ) ); + $excluded_ips = array_map( 'trim', explode( ',', $excluded_ips_raw ) ); + + if ( in_array( $billing_email, $excluded_emails, true ) ) { + Logger::log( "Skipping Purchase event for excluded email: $billing_email" ); + return; + } + + if ( in_array( $order_ip, $excluded_ips, true ) ) { + Logger::log( "Skipping Purchase event for excluded IP: $order_ip" ); + return; + } + // Get the status of the order to ensure we track the actual purchases and not the ones that have a failed payment. $order_state = $order->get_status(); @@ -885,7 +914,7 @@ public function inject_purchase_event( $order_id ) { Logger::log( 'Purchase event fired for order ' . $order_id . ' by hook ' . $hook_name . '.', - [], + array(), array( 'should_send_log_to_meta' => false, 'should_save_log_in_woocommerce' => true, From 4bfd0d61d43ce55eacc870ad6464086bed56017d Mon Sep 17 00:00:00 2001 From: Uros Rakic Date: Tue, 15 Jul 2025 11:34:10 +0200 Subject: [PATCH 3/4] Enhance admin settings with Select2 taggable multiselect inputs for excluded emails and IPs --- assets/js/admin/enhanced-settings-sync.js | 18 +++++++++++++ facebook-commerce-events-tracker.php | 8 ++++-- includes/Admin/Settings_Screens/Shops.php | 33 +++++++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/assets/js/admin/enhanced-settings-sync.js b/assets/js/admin/enhanced-settings-sync.js index ff3381c04..f37cb83f7 100644 --- a/assets/js/admin/enhanced-settings-sync.js +++ b/assets/js/admin/enhanced-settings-sync.js @@ -139,4 +139,22 @@ jQuery(document).ready(function($) { button.prop('disabled', false); }); }); + + $('#wc_facebook_excluded_emails, #wc_facebook_excluded_ips').select2({ + tags: true, + tokenSeparators: [',', ' '], + width: 'resolve', + placeholder: 'Type and hit space or comma to add', + createTag: function(params) { + var term = $.trim(params.term); + if (term === '') { + return null; + } + return { + id: term, + text: term, + newTag: true + }; + } + }); }); diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index 79ff42554..11eb98f6b 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -876,8 +876,12 @@ public function inject_purchase_event( $order_id ) { $excluded_emails_raw = get_option( 'wc_facebook_excluded_emails', '' ); $excluded_ips_raw = get_option( 'wc_facebook_excluded_ips', '' ); - $excluded_emails = array_map( 'trim', explode( ',', strtolower( $excluded_emails_raw ) ) ); - $excluded_ips = array_map( 'trim', explode( ',', $excluded_ips_raw ) ); + $excluded_emails_raw = is_array( $excluded_emails_raw ) ? $excluded_emails_raw : explode( ',', $excluded_emails_raw ); + $excluded_ips_raw = is_array( $excluded_ips_raw ) ? $excluded_ips_raw : explode( ',', $excluded_ips_raw ); + + $excluded_emails = array_map( 'trim', array_map( 'strtolower', $excluded_emails_raw ) ); + $excluded_ips = array_map( 'trim', $excluded_ips_raw ); + if ( in_array( $billing_email, $excluded_emails, true ) ) { Logger::log( "Skipping Purchase event for excluded email: $billing_email" ); diff --git a/includes/Admin/Settings_Screens/Shops.php b/includes/Admin/Settings_Screens/Shops.php index 9155fc21d..6c364965e 100644 --- a/includes/Admin/Settings_Screens/Shops.php +++ b/includes/Admin/Settings_Screens/Shops.php @@ -121,6 +121,9 @@ public function enqueue_assets() { wp_enqueue_style( 'wc-facebook-admin-shops-settings', facebook_for_woocommerce()->get_plugin_url() . '/assets/css/admin/facebook-for-woocommerce-shops.css', array(), \WC_Facebookcommerce::VERSION ); + wp_enqueue_script( 'select2' ); + wp_enqueue_style( 'select2' ); + wp_enqueue_script( 'wc-facebook-enhanced-settings-sync', facebook_for_woocommerce()->get_asset_build_dir_url() . '/admin/enhanced-settings-sync.js', @@ -330,6 +333,18 @@ public static function get_settings_with_title_static( string $title ): array { RolloutSwitches::SWITCH_OFFER_MANAGEMENT_ENABLED ); + $existing_emails = get_option( 'wc_facebook_excluded_emails', [] ); + if ( is_string( $existing_emails ) ) { + $existing_emails = array_map( 'trim', explode( ',', $existing_emails ) ); + } + $existing_email_options = array_combine( $existing_emails, $existing_emails ); + + $existing_ips = get_option( 'wc_facebook_excluded_ips', [] ); + if ( is_string( $existing_ips ) ) { + $existing_ips = array_map( 'trim', explode( ',', $existing_ips ) ); + } + $existing_ip_options = array_combine( $existing_ips, $existing_ips ); + $title_array = [ 'title' => $title, 'type' => 'title', @@ -359,16 +374,30 @@ public static function get_settings_with_title_static( string $title ): array { 'title' => __( 'Exclude Emails from Purchase Events', 'facebook-for-woocommerce' ), 'desc' => __( 'Comma-separated list of email addresses. Orders from these will not trigger a Facebook Purchase event.', 'facebook-for-woocommerce' ), 'id' => 'wc_facebook_excluded_emails', - 'type' => 'text', + 'type' => 'multiselect', 'default' => '', + 'class' => 'wc-enhanced-select', + 'custom_attributes' => [ + 'multiple' => 'multiple', + ], + 'tags' => true, + 'css' => 'width: 50%;', + 'options' => $existing_email_options, ], [ 'title' => __( 'Exclude IPs from Purchase Events', 'facebook-for-woocommerce' ), 'desc' => __( 'Comma-separated list of IP addresses. Orders from these will not trigger a Facebook Purchase event.', 'facebook-for-woocommerce' ), 'id' => 'wc_facebook_excluded_ips', - 'type' => 'text', + 'type' => 'multiselect', 'default' => '', + 'class' => 'wc-enhanced-select', + 'custom_attributes' => [ + 'multiple' => 'multiple', + ], + 'tags' => true, + 'css' => 'width: 50%;', + 'options' => $existing_ip_options, ], [ From 1b4e34f3910bfc6ebf8674ac5ca4ada9ef38b280 Mon Sep 17 00:00:00 2001 From: Uros Rakic Date: Thu, 17 Jul 2025 14:00:35 +0200 Subject: [PATCH 4/4] Fix styles --- facebook-commerce-events-tracker.php | 1 - 1 file changed, 1 deletion(-) diff --git a/facebook-commerce-events-tracker.php b/facebook-commerce-events-tracker.php index 11eb98f6b..93478cff1 100644 --- a/facebook-commerce-events-tracker.php +++ b/facebook-commerce-events-tracker.php @@ -882,7 +882,6 @@ public function inject_purchase_event( $order_id ) { $excluded_emails = array_map( 'trim', array_map( 'strtolower', $excluded_emails_raw ) ); $excluded_ips = array_map( 'trim', $excluded_ips_raw ); - if ( in_array( $billing_email, $excluded_emails, true ) ) { Logger::log( "Skipping Purchase event for excluded email: $billing_email" ); return;