diff --git a/anytrack-for-woocommerce/trunk/anytrack-for-woocommerce.php b/anytrack-for-woocommerce/trunk/anytrack-for-woocommerce.php
index a85a3f2..d9266d1 100755
--- a/anytrack-for-woocommerce/trunk/anytrack-for-woocommerce.php
+++ b/anytrack-for-woocommerce/trunk/anytrack-for-woocommerce.php
@@ -2,10 +2,10 @@
/*
Plugin Name: AnyTrack for WooCommerce
Description: Connect with Google, Facebook, Bing, Taboola and Outbrain and sync all your ad campaigns directly from WooCommerce.
-Version: 1.5.7
+Version: 1.5.8
Author: AnyTrack Ltd.
Author URI: https://anytrack.io
-Stable tag: 1.5.7
+Stable tag: 1.5.8
*/
//error_reporting(E_ALL);
diff --git a/anytrack-for-woocommerce/trunk/modules/settings.php b/anytrack-for-woocommerce/trunk/modules/settings.php
index 73962df..370f4c5 100644
--- a/anytrack-for-woocommerce/trunk/modules/settings.php
+++ b/anytrack-for-woocommerce/trunk/modules/settings.php
@@ -1,6 +1,5 @@
$value ){
$options[$key] = trim( sanitize_text_field( $value ) );
}
+
+ // Validate before saving
+ $validation_result = $this->validateSave( $options );
+ if( $validation_result !== true ){
+ $this->message = '
' . $validation_result . '
';
+ return;
+ }
+
update_option( $this->setttings_prefix.'_options', $options );
$this->message = ''.__('Settings saved', $this->setttings_prefix ).'
';
@@ -26,6 +33,112 @@ function __construct( $prefix ){
}
+ function getWooCommerceIntegrationErrorMessage(){
+ return __('Please install the WooCommerce integration through AnyTrack integrations catalog', $this->setttings_prefix );
+ }
+
+ function getInvalidPropertyIdErrorMessage(){
+ return __('Invalid Property ID: Property does not exist', $this->setttings_prefix );
+ }
+
+ function isInvalidPropertyIdResponse( $body, $property_id ){
+ if( empty( $body ) ){
+ return false;
+ }
+
+ $property_id_pattern = preg_quote( $property_id, '/' );
+ $invalid_property_patterns = array(
+ '/Property\s+["\']?' . $property_id_pattern . '["\']?\s+(not exists anymore|does not exist|not found)/i',
+ '/console\.error\s*\(\s*["\'][^"\']*(not exists anymore|does not exist|not found)[^"\']*["\']\s*\)/i'
+ );
+
+ foreach( $invalid_property_patterns as $pattern ){
+ if( preg_match( $pattern, $body ) ){
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function validateSave( $options ){
+ // Check if property_id exists and is exactly 12 characters
+ if( !isset( $options['property_id'] ) || empty( $options['property_id'] ) ){
+ return __('Property ID is required', $this->setttings_prefix );
+ }
+
+ $property_id = $options['property_id'];
+ if( strlen( $property_id ) !== 12 ){
+ return __('Property ID must be exactly 12 characters', $this->setttings_prefix );
+ }
+
+ // Make API request to validate the property
+ $ANYTRACK_TRACKER_ENDPOINT = defined('ANYTRACK_TRACKER_ENDPOINT') ? ANYTRACK_TRACKER_ENDPOINT : 'https://t1.anytrack.io/assets/';
+ $api_url = rtrim( $ANYTRACK_TRACKER_ENDPOINT, '/' ) . '/' . $property_id . '.js';
+
+ $response = wp_remote_get( $api_url, array(
+ 'timeout' => 15,
+ 'headers' => array(
+ 'Accept' => 'application/javascript'
+ )
+ ) );
+
+ if( is_wp_error( $response ) ){
+ return __('Failed to validate Property ID: ' . $response->get_error_message(), $this->setttings_prefix );
+ }
+
+ $body = wp_remote_retrieve_body( $response );
+ $response_code = wp_remote_retrieve_response_code( $response );
+
+ if( $response_code !== 200 ){
+ return __('Invalid Property ID: Unable to retrieve tracking script', $this->setttings_prefix );
+ }
+
+ if( $this->isInvalidPropertyIdResponse( $body, $property_id ) ){
+ return $this->getInvalidPropertyIdErrorMessage();
+ }
+
+ // Parse JavaScript to check for WooCommerce integration
+ // Extract the last JSON object passed to AnyTrack function (the configuration)
+ if( preg_match('/AnyTrack["\']?\s*,\s*(\{.+\})\s*\)\s*;?\s*$/s', $body, $matches) ){
+ $config_str = $matches[1];
+
+ // The config is already valid JSON in the response
+ $config = json_decode( $config_str, true );
+
+ if( json_last_error() === JSON_ERROR_NONE ){
+ // Successfully parsed JSON, check for ig field
+ if( !isset( $config['ig'] ) || !is_array( $config['ig'] ) ){
+ return $this->getWooCommerceIntegrationErrorMessage();
+ }
+
+ // Check if woocommerce integration exists
+ $has_woocommerce = false;
+ foreach( $config['ig'] as $integration ){
+ if( isset( $integration['akid'] ) && $integration['akid'] === 'woocommerce' ){
+ $has_woocommerce = true;
+ break;
+ }
+ }
+
+ if( !$has_woocommerce ){
+ return $this->getWooCommerceIntegrationErrorMessage();
+ }
+
+ return true; // Valid - WooCommerce integration found
+ }
+ }
+
+ // Fallback: If JSON parsing fails, use simpler regex search
+ // This handles cases where the JS structure is different
+ if( preg_match('/"ig"\s*:\s*\[/s', $body) && preg_match('/"akid"\s*:\s*"woocommerce"/s', $body) ){
+ return true; // Valid - found both ig array and woocommerce akid
+ }
+
+ // Could not validate WooCommerce integration
+ return $this->getWooCommerceIntegrationErrorMessage();
+ }
+
function get_setting( $setting_name ){
$inner_option = get_option( $this->setttings_prefix.'_options');
return $inner_option[$setting_name];
diff --git a/anytrack-for-woocommerce/trunk/readme.txt b/anytrack-for-woocommerce/trunk/readme.txt
index bd4a729..8f484a4 100755
--- a/anytrack-for-woocommerce/trunk/readme.txt
+++ b/anytrack-for-woocommerce/trunk/readme.txt
@@ -4,7 +4,7 @@ Donate link: https://anytrack.io/
Tags: woocommerce, e-commerce, conversions, facebook, google, funnelkit
Requires at least: 4.7
Tested up to: 6.8.1
-Stable tag: 1.5.6
+Stable tag: 1.5.8
Requires PHP: 7.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -77,6 +77,9 @@ prefer on the pixel settings on AnyTrack.
Initial version.
== Changelog ==
+= 1.5.8 =
+* Add property id validation
+
= 1.5.7 =
* Restrict the event mapping to the default standards