Skip to content

Commit 00767af

Browse files
JeDaVardshftlvchopencode-agent[bot]
authored
AT-1709 add property id validation (#8)
* AT-1709 add property id validation * Fix invalid property ID detection Co-authored-by: shftlvch <shftlvch@users.noreply.github.com> --------- Co-authored-by: Daniil Sheftelevich <shftlvch@gmail.com> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: shftlvch <shftlvch@users.noreply.github.com>
1 parent 53813f6 commit 00767af

3 files changed

Lines changed: 120 additions & 4 deletions

File tree

anytrack-for-woocommerce/trunk/anytrack-for-woocommerce.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
/*
33
Plugin Name: AnyTrack for WooCommerce
44
Description: Connect with Google, Facebook, Bing, Taboola and Outbrain and sync all your ad campaigns directly from WooCommerce.
5-
Version: 1.5.7
5+
Version: 1.5.8
66
Author: AnyTrack Ltd.
77
Author URI: https://anytrack.io
8-
Stable tag: 1.5.7
8+
Stable tag: 1.5.8
99
*/
1010

1111
//error_reporting(E_ALL);

anytrack-for-woocommerce/trunk/modules/settings.php

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?php
22

3-
43
class anytrack_for_woocommerce_SettingsClassV2{
54
/* V1.0.1 */
65
var $setttings_parameters;
@@ -16,6 +15,14 @@ function __construct( $prefix ){
1615
foreach( $_POST as $key=>$value ){
1716
$options[$key] = trim( sanitize_text_field( $value ) );
1817
}
18+
19+
// Validate before saving
20+
$validation_result = $this->validateSave( $options );
21+
if( $validation_result !== true ){
22+
$this->message = '<div class="alert alert-danger">' . $validation_result . '</div>';
23+
return;
24+
}
25+
1926
update_option( $this->setttings_prefix.'_options', $options );
2027

2128
$this->message = '<div class="alert alert-success">'.__('Settings saved', $this->setttings_prefix ).'</div>';
@@ -26,6 +33,112 @@ function __construct( $prefix ){
2633

2734
}
2835

36+
function getWooCommerceIntegrationErrorMessage(){
37+
return __('Please install the WooCommerce integration through <a href="https://dashboard.anytrack.io/catalog/woocommerce" target="_blank">AnyTrack integrations catalog</a>', $this->setttings_prefix );
38+
}
39+
40+
function getInvalidPropertyIdErrorMessage(){
41+
return __('Invalid Property ID: Property does not exist', $this->setttings_prefix );
42+
}
43+
44+
function isInvalidPropertyIdResponse( $body, $property_id ){
45+
if( empty( $body ) ){
46+
return false;
47+
}
48+
49+
$property_id_pattern = preg_quote( $property_id, '/' );
50+
$invalid_property_patterns = array(
51+
'/Property\s+["\']?' . $property_id_pattern . '["\']?\s+(not exists anymore|does not exist|not found)/i',
52+
'/console\.error\s*\(\s*["\'][^"\']*(not exists anymore|does not exist|not found)[^"\']*["\']\s*\)/i'
53+
);
54+
55+
foreach( $invalid_property_patterns as $pattern ){
56+
if( preg_match( $pattern, $body ) ){
57+
return true;
58+
}
59+
}
60+
61+
return false;
62+
}
63+
64+
function validateSave( $options ){
65+
// Check if property_id exists and is exactly 12 characters
66+
if( !isset( $options['property_id'] ) || empty( $options['property_id'] ) ){
67+
return __('Property ID is required', $this->setttings_prefix );
68+
}
69+
70+
$property_id = $options['property_id'];
71+
if( strlen( $property_id ) !== 12 ){
72+
return __('Property ID must be exactly 12 characters', $this->setttings_prefix );
73+
}
74+
75+
// Make API request to validate the property
76+
$ANYTRACK_TRACKER_ENDPOINT = defined('ANYTRACK_TRACKER_ENDPOINT') ? ANYTRACK_TRACKER_ENDPOINT : 'https://t1.anytrack.io/assets/';
77+
$api_url = rtrim( $ANYTRACK_TRACKER_ENDPOINT, '/' ) . '/' . $property_id . '.js';
78+
79+
$response = wp_remote_get( $api_url, array(
80+
'timeout' => 15,
81+
'headers' => array(
82+
'Accept' => 'application/javascript'
83+
)
84+
) );
85+
86+
if( is_wp_error( $response ) ){
87+
return __('Failed to validate Property ID: ' . $response->get_error_message(), $this->setttings_prefix );
88+
}
89+
90+
$body = wp_remote_retrieve_body( $response );
91+
$response_code = wp_remote_retrieve_response_code( $response );
92+
93+
if( $response_code !== 200 ){
94+
return __('Invalid Property ID: Unable to retrieve tracking script', $this->setttings_prefix );
95+
}
96+
97+
if( $this->isInvalidPropertyIdResponse( $body, $property_id ) ){
98+
return $this->getInvalidPropertyIdErrorMessage();
99+
}
100+
101+
// Parse JavaScript to check for WooCommerce integration
102+
// Extract the last JSON object passed to AnyTrack function (the configuration)
103+
if( preg_match('/AnyTrack["\']?\s*,\s*(\{.+\})\s*\)\s*;?\s*$/s', $body, $matches) ){
104+
$config_str = $matches[1];
105+
106+
// The config is already valid JSON in the response
107+
$config = json_decode( $config_str, true );
108+
109+
if( json_last_error() === JSON_ERROR_NONE ){
110+
// Successfully parsed JSON, check for ig field
111+
if( !isset( $config['ig'] ) || !is_array( $config['ig'] ) ){
112+
return $this->getWooCommerceIntegrationErrorMessage();
113+
}
114+
115+
// Check if woocommerce integration exists
116+
$has_woocommerce = false;
117+
foreach( $config['ig'] as $integration ){
118+
if( isset( $integration['akid'] ) && $integration['akid'] === 'woocommerce' ){
119+
$has_woocommerce = true;
120+
break;
121+
}
122+
}
123+
124+
if( !$has_woocommerce ){
125+
return $this->getWooCommerceIntegrationErrorMessage();
126+
}
127+
128+
return true; // Valid - WooCommerce integration found
129+
}
130+
}
131+
132+
// Fallback: If JSON parsing fails, use simpler regex search
133+
// This handles cases where the JS structure is different
134+
if( preg_match('/"ig"\s*:\s*\[/s', $body) && preg_match('/"akid"\s*:\s*"woocommerce"/s', $body) ){
135+
return true; // Valid - found both ig array and woocommerce akid
136+
}
137+
138+
// Could not validate WooCommerce integration
139+
return $this->getWooCommerceIntegrationErrorMessage();
140+
}
141+
29142
function get_setting( $setting_name ){
30143
$inner_option = get_option( $this->setttings_prefix.'_options');
31144
return $inner_option[$setting_name];

anytrack-for-woocommerce/trunk/readme.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Donate link: https://anytrack.io/
44
Tags: woocommerce, e-commerce, conversions, facebook, google, funnelkit
55
Requires at least: 4.7
66
Tested up to: 6.8.1
7-
Stable tag: 1.5.6
7+
Stable tag: 1.5.8
88
Requires PHP: 7.0
99
License: GPLv2 or later
1010
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -77,6 +77,9 @@ prefer on the pixel settings on AnyTrack.
7777
Initial version.
7878

7979
== Changelog ==
80+
= 1.5.8 =
81+
* Add property id validation
82+
8083
= 1.5.7 =
8184
* Restrict the event mapping to the default standards
8285

0 commit comments

Comments
 (0)