Pixel Manager for WooCommerce – Track Google Analytics, Google Ads, Facebook and more - Version 1.9.6

Version Description

  • Tweak: Added one more tweak for LiteSpeed Cache users

  • Fix: Changed reading options from database to passing options from primary instance in order to avoid options caching issues on saving.

Download this release

Release Info

Developer alekv
Plugin Icon 128x128 Pixel Manager for WooCommerce – Track Google Analytics, Google Ads, Facebook and more
Version 1.9.6
Comparing to
See all releases

Code changes from version 1.8.28 to 1.9.6

Files changed (38) hide show
  1. classes/admin/class-admin.php +131 -19
  2. classes/admin/class-ask-for-rating.php +69 -68
  3. classes/admin/class-debug-info.php +1 -1
  4. classes/admin/class-environment-check.php +76 -36
  5. classes/admin/class-launch-deal.php +1 -7
  6. classes/class-default-options.php +99 -0
  7. classes/pixels/class-cookie-consent-management.php +2 -2
  8. classes/pixels/class-pixel-manager-base.php +10 -7
  9. classes/pixels/class-pixel-manager.php +210 -47
  10. classes/pixels/class-pixel.php +8 -44
  11. classes/pixels/class-shortcodes.php +2 -2
  12. classes/pixels/facebook/class-facebook-browser-pixel.php +24 -65
  13. classes/pixels/facebook/class-facebook-pixel-manager-microdata.php +3 -3
  14. classes/pixels/facebook/class-facebook-pixel-manager.php +58 -36
  15. classes/pixels/google/class-google-ads.php +17 -33
  16. classes/pixels/google/class-google-analytics-4-eec.php +6 -76
  17. classes/pixels/google/class-google-analytics-4-standard.php +2 -2
  18. classes/pixels/google/class-google-analytics-4.php +13 -14
  19. classes/pixels/google/class-google-analytics-refund-4.php +2 -6
  20. classes/pixels/google/class-google-analytics-refund-ua.php +2 -6
  21. classes/pixels/google/class-google-analytics-refund.php +2 -2
  22. classes/pixels/google/class-google-analytics-ua-eec.php +6 -65
  23. classes/pixels/google/class-google-analytics-ua-standard.php +2 -2
  24. classes/pixels/google/class-google-analytics-ua.php +17 -15
  25. classes/pixels/google/class-google-analytics.php +27 -119
  26. classes/pixels/google/class-google-pixel-manager.php +67 -96
  27. classes/pixels/google/class-google.php +15 -39
  28. classes/pixels/google/trait-google.php +67 -0
  29. classes/pixels/hotjar/class-hotjar-pixel.php +2 -2
  30. classes/pixels/trait-product.php +57 -1
  31. classes/pixels/trait-shop.php +70 -0
  32. js/admin/tabs.js +2 -2
  33. js/public/facebook.js +54 -14
  34. js/public/google-ads.js +128 -0
  35. js/public/wooptpm.js +655 -200
  36. languages/woocommerce-google-adwords-conversion-tracking-tag.pot +159 -134
  37. readme.txt +56 -2
  38. wgact.php +11 -96
classes/admin/class-admin.php CHANGED
@@ -21,11 +21,11 @@ class Admin
21
  protected $options ;
22
  protected $plugin_hook ;
23
  protected $documentation_host ;
24
- public function __construct()
25
  {
 
26
  $this->plugin_hook = 'woocommerce_page_wgact';
27
  $this->documentation_host = 'docs.woopt.com';
28
- $this->options = get_option( 'wgact_plugin_options' );
29
  add_action( 'admin_enqueue_scripts', [ $this, 'wgact_admin_scripts' ] );
30
  // add the admin options page
31
  add_action( 'admin_menu', [ $this, 'wgact_plugin_admin_add_page' ], 99 );
@@ -39,7 +39,7 @@ class Admin
39
 
40
  public function my_after_purchase_js( $js_function ) : string
41
  {
42
- return "function ( response ) {\n\n let\n isTrial = (null != response.purchase.trial_ends),\n isSubscription = (null != response.purchase.initial_amount),\n total = isTrial ? 0 : (isSubscription ? response.purchase.initial_amount : response.purchase.gross).toString(),\n productName = 'WooCommerce Pixel Manager',\n // storeUrl = 'https://woopt.com',\n storeName = 'woopt WooCommerce Pixel Manager';\n \n window.dataLayer = window.dataLayer || [];\n\n function gtag() {\n dataLayer.push(arguments);\n }\n \n gtag('js', new Date()); \n \n gtag('config', 'UA-39746956-10', {'anonymize_ip':'true'});\n \n gtag('event', 'purchase', {\n 'send_to':['UA-39746956-10'],\n 'transaction_id':response.purchase.id.toString(),\n 'currency':'USD',\n 'discount':0,\n 'items':[{\n 'id':response.purchase.plan_id.toString(),\n 'quantity':1,\n 'price':response.purchase.initial_amount.toString(),\n 'name':productName,\n 'category': 'Plugin',\n }],\n 'affiliation': storeName,\n 'value':response.purchase.initial_amount.toString()\n });\n \n }";
43
  }
44
 
45
  public function my_checkout_enrich( $html ) : string
@@ -53,41 +53,41 @@ class Admin
53
  return;
54
  }
55
  wp_enqueue_script(
56
- 'script-blocker-warning',
57
  plugin_dir_url( __DIR__ ) . '../js/admin/script-blocker-warning.js',
58
- [],
59
  WGACT_CURRENT_VERSION,
60
  false
61
  );
62
  wp_enqueue_script(
63
- 'admin-helpers',
64
  plugin_dir_url( __DIR__ ) . '../js/admin/helpers.js',
65
- [],
66
  WGACT_CURRENT_VERSION,
67
  false
68
  );
69
  wp_enqueue_script(
70
- 'admin-tabs',
71
  plugin_dir_url( __DIR__ ) . '../js/admin/tabs.js',
72
- [],
73
  WGACT_CURRENT_VERSION,
74
  false
75
  );
76
  wp_enqueue_script(
77
- 'selectWoo',
78
  plugin_dir_url( __DIR__ ) . '../js/admin/selectWoo.full.min.js',
79
- [],
80
  WGACT_CURRENT_VERSION,
81
  false
82
  );
83
  wp_enqueue_style(
84
- 'admin',
85
  plugin_dir_url( __DIR__ ) . '../css/admin.css',
86
  [],
87
  WGACT_CURRENT_VERSION
88
  );
89
  wp_enqueue_style(
90
- 'selectWoo',
91
  plugin_dir_url( __DIR__ ) . '../css/selectWoo.min.css',
92
  [],
93
  WGACT_CURRENT_VERSION
@@ -184,7 +184,7 @@ class Admin
184
  );
185
  add_settings_field(
186
  'wgact_plugin_analytics_4_measurement_id',
187
- esc_html__( 'Google Analytics 4', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
188
  [ $this, 'wgact_option_html_google_analytics_4_id' ],
189
  'wgact_plugin_options_page',
190
  $section_ids['settings_name']
@@ -366,16 +366,26 @@ class Admin
366
  $section_ids['settings_name']
367
  );
368
  }
 
369
  if ( wga_fs()->is__premium_only() || $this->pro_version_demo_active() ) {
370
  // add fields for the Google enhanced e-commerce
371
  add_settings_field(
372
  'wgact_setting_google_analytics_eec',
373
- esc_html__( 'Enhanced E-Commerce', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
374
  [ $this, 'wgact_setting_html_google_analytics_eec' ],
375
  'wgact_plugin_options_page',
376
  $section_ids['settings_name']
377
  );
 
 
 
 
 
 
 
 
378
  }
 
379
  // add fields for the Google Analytics link attribution
380
  add_settings_field(
381
  'wgact_setting_google_analytics_link_attribution',
@@ -434,7 +444,7 @@ class Admin
434
  // add fields for the Google Consent beta
435
  add_settings_field(
436
  'wgact_setting_google_consent_mode_active',
437
- esc_html__( 'Google Consent Mode', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
438
  [ $this, 'wgact_setting_html_google_consent_mode_active' ],
439
  'wgact_plugin_options_page',
440
  $section_ids['settings_name']
@@ -442,7 +452,7 @@ class Admin
442
  // add fields for the Google consent regions
443
  add_settings_field(
444
  'wgact_setting_google_consent_regions',
445
- esc_html__( 'Google Consent Regions', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
446
  [ $this, 'wgact_setting_html_google_consent_regions' ],
447
  'wgact_plugin_options_page',
448
  $section_ids['settings_name']
@@ -460,7 +470,7 @@ class Admin
460
  // add fields for the Cookiebot support
461
  add_settings_field(
462
  'wgact_setting_cookiebot_active',
463
- esc_html__( 'Cookiebot support', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
464
  [ $this, 'wgact_setting_html_cookiebot_support' ],
465
  'wgact_plugin_options_page',
466
  $section_ids['settings_name']
@@ -482,7 +492,18 @@ class Admin
482
  'wgact_plugin_options_page',
483
  $section_ids['settings_name']
484
  );
485
- // add fields for the gtag insertion
 
 
 
 
 
 
 
 
 
 
 
486
  add_settings_field(
487
  'wgact_setting_facebook_microdata_active',
488
  esc_html__( 'Facebook microdata', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
@@ -1164,6 +1185,30 @@ class Admin
1164
 
1165
  }
1166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1167
  public function wgact_setting_html_google_analytics_link_attribution()
1168
  {
1169
  // adding the hidden input is a hack to make WordPress save the option with the value zero,
@@ -1294,6 +1339,37 @@ class Admin
1294
 
1295
  }
1296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1297
  public function wgact_setting_html_facebook_microdata()
1298
  {
1299
  // adding the hidden input is a hack to make WordPress save the option with the value zero,
@@ -1831,6 +1907,15 @@ class Admin
1831
  add_settings_error( 'wgact_plugin_options', 'invalid-google-analytics-4-measurement-id', esc_html__( 'You have entered an invalid Google Analytics 4 measurement ID.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1832
  }
1833
 
 
 
 
 
 
 
 
 
 
1834
  }
1835
  // validate ['google]['ads']['conversion_id']
1836
  if ( isset( $input['google']['ads']['conversion_id'] ) ) {
@@ -1885,6 +1970,15 @@ class Admin
1885
  add_settings_error( 'wgact_plugin_options', 'invalid-facebook-pixel-id', esc_html__( 'You have entered an invalid Facebook pixel ID. It only contains 14 to 16 digits.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1886
  }
1887
 
 
 
 
 
 
 
 
 
 
1888
  }
1889
  // validate Bing Ads UET tag ID
1890
  if ( isset( $input['bing']['uet_tag_id'] ) ) {
@@ -2041,6 +2135,15 @@ class Admin
2041
  return $this->validate_with_regex( $re, $string );
2042
  }
2043
 
 
 
 
 
 
 
 
 
 
2044
  protected function is_facebook_pixel_id( $string ) : bool
2045
  {
2046
  if ( empty($string) ) {
@@ -2050,6 +2153,15 @@ class Admin
2050
  return $this->validate_with_regex( $re, $string );
2051
  }
2052
 
 
 
 
 
 
 
 
 
 
2053
  protected function is_bing_uet_tag_id( $string ) : bool
2054
  {
2055
  if ( empty($string) ) {
21
  protected $options ;
22
  protected $plugin_hook ;
23
  protected $documentation_host ;
24
+ public function __construct( $options )
25
  {
26
+ $this->options = $options;
27
  $this->plugin_hook = 'woocommerce_page_wgact';
28
  $this->documentation_host = 'docs.woopt.com';
 
29
  add_action( 'admin_enqueue_scripts', [ $this, 'wgact_admin_scripts' ] );
30
  // add the admin options page
31
  add_action( 'admin_menu', [ $this, 'wgact_plugin_admin_add_page' ], 99 );
39
 
40
  public function my_after_purchase_js( $js_function ) : string
41
  {
42
+ return "function ( response ) {\n\n let\n isTrial = (null != response.purchase.trial_ends),\n isSubscription = (null != response.purchase.initial_amount),\n total = isTrial ? 0 : (isSubscription ? response.purchase.initial_amount : response.purchase.gross).toString(),\n productName = 'WooCommerce Pixel Manager',\n // storeUrl = 'https://woopt.com',\n storeName = 'woopt WooCommerce Pixel Manager';\n \n window.dataLayer = window.dataLayer || [];\n\n function gtag() {\n dataLayer.push(arguments);\n }\n \n gtag('js', new Date()); \n \n gtag('config', 'UA-39746956-10', {'anonymize_ip':'true'});\n gtag('config', 'G-LWRCPMQS9T');\n gtag('config', 'AW-406204436');\n \n gtag('event', 'purchase', {\n 'send_to':['UA-39746956-10', 'G-LWRCPMQS9T'],\n 'transaction_id':response.purchase.id.toString(),\n 'currency':'USD',\n 'discount':0,\n 'items':[{\n 'id':response.purchase.plan_id.toString(),\n 'quantity':1,\n 'price':total,\n 'name':productName,\n 'category': 'Plugin',\n }],\n 'affiliation': storeName,\n 'value':response.purchase.initial_amount.toString()\n });\n \n gtag('event', 'conversion', {\n 'send_to': 'AW-406204436/XrUYCK3J8YoCEJTg2MEB',\n 'value': response.purchase.initial_amount.toString(),\n 'currency': 'USD',\n 'transaction_id': response.purchase.id.toString()\n });\n\n }";
43
  }
44
 
45
  public function my_checkout_enrich( $html ) : string
53
  return;
54
  }
55
  wp_enqueue_script(
56
+ 'wooptpm-script-blocker-warning',
57
  plugin_dir_url( __DIR__ ) . '../js/admin/script-blocker-warning.js',
58
+ [ 'jquery' ],
59
  WGACT_CURRENT_VERSION,
60
  false
61
  );
62
  wp_enqueue_script(
63
+ 'wooptpm-admin-helpers',
64
  plugin_dir_url( __DIR__ ) . '../js/admin/helpers.js',
65
+ [ 'jquery' ],
66
  WGACT_CURRENT_VERSION,
67
  false
68
  );
69
  wp_enqueue_script(
70
+ 'wooptpm-admin-tabs',
71
  plugin_dir_url( __DIR__ ) . '../js/admin/tabs.js',
72
+ [ 'jquery' ],
73
  WGACT_CURRENT_VERSION,
74
  false
75
  );
76
  wp_enqueue_script(
77
+ 'wooptpm-selectWoo',
78
  plugin_dir_url( __DIR__ ) . '../js/admin/selectWoo.full.min.js',
79
+ [ 'jquery' ],
80
  WGACT_CURRENT_VERSION,
81
  false
82
  );
83
  wp_enqueue_style(
84
+ 'wooptpm-admin',
85
  plugin_dir_url( __DIR__ ) . '../css/admin.css',
86
  [],
87
  WGACT_CURRENT_VERSION
88
  );
89
  wp_enqueue_style(
90
+ 'wooptpm-selectWoo',
91
  plugin_dir_url( __DIR__ ) . '../css/selectWoo.min.css',
92
  [],
93
  WGACT_CURRENT_VERSION
184
  );
185
  add_settings_field(
186
  'wgact_plugin_analytics_4_measurement_id',
187
+ esc_html__( 'Google Analytics 4', 'woocommerce-google-adwords-conversion-tracking-tag' ),
188
  [ $this, 'wgact_option_html_google_analytics_4_id' ],
189
  'wgact_plugin_options_page',
190
  $section_ids['settings_name']
366
  $section_ids['settings_name']
367
  );
368
  }
369
+
370
  if ( wga_fs()->is__premium_only() || $this->pro_version_demo_active() ) {
371
  // add fields for the Google enhanced e-commerce
372
  add_settings_field(
373
  'wgact_setting_google_analytics_eec',
374
+ esc_html__( 'Enhanced E-Commerce', 'woocommerce-google-adwords-conversion-tracking-tag' ),
375
  [ $this, 'wgact_setting_html_google_analytics_eec' ],
376
  'wgact_plugin_options_page',
377
  $section_ids['settings_name']
378
  );
379
+ // add fields for the Google GA 4 API secret
380
+ add_settings_field(
381
+ 'wgact_setting_google_analytics_4_api_secret',
382
+ esc_html__( 'GA 4 API secret', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
383
+ [ $this, 'wgact_setting_html_google_analytics_4_api_secret' ],
384
+ 'wgact_plugin_options_page',
385
+ $section_ids['settings_name']
386
+ );
387
  }
388
+
389
  // add fields for the Google Analytics link attribution
390
  add_settings_field(
391
  'wgact_setting_google_analytics_link_attribution',
444
  // add fields for the Google Consent beta
445
  add_settings_field(
446
  'wgact_setting_google_consent_mode_active',
447
+ esc_html__( 'Google Consent Mode', 'woocommerce-google-adwords-conversion-tracking-tag' ),
448
  [ $this, 'wgact_setting_html_google_consent_mode_active' ],
449
  'wgact_plugin_options_page',
450
  $section_ids['settings_name']
452
  // add fields for the Google consent regions
453
  add_settings_field(
454
  'wgact_setting_google_consent_regions',
455
+ esc_html__( 'Google Consent Regions', 'woocommerce-google-adwords-conversion-tracking-tag' ),
456
  [ $this, 'wgact_setting_html_google_consent_regions' ],
457
  'wgact_plugin_options_page',
458
  $section_ids['settings_name']
470
  // add fields for the Cookiebot support
471
  add_settings_field(
472
  'wgact_setting_cookiebot_active',
473
+ esc_html__( 'Cookiebot support', 'woocommerce-google-adwords-conversion-tracking-tag' ),
474
  [ $this, 'wgact_setting_html_cookiebot_support' ],
475
  'wgact_plugin_options_page',
476
  $section_ids['settings_name']
492
  'wgact_plugin_options_page',
493
  $section_ids['settings_name']
494
  );
495
+ // add field for the Facebook CAPI token
496
+ // add_settings_field(
497
+ // 'wgact_setting_facebook_capi_token',
498
+ // esc_html__(
499
+ // 'Facebook CAPI token',
500
+ // 'woocommerce-google-adwords-conversion-tracking-tag'
501
+ // ) . $this->svg_beta(),
502
+ // [$this, 'wgact_setting_html_facebook_capi_token'],
503
+ // 'wgact_plugin_options_page',
504
+ // $section_ids['settings_name']
505
+ // );
506
+ // add fields for Facebook microdata
507
  add_settings_field(
508
  'wgact_setting_facebook_microdata_active',
509
  esc_html__( 'Facebook microdata', 'woocommerce-google-adwords-conversion-tracking-tag' ) . $this->svg_beta(),
1185
 
1186
  }
1187
 
1188
+ public function wgact_setting_html_google_analytics_4_api_secret()
1189
+ {
1190
+ echo "<input \n id='wgact_setting_google_analytics_4_api_secret' \n name='wgact_plugin_options[google][analytics][ga4][api_secret]' \n size='40' \n type='text' \n value='{$this->options['google']['analytics']['ga4']['api_secret']}' \n {$this->disable_if_demo()}\n />" ;
1191
+ echo $this->get_status_icon( $this->options['google']['analytics']['ga4']['api_secret'], $this->options['google']['analytics']['eec'] ) ;
1192
+ // echo $this->get_documentation_html('/wgact/?utm_source=woocommerce-plugin&utm_medium=documentation-link&utm_campaign=woopt-pixel-manager-docs&utm_content=google-ads-phone-conversion-number#/pixels/google-ads?id=phone-conversion-number');
1193
+ echo $this->svg_pro_feature() ;
1194
+ echo '<br><br>' ;
1195
+
1196
+ if ( !$this->options['google']['analytics']['ga4']['measurement_id'] ) {
1197
+ echo '<p></p><span class="dashicons dashicons-info" style="margin-right: 10px"></span>' ;
1198
+ esc_html_e( 'Google Analytics 4 activation required', 'woocommerce-google-adwords-conversion-tracking-tag' );
1199
+ echo '</p>' ;
1200
+ }
1201
+
1202
+
1203
+ if ( !$this->options['google']['analytics']['eec'] ) {
1204
+ echo '<p></p><span class="dashicons dashicons-info" style="margin-right: 10px"></span>' ;
1205
+ esc_html_e( 'Enhanced E-Commerce activation required', 'woocommerce-google-adwords-conversion-tracking-tag' );
1206
+ echo '</p><br>' ;
1207
+ }
1208
+
1209
+ esc_html_e( 'If enabled, purchase and refund events will be sent to Google through the measurement protocol for increased accuracy.', 'woocommerce-google-adwords-conversion-tracking-tag' );
1210
+ }
1211
+
1212
  public function wgact_setting_html_google_analytics_link_attribution()
1213
  {
1214
  // adding the hidden input is a hack to make WordPress save the option with the value zero,
1339
 
1340
  }
1341
 
1342
+ public function wgact_setting_html_facebook_capi_token()
1343
+ {
1344
+ ?><textarea id='wgact_setting_facebook_capi_token'
1345
+ name='wgact_plugin_options[facebook][capi_token]'
1346
+ cols='60'
1347
+ rows='5'
1348
+ value='<?php
1349
+ echo $this->options['facebook']['capi_token'] ;
1350
+ ?>'
1351
+ <?php
1352
+ echo $this->disable_if_demo() ;
1353
+ ?>
1354
+ ><?php
1355
+ echo $this->options['facebook']['capi_token'] ;
1356
+ ?></textarea>
1357
+ <?php
1358
+ echo $this->get_status_icon( $this->options['facebook']['capi_token'], $this->options['facebook']['pixel_id'] ) ;
1359
+ echo $this->svg_pro_feature() ;
1360
+
1361
+ if ( !$this->options['facebook']['pixel_id'] ) {
1362
+ echo '<p></p><span class="dashicons dashicons-info"></span>' ;
1363
+ esc_html_e( 'You need to activate the Facebook pixel', 'woocommerce-google-adwords-conversion-tracking-tag' );
1364
+ echo '</p><br>' ;
1365
+ }
1366
+
1367
+ // echo $this->get_documentation_html('/wgact/?utm_source=woocommerce-plugin&utm_medium=documentation-link&utm_campaign=woopt-pixel-manager-docs&utm_content=google-ads-conversion-id#/pixels/google-ads?id=configure-the-plugin');
1368
+ echo '<br><br>' ;
1369
+ // esc_html_e('The conversion ID looks similar to this:', 'woocommerce-google-adwords-conversion-tracking-tag');
1370
+ // echo '&nbsp;<i>123456789</i>';
1371
+ }
1372
+
1373
  public function wgact_setting_html_facebook_microdata()
1374
  {
1375
  // adding the hidden input is a hack to make WordPress save the option with the value zero,
1907
  add_settings_error( 'wgact_plugin_options', 'invalid-google-analytics-4-measurement-id', esc_html__( 'You have entered an invalid Google Analytics 4 measurement ID.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1908
  }
1909
 
1910
+ }
1911
+ // validate Google Analytics 4 API key
1912
+ if ( isset( $input['google']['analytics']['ga4']['api_secret'] ) ) {
1913
+
1914
+ if ( !$this->is_google_analytics_4_api_secret( $input['google']['analytics']['ga4']['api_secret'] ) ) {
1915
+ $input['google']['analytics']['ga4']['api_secret'] = ( isset( $this->options['google']['analytics']['ga4']['api_secret'] ) ? $this->options['google']['analytics']['ga4']['api_secret'] : '' );
1916
+ add_settings_error( 'wgact_plugin_options', 'invalid-google-analytics-4-measurement-id', esc_html__( 'You have entered an invalid Google Analytics 4 API key.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1917
+ }
1918
+
1919
  }
1920
  // validate ['google]['ads']['conversion_id']
1921
  if ( isset( $input['google']['ads']['conversion_id'] ) ) {
1970
  add_settings_error( 'wgact_plugin_options', 'invalid-facebook-pixel-id', esc_html__( 'You have entered an invalid Facebook pixel ID. It only contains 14 to 16 digits.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1971
  }
1972
 
1973
+ }
1974
+ // validate ['facebook']['capi_token']
1975
+ if ( isset( $input['facebook']['capi_token'] ) ) {
1976
+
1977
+ if ( !$this->is_facebook_capi_token( $input['facebook']['capi_token'] ) ) {
1978
+ $input['facebook']['capi_token'] = ( isset( $this->options['facebook']['capi_token'] ) ? $this->options['facebook']['capi_token'] : '' );
1979
+ add_settings_error( 'wgact_plugin_options', 'invalid-facebook-pixel-id', esc_html__( 'You have entered an invalid Facebook CAPI token.', 'woocommerce-google-adwords-conversion-tracking-tag' ) );
1980
+ }
1981
+
1982
  }
1983
  // validate Bing Ads UET tag ID
1984
  if ( isset( $input['bing']['uet_tag_id'] ) ) {
2135
  return $this->validate_with_regex( $re, $string );
2136
  }
2137
 
2138
+ public function is_google_analytics_4_api_secret( $string ) : bool
2139
+ {
2140
+ if ( empty($string) ) {
2141
+ return true;
2142
+ }
2143
+ $re = '/^[a-zA-Z\\d_-]{18,26}$/m';
2144
+ return $this->validate_with_regex( $re, $string );
2145
+ }
2146
+
2147
  protected function is_facebook_pixel_id( $string ) : bool
2148
  {
2149
  if ( empty($string) ) {
2153
  return $this->validate_with_regex( $re, $string );
2154
  }
2155
 
2156
+ protected function is_facebook_capi_token( $string ) : bool
2157
+ {
2158
+ if ( empty($string) ) {
2159
+ return true;
2160
+ }
2161
+ $re = '/^[a-zA-Z\\d_-]{150,250}$/m';
2162
+ return $this->validate_with_regex( $re, $string );
2163
+ }
2164
+
2165
  protected function is_bing_uet_tag_id( $string ) : bool
2166
  {
2167
  if ( empty($string) ) {
classes/admin/class-ask-for-rating.php CHANGED
@@ -2,16 +2,17 @@
2
 
3
  namespace WGACT\Classes\Admin;
4
 
5
- if ( ! defined( 'ABSPATH' ) ) {
6
- exit; // Exit if accessed directly
7
  }
8
 
9
- class Ask_For_Rating {
 
10
 
11
  private $option_name = WGACT_DB_RATINGS;
12
- private $conversions_count;
13
 
14
- public function __construct() {
 
15
 
16
  // $options = get_option($this->option_name);
17
  // $options['conversions_count'] = 8;
@@ -20,21 +21,16 @@ class Ask_For_Rating {
20
  // $options['rating_done'] = false;
21
  // update_option($this->option_name,$options);
22
 
23
- // ask for a rating in a plugin notice
24
- add_action( 'admin_enqueue_scripts', [$this,'wgact_rating_script'] );
25
- add_action( 'wp_ajax_wgact_dismissed_notice_handler', [$this, 'ajax_rating_notice_handler'] );
26
- add_action( 'admin_notices', [$this, 'ask_for_rating_notices_if_not_asked_before'] );
27
- }
28
 
29
- public function wgact_rating_script(){
 
30
 
31
- wp_enqueue_script(
32
- 'ask-for-rating', // Handle
33
- plugin_dir_url( __DIR__ ) . '../js/admin/ask-for-rating.js',
34
- [ 'jquery' ],
35
- WGACT_CURRENT_VERSION,
36
- true
37
- );
38
 
39
  // wp_localize_script(
40
  // 'ask-for-rating', // Handle
@@ -46,90 +42,95 @@ class Ask_For_Rating {
46
  // );
47
  }
48
 
49
- // server side php ajax handler for the admin rating notice
50
- public function ajax_rating_notice_handler() {
 
51
 
52
- $set = $_POST['set'];
53
 
54
- $options = get_option($this->option_name);
55
 
56
- if ( 'rating_done' === $set ){
57
 
58
  // error_log('saving rating done');
59
- $options['rating_done'] = true;
60
- update_option($this->option_name, $options);
61
 
62
- } elseif ('later' === $set) {
63
 
64
  // error_log('saving later');
65
- $options['rating_threshold'] = $this->get_next_threshold($options['conversions_count']);
66
- update_option($this->option_name, $options);
67
  }
68
 
69
- wp_die(); // this is required to terminate immediately and return a proper response
70
- }
71
 
72
- public function ask_for_rating_notices_if_not_asked_before() {
 
73
 
74
- $wgact_ratings = get_option($this->option_name);
75
 
76
- if ( isset( $wgact_ratings['conversions_count'] ) ) {
77
 
78
- $this->conversions_count = $wgact_ratings['conversions_count'];
79
  // error_log('conversion count: ' . $wgact_ratings['conversions_count'] );
80
 
81
  // in rare cases this option has not been set
82
  // in those cases we set it to avoid further errors
83
- if(! isset($wgact_ratings['rating_done'])){
84
  $wgact_ratings['rating_done'] = false;
85
  update_option($this->option_name, $wgact_ratings);
86
  }
87
 
88
  // in rare cases this option has not been set
89
  // in those cases we set it to avoid further errors
90
- if(! isset($wgact_ratings['rating_threshold'])){
91
  $wgact_ratings['rating_threshold'] = 10;
92
  update_option($this->option_name, $wgact_ratings);
93
  }
94
 
95
- if((false === $wgact_ratings['rating_done'] && $this->conversions_count > $wgact_ratings['rating_threshold']) || ( defined( 'WGACT_ALWAYS_AKS_FOR_RATING' ) && true === WGACT_ALWAYS_AKS_FOR_RATING )){
96
 
97
- $this->ask_for_rating_notices($this->conversions_count);
98
  }
99
- } else {
100
 
101
- // set default settings for wgact_ratings
102
- update_option($this->option_name, $this->get_default_settings());
103
- }
104
- }
105
 
106
- private function get_next_threshold($conversions_count){
 
107
 
108
- return $conversions_count * 10;
109
- }
110
 
111
 
112
- private function get_default_settings(): array {
 
113
 
114
- return [
115
- 'conversions_count' => 1,
116
- 'rating_threshold' => 10,
117
- 'rating_done' => false,
118
  ];
119
- }
120
 
121
- // show an admin notice to ask for a plugin rating
122
- public function ask_for_rating_notices($conversions_count) {
 
123
 
124
- ?>
125
- <div class="notice notice-success wgact-rating-success-notice" style="display: none">
126
- <div style="color:#02830b;font-weight: bold">
127
 
128
  <span>
129
  <?php
130
  printf(
131
- /* translators: %d: the amount of purchase conversions that have been measured */
132
- esc_html__( 'Hey, I noticed that you tracked more than %d purchase conversions with the Google Ads Conversion Tracking plugin - that\'s awesome! Could you please do me a BIG favour and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation.', 'woocommerce-google-adwords-conversion-tracking-tag' ),
133
  $conversions_count
134
  );
135
  ?>
@@ -142,27 +143,27 @@ class Ask_For_Rating {
142
 
143
  <ul style="list-style-type: disc ;padding-left:20px">
144
  <li>
145
- <a id="rate-it" href="#">
146
- <?php esc_html_e( 'Ok, you deserve it', 'woocommerce-google-adwords-conversion-tracking-tag' ); ?>
147
  </a>
148
  </li>
149
  <li>
150
- <a id="maybe-later" href="#">
151
- <?php esc_html_e( 'Nope, maybe later', 'woocommerce-google-adwords-conversion-tracking-tag' ); ?>
152
  </a>
153
  </li>
154
  <li>
155
- <a id="already-did" href="#">
156
- <?php esc_html_e( 'I already did', 'woocommerce-google-adwords-conversion-tracking-tag' ); ?>
157
  </a>
158
  </li>
159
  </ul>
160
  </div>
161
 
162
 
163
- </div>
164
- <?php
165
 
166
- }
167
 
168
  }
2
 
3
  namespace WGACT\Classes\Admin;
4
 
5
+ if (!defined('ABSPATH')) {
6
+ exit; // Exit if accessed directly
7
  }
8
 
9
+ class Ask_For_Rating
10
+ {
11
 
12
  private $option_name = WGACT_DB_RATINGS;
 
13
 
14
+ public function __construct()
15
+ {
16
 
17
  // $options = get_option($this->option_name);
18
  // $options['conversions_count'] = 8;
21
  // $options['rating_done'] = false;
22
  // update_option($this->option_name,$options);
23
 
24
+ // ask for a rating in a plugin notice
25
+ add_action('admin_enqueue_scripts', [$this, 'wgact_rating_script']);
26
+ add_action('wp_ajax_wgact_dismissed_notice_handler', [$this, 'ajax_rating_notice_handler']);
27
+ add_action('admin_notices', [$this, 'ask_for_rating_notices_if_not_asked_before']);
28
+ }
29
 
30
+ public function wgact_rating_script()
31
+ {
32
 
33
+ wp_enqueue_script('wooptpm-ask-for-rating', plugin_dir_url(__DIR__) . '../js/admin/ask-for-rating.js', ['jquery'], WGACT_CURRENT_VERSION, true);
 
 
 
 
 
 
34
 
35
  // wp_localize_script(
36
  // 'ask-for-rating', // Handle
42
  // );
43
  }
44
 
45
+ // server side php ajax handler for the admin rating notice
46
+ public function ajax_rating_notice_handler()
47
+ {
48
 
49
+ $set = $_POST['set'];
50
 
51
+ $options = get_option($this->option_name);
52
 
53
+ if ('rating_done' === $set) {
54
 
55
  // error_log('saving rating done');
56
+ $options['rating_done'] = true;
57
+ update_option($this->option_name, $options);
58
 
59
+ } elseif ('later' === $set) {
60
 
61
  // error_log('saving later');
62
+ $options['rating_threshold'] = $this->get_next_threshold($options['conversions_count']);
63
+ update_option($this->option_name, $options);
64
  }
65
 
66
+ wp_die(); // this is required to terminate immediately and return a proper response
67
+ }
68
 
69
+ public function ask_for_rating_notices_if_not_asked_before()
70
+ {
71
 
72
+ $wgact_ratings = get_option($this->option_name);
73
 
74
+ if (isset($wgact_ratings['conversions_count'])) {
75
 
76
+ $conversions_count = $wgact_ratings['conversions_count'];
77
  // error_log('conversion count: ' . $wgact_ratings['conversions_count'] );
78
 
79
  // in rare cases this option has not been set
80
  // in those cases we set it to avoid further errors
81
+ if (!isset($wgact_ratings['rating_done'])) {
82
  $wgact_ratings['rating_done'] = false;
83
  update_option($this->option_name, $wgact_ratings);
84
  }
85
 
86
  // in rare cases this option has not been set
87
  // in those cases we set it to avoid further errors
88
+ if (!isset($wgact_ratings['rating_threshold'])) {
89
  $wgact_ratings['rating_threshold'] = 10;
90
  update_option($this->option_name, $wgact_ratings);
91
  }
92
 
93
+ if ((false === $wgact_ratings['rating_done'] && $conversions_count > $wgact_ratings['rating_threshold']) || (defined('WGACT_ALWAYS_AKS_FOR_RATING') && true === WGACT_ALWAYS_AKS_FOR_RATING)) {
94
 
95
+ $this->ask_for_rating_notices($conversions_count);
96
  }
97
+ } else {
98
 
99
+ // set default settings for wgact_ratings
100
+ update_option($this->option_name, $this->get_default_settings());
101
+ }
102
+ }
103
 
104
+ private function get_next_threshold($conversions_count)
105
+ {
106
 
107
+ return $conversions_count * 10;
108
+ }
109
 
110
 
111
+ private function get_default_settings(): array
112
+ {
113
 
114
+ return [
115
+ 'conversions_count' => 1,
116
+ 'rating_threshold' => 10,
117
+ 'rating_done' => false,
118
  ];
119
+ }
120
 
121
+ // show an admin notice to ask for a plugin rating
122
+ public function ask_for_rating_notices($conversions_count)
123
+ {
124
 
125
+ ?>
126
+ <div class="notice notice-success wgact-rating-success-notice" style="display: none">
127
+ <div style="color:#02830b;font-weight: bold">
128
 
129
  <span>
130
  <?php
131
  printf(
132
+ /* translators: %d: the amount of purchase conversions that have been measured */
133
+ esc_html__('Hey, I noticed that you tracked more than %d purchase conversions with the Google Ads Conversion Tracking plugin - that\'s awesome! Could you please do me a BIG favour and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation.', 'woocommerce-google-adwords-conversion-tracking-tag'),
134
  $conversions_count
135
  );
136
  ?>
143
 
144
  <ul style="list-style-type: disc ;padding-left:20px">
145
  <li>
146
+ <a id="rate-it" href="#">
147
+ <?php esc_html_e('Ok, you deserve it', 'woocommerce-google-adwords-conversion-tracking-tag'); ?>
148
  </a>
149
  </li>
150
  <li>
151
+ <a id="maybe-later" href="#">
152
+ <?php esc_html_e('Nope, maybe later', 'woocommerce-google-adwords-conversion-tracking-tag'); ?>
153
  </a>
154
  </li>
155
  <li>
156
+ <a id="already-did" href="#">
157
+ <?php esc_html_e('I already did', 'woocommerce-google-adwords-conversion-tracking-tag'); ?>
158
  </a>
159
  </li>
160
  </ul>
161
  </div>
162
 
163
 
164
+ </div>
165
+ <?php
166
 
167
+ }
168
 
169
  }
classes/admin/class-debug-info.php CHANGED
@@ -113,7 +113,7 @@ class Debug_info {
113
  return $html;
114
  }
115
 
116
- private function is_wp_rocket_js_concatenation()
117
  {
118
  if (is_plugin_active('wp-rocket/wp-rocket.php')) {
119
 
113
  return $html;
114
  }
115
 
116
+ private function is_wp_rocket_js_concatenation(): string
117
  {
118
  if (is_plugin_active('wp-rocket/wp-rocket.php')) {
119
 
classes/admin/class-environment-check.php CHANGED
@@ -24,13 +24,7 @@ class Environment_Check
24
 
25
  public function environment_check_script()
26
  {
27
- wp_enqueue_script(
28
- 'environment-check', // Handle
29
- plugin_dir_url(__DIR__) . '../js/admin/environment-check.js',
30
- ['jquery'],
31
- WGACT_CURRENT_VERSION,
32
- true
33
- );
34
  }
35
 
36
  public function ajax_environment_check_handler()
@@ -135,9 +129,20 @@ class Environment_Check
135
  return is_plugin_active('borlabs-cookie/borlabs-cookie.php');
136
  }
137
 
 
 
 
 
 
 
 
 
 
 
 
138
  public function is_woo_discount_rules_active(): bool
139
  {
140
- if(is_plugin_active('woo-discount-rules/woo-discount-rules.php') || is_plugin_active('woo-discount-rules-pro/woo-discount-rules-pro.php')){
141
  return true;
142
  } else {
143
  return false;
@@ -167,24 +172,40 @@ class Environment_Check
167
  public function permanent_compatibility_mode()
168
  {
169
  if ($this->is_wp_rocket_active()) $this->exclude_inline_scripts_from_wp_rocket();
170
-
171
- if ($this->is_sg_optimizer_active())
172
- {
173
  add_filter('sgo_javascript_combine_excluded_inline_content', [$this, 'sg_optimizer_js_exclude_combine_inline_content']);
174
  add_filter('sgo_js_minify_exclude', [$this, 'sg_optimizer_js_minify_exclude']);
 
175
  }
176
 
177
- if ($this->is_litespeed_active())
178
- {
179
  add_filter('litespeed_optm_js_defer_exc', [$this, 'litespeed_cache_js_defer_exc']);
180
  add_filter('litespeed_optimize_js_excludes', [$this, 'litespeed_optimize_js_excludes']);
181
  add_filter('litespeed_optm_cssjs', [$this, 'litespeed_optm_cssjs']);
182
 
183
-
184
-
185
  // litespeed_optm_cssjs
186
  // litespeed_optm_html_head
187
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
  public function litespeed_optm_cssjs($excludes)
@@ -194,8 +215,8 @@ class Environment_Check
194
 
195
  public function litespeed_optimize_js_excludes($excludes)
196
  {
197
- if(is_array($excludes)){
198
- $excludes = array_merge($excludes,$this->get_wooptpm_script_identifiers());
199
  }
200
 
201
  return $excludes;
@@ -203,42 +224,58 @@ class Environment_Check
203
 
204
  public function litespeed_cache_js_defer_exc($excludes): array
205
  {
206
- if(is_array($excludes)){
207
- $excludes = array_merge($excludes,$this->get_wooptpm_script_identifiers());
208
  }
209
  return $excludes;
210
  }
211
 
212
  public function sg_optimizer_js_exclude_combine_inline_content($exclude_list): array
213
  {
214
- if(is_array($exclude_list)) {
215
- $exclude_list = array_merge($exclude_list, $this->get_wooptpm_script_identifiers());
216
  }
217
 
 
 
 
 
218
  return $exclude_list;
219
  }
220
 
221
  public function sg_optimizer_js_minify_exclude($exclude_list)
222
  {
223
  $exclude_list[] = 'wooptpm-front-end-scripts';
224
- $exclude_list[] = 'front-end-scripts';
225
  $exclude_list[] = 'wooptpm-front-end-scripts-premium-only';
226
- $exclude_list[] = 'front-end-scripts-premium-only';
227
- $exclude_list[] = 'facebook';
228
- $exclude_list[] = 'script-blocker-warning';
229
- $exclude_list[] = 'admin-helpers';
230
- $exclude_list[] = 'admin-tabs';
231
- $exclude_list[] = 'selectWoo';
232
- $exclude_list[] = 'google-ads';
233
- $exclude_list[] = 'ga-ua-eec';
234
- $exclude_list[] = 'ga4-eec';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
  return $exclude_list;
237
  }
238
 
239
  public function exclude_inline_scripts_from_wp_rocket()
240
  {
241
- // error_log('test');
242
  $options = get_option('wp_rocket_settings');
243
  $update_options = false;
244
 
@@ -247,28 +284,28 @@ class Environment_Check
247
  foreach ($js_to_exclude as $string) {
248
 
249
  // add exclusions for inline js
250
- if (is_array($options['exclude_inline_js']) && !in_array($string, $options['exclude_inline_js'])) {
251
 
252
  array_push($options['exclude_inline_js'], $string);
253
  $update_options = true;
254
  }
255
 
256
  // add exclusions for js
257
- if (is_array($options['exclude_js']) && !in_array($string, $options['exclude_js'])) {
258
 
259
  array_push($options['exclude_js'], $string);
260
  $update_options = true;
261
  }
262
 
263
  // remove scripts from delay_js_scripts
264
- if (is_array($options['delay_js_scripts']) && in_array($string, $options['delay_js_scripts'])) {
265
 
266
  unset($options['delay_js_scripts'][array_search($string, $options['delay_js_scripts'])]);
267
  $update_options = true;
268
  }
269
 
270
  // exclude_defer_js
271
- if (is_array($options['exclude_defer_js']) && !in_array($string, $options['exclude_defer_js'])) {
272
 
273
  array_push($options['exclude_defer_js'], $string);
274
  $update_options = true;
@@ -300,6 +337,9 @@ class Environment_Check
300
  'optimize.js',
301
  'googleoptimize.com/optimize.js',
302
  'jQuery',
 
 
 
303
  'wooptpm',
304
  'wooptpmDataLayer',
305
  'window.wooptpmDataLayer',
24
 
25
  public function environment_check_script()
26
  {
27
+ wp_enqueue_script('wooptpm-environment-check', plugin_dir_url(__DIR__) . '../js/admin/environment-check.js', ['jquery'], WGACT_CURRENT_VERSION, true);
 
 
 
 
 
 
28
  }
29
 
30
  public function ajax_environment_check_handler()
129
  return is_plugin_active('borlabs-cookie/borlabs-cookie.php');
130
  }
131
 
132
+ public function is_wpml_woocommerce_multi_currency_active(): bool
133
+ {
134
+ global $woocommerce_wpml;
135
+
136
+ if (is_plugin_active('woocommerce-multilingual/wpml-woocommerce.php') && is_object($woocommerce_wpml->multi_currency)) {
137
+ return true;
138
+ } else {
139
+ return false;
140
+ }
141
+ }
142
+
143
  public function is_woo_discount_rules_active(): bool
144
  {
145
+ if (is_plugin_active('woo-discount-rules/woo-discount-rules.php') || is_plugin_active('woo-discount-rules-pro/woo-discount-rules-pro.php')) {
146
  return true;
147
  } else {
148
  return false;
172
  public function permanent_compatibility_mode()
173
  {
174
  if ($this->is_wp_rocket_active()) $this->exclude_inline_scripts_from_wp_rocket();
175
+
176
+ if ($this->is_sg_optimizer_active()) {
 
177
  add_filter('sgo_javascript_combine_excluded_inline_content', [$this, 'sg_optimizer_js_exclude_combine_inline_content']);
178
  add_filter('sgo_js_minify_exclude', [$this, 'sg_optimizer_js_minify_exclude']);
179
+ add_filter('sgo_javascript_combine_exclude_move_after', [$this, 'sgo_javascript_combine_exclude_move_after']);
180
  }
181
 
182
+ if ($this->is_litespeed_active()) {
 
183
  add_filter('litespeed_optm_js_defer_exc', [$this, 'litespeed_cache_js_defer_exc']);
184
  add_filter('litespeed_optimize_js_excludes', [$this, 'litespeed_optimize_js_excludes']);
185
  add_filter('litespeed_optm_cssjs', [$this, 'litespeed_optm_cssjs']);
186
 
 
 
187
  // litespeed_optm_cssjs
188
  // litespeed_optm_html_head
189
  }
190
+
191
+ if ($this->is_autoptimize_active()) {
192
+ add_filter('autoptimize_filter_js_consider_minified', [$this, 'autoptimize_filter_js_consider_minified']);
193
+ add_filter('autoptimize_filter_js_dontmove', [$this, 'autoptimize_filter_js_dontmove']);
194
+ }
195
+ }
196
+
197
+ // https://github.com/futtta/autoptimize/blob/37b13d4e19269bb2f50df123257de51afa37244f/classes/autoptimizeScripts.php#L387
198
+ public function autoptimize_filter_js_consider_minified()
199
+ {
200
+ $exclude_js[] = 'wooptpm.js';
201
+ return $exclude_js;
202
+ }
203
+
204
+ // https://github.com/futtta/autoptimize/blob/37b13d4e19269bb2f50df123257de51afa37244f/classes/autoptimizeScripts.php#L285
205
+ public function autoptimize_filter_js_dontmove($dontmove)
206
+ {
207
+ $dontmove[] = 'wooptpm.js';
208
+ return $dontmove;
209
  }
210
 
211
  public function litespeed_optm_cssjs($excludes)
215
 
216
  public function litespeed_optimize_js_excludes($excludes)
217
  {
218
+ if (is_array($excludes)) {
219
+ $excludes = array_merge($excludes, $this->get_wooptpm_script_identifiers());
220
  }
221
 
222
  return $excludes;
224
 
225
  public function litespeed_cache_js_defer_exc($excludes): array
226
  {
227
+ if (is_array($excludes)) {
228
+ $excludes = array_merge($excludes, $this->get_wooptpm_script_identifiers());
229
  }
230
  return $excludes;
231
  }
232
 
233
  public function sg_optimizer_js_exclude_combine_inline_content($exclude_list): array
234
  {
235
+ if (is_array($exclude_list)) {
236
+ $exclude_list = array_merge($exclude_list, $this->get_wooptpm_script_identifiers());
237
  }
238
 
239
+ // foreach ($this->get_wooptpm_script_identifiers() as $exclusion) {
240
+ // $exclude_list[] = $exclusion;
241
+ // }
242
+
243
  return $exclude_list;
244
  }
245
 
246
  public function sg_optimizer_js_minify_exclude($exclude_list)
247
  {
248
  $exclude_list[] = 'wooptpm-front-end-scripts';
 
249
  $exclude_list[] = 'wooptpm-front-end-scripts-premium-only';
250
+ $exclude_list[] = 'wooptpm';
251
+ $exclude_list[] = 'wooptpm-premium-only';
252
+ $exclude_list[] = 'wooptpm-facebook';
253
+ $exclude_list[] = 'wooptpm-script-blocker-warning';
254
+ $exclude_list[] = 'wooptpm-admin-helpers';
255
+ $exclude_list[] = 'wooptpm-admin-tabs';
256
+ $exclude_list[] = 'wooptpm-selectWoo';
257
+ $exclude_list[] = 'wooptpm-google-ads';
258
+ $exclude_list[] = 'wooptpm-ga-ua-eec';
259
+ $exclude_list[] = 'wooptpm-ga4-eec';
260
+ $exclude_list[] = 'jquery';
261
+ $exclude_list[] = 'jquery-cookie';
262
+ $exclude_list[] = 'jquery-core';
263
+ $exclude_list[] = 'jquery-migrate';
264
+
265
+ return $exclude_list;
266
+ }
267
+
268
+ public function sgo_javascript_combine_exclude_move_after($exclude_list): array
269
+ {
270
+ if (is_array($exclude_list)) {
271
+ $exclude_list = array_merge($exclude_list, $this->get_wooptpm_script_identifiers());
272
+ }
273
 
274
  return $exclude_list;
275
  }
276
 
277
  public function exclude_inline_scripts_from_wp_rocket()
278
  {
 
279
  $options = get_option('wp_rocket_settings');
280
  $update_options = false;
281
 
284
  foreach ($js_to_exclude as $string) {
285
 
286
  // add exclusions for inline js
287
+ if (array_key_exists('exclude_inline_js', $options) && is_array($options['exclude_inline_js']) && !in_array($string, $options['exclude_inline_js'])) {
288
 
289
  array_push($options['exclude_inline_js'], $string);
290
  $update_options = true;
291
  }
292
 
293
  // add exclusions for js
294
+ if (array_key_exists('exclude_js', $options) && is_array($options['exclude_js']) && !in_array($string, $options['exclude_js'])) {
295
 
296
  array_push($options['exclude_js'], $string);
297
  $update_options = true;
298
  }
299
 
300
  // remove scripts from delay_js_scripts
301
+ if (array_key_exists('delay_js_scripts', $options) && is_array($options['delay_js_scripts']) && in_array($string, $options['delay_js_scripts'])) {
302
 
303
  unset($options['delay_js_scripts'][array_search($string, $options['delay_js_scripts'])]);
304
  $update_options = true;
305
  }
306
 
307
  // exclude_defer_js
308
+ if (array_key_exists('exclude_defer_js', $options) && is_array($options['exclude_defer_js']) && !in_array($string, $options['exclude_defer_js'])) {
309
 
310
  array_push($options['exclude_defer_js'], $string);
311
  $update_options = true;
337
  'optimize.js',
338
  'googleoptimize.com/optimize.js',
339
  'jQuery',
340
+ 'jQuery.min.js',
341
+ 'jquery.js',
342
+ 'jquery.min.js',
343
  'wooptpm',
344
  'wooptpmDataLayer',
345
  'window.wooptpmDataLayer',
classes/admin/class-launch-deal.php CHANGED
@@ -48,13 +48,7 @@ class Launch_Deal
48
 
49
  public function wooptpm_launch_deal_front_end_script()
50
  {
51
- wp_enqueue_script(
52
- 'wooptpm-launch-deal', // Handle
53
- plugin_dir_url(__DIR__) . '../js/admin/launch-deal.js',
54
- ['jquery'],
55
- WGACT_CURRENT_VERSION,
56
- true
57
- );
58
  }
59
 
60
  // server side php ajax handler for the admin rating notice
48
 
49
  public function wooptpm_launch_deal_front_end_script()
50
  {
51
+ wp_enqueue_script('wooptpm-launch-deal', plugin_dir_url(__DIR__) . '../js/admin/launch-deal.js', ['jquery'], WGACT_CURRENT_VERSION, true);
 
 
 
 
 
 
52
  }
53
 
54
  // server side php ajax handler for the admin rating notice
classes/class-default-options.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WGACT\Classes;
4
+
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ exit; // Exit if accessed directly
7
+ }
8
+
9
+ class Default_Options {
10
+
11
+ // get the default options
12
+ public function get_default_options(): array
13
+ {
14
+ // default options settings
15
+ return [
16
+ 'google' => [
17
+ 'ads' => [
18
+ 'conversion_id' => '',
19
+ 'conversion_label' => '',
20
+ 'aw_merchant_id' => '',
21
+ 'product_identifier' => 0,
22
+ 'google_business_vertical' => 0,
23
+ 'dynamic_remarketing' => 0,
24
+ 'phone_conversion_number' => '',
25
+ 'phone_conversion_label' => '',
26
+ ],
27
+ 'analytics' => [
28
+ 'universal' => [
29
+ 'property_id' => '',
30
+ ],
31
+ 'ga4' => [
32
+ 'measurement_id' => '',
33
+ 'api_secret' => '',
34
+ ],
35
+ 'eec' => 0,
36
+ 'link_attribution' => 0,
37
+ ],
38
+ 'optimize' => [
39
+ 'container_id' => '',
40
+ ],
41
+ 'gtag' => [
42
+ 'deactivation' => 0,
43
+ ],
44
+ 'consent_mode' => [
45
+ 'active' => 0,
46
+ 'regions' => [],
47
+ ],
48
+ 'user_id' => 0,
49
+ ],
50
+ 'facebook' => [
51
+ 'pixel_id' => '',
52
+ 'capi_token' => '',
53
+ 'microdata' => 0,
54
+ ],
55
+ 'bing' => [
56
+ 'uet_tag_id' => ''
57
+ ],
58
+ 'twitter' => [
59
+ 'pixel_id' => ''
60
+ ],
61
+ 'pinterest' => [
62
+ 'pixel_id' => ''
63
+ ],
64
+ 'hotjar' => [
65
+ 'site_id' => ''
66
+ ],
67
+ 'shop' => [
68
+ 'order_total_logic' => 0,
69
+ 'cookie_consent_mgmt' => [
70
+ 'cookiebot' => [
71
+ 'active' => 0
72
+ ],
73
+ ],
74
+ 'order_deduplication' => 1
75
+ ],
76
+ 'general' => [
77
+ 'variations_output' => 1,
78
+ 'maximum_compatibility_mode' => 0,
79
+ 'pro_version_demo' => 0,
80
+ ],
81
+ 'db_version' => WGACT_DB_VERSION,
82
+ ];
83
+ }
84
+
85
+ public function update_with_defaults($array_input, $array_default)
86
+ {
87
+ foreach ($array_default as $key => $value) {
88
+ if (array_key_exists($key, $array_input)) {
89
+ if (is_array($value)) {
90
+ $array_input[$key] = $this->update_with_defaults($array_input[$key], $value);
91
+ }
92
+ } else {
93
+ $array_input[$key] = $value;
94
+ }
95
+ }
96
+
97
+ return $array_input;
98
+ }
99
+ }
classes/pixels/class-cookie-consent-management.php CHANGED
@@ -28,8 +28,8 @@ class Cookie_Consent_Management {
28
  public $pluginPrefix;
29
 
30
  // check if third party cookie prevention is active
31
- public function is_cookie_prevention_active() {
32
-
33
  $cookie_prevention = false;
34
 
35
  // use filter to set default to activate prevention
28
  public $pluginPrefix;
29
 
30
  // check if third party cookie prevention is active
31
+ public function is_cookie_prevention_active(): bool
32
+ {
33
  $cookie_prevention = false;
34
 
35
  // use filter to set default to activate prevention
classes/pixels/class-pixel-manager-base.php CHANGED
@@ -5,6 +5,8 @@ namespace WGACT\Classes\Pixels;
5
 
6
  use stdClass;
7
  use WC_Order;
 
 
8
 
9
  if (!defined('ABSPATH')) {
10
  exit; // Exit if accessed directly
@@ -18,12 +20,13 @@ class Pixel_Manager_Base
18
  protected $options;
19
  protected $options_obj;
20
 
21
- public function __construct()
22
  {
23
  /*
24
  * Initialize options
25
  */
26
- $this->options = get_option(WGACT_DB_OPTIONS_NAME);
 
27
 
28
  $this->options_obj = json_decode(json_encode($this->options));
29
 
@@ -83,7 +86,7 @@ class Pixel_Manager_Base
83
  // return;
84
  // }
85
 
86
- $product_attributes['product_id_compiled'] = $this->get_compiled_product_id($product_id, $product->get_sku(), '', $this->options);
87
 
88
  $product_attributes['dyn_r_ids'] = $this->get_dyn_r_ids($product);
89
 
@@ -112,7 +115,7 @@ class Pixel_Manager_Base
112
  } else {
113
  $user = $order->get_billing_email();
114
  }
115
- $is_new_customer = !$this->has_bought($user, $order);
116
 
117
  $order_total = 0 == $this->options_obj->shop->order_total_logic ? $order->get_subtotal() - $order->get_total_discount() : $order->get_total();
118
 
@@ -223,7 +226,7 @@ class Pixel_Manager_Base
223
  }
224
 
225
  // https://stackoverflow.com/a/46216073/4688612
226
- protected function has_bought($value = 0, $order): bool
227
  {
228
  global $wpdb;
229
 
@@ -286,8 +289,8 @@ class Pixel_Manager_Base
286
 
287
  protected function find_matching_product_variation_id($product_id, $attributes): int
288
  {
289
- return (new \WC_Product_Data_Store_CPT())->find_matching_product_variation(
290
- new \WC_Product($product_id),
291
  $attributes
292
  );
293
  }
5
 
6
  use stdClass;
7
  use WC_Order;
8
+ use WC_Product;
9
+ use WC_Product_Data_Store_CPT;
10
 
11
  if (!defined('ABSPATH')) {
12
  exit; // Exit if accessed directly
20
  protected $options;
21
  protected $options_obj;
22
 
23
+ public function __construct($options)
24
  {
25
  /*
26
  * Initialize options
27
  */
28
+ // $this->options = get_option(WGACT_DB_OPTIONS_NAME);
29
+ $this->options = $options;
30
 
31
  $this->options_obj = json_decode(json_encode($this->options));
32
 
86
  // return;
87
  // }
88
 
89
+ $product_attributes['product_id_compiled'] = $this->get_compiled_product_id($product_id, $product->get_sku(), $this->options, '');
90
 
91
  $product_attributes['dyn_r_ids'] = $this->get_dyn_r_ids($product);
92
 
115
  } else {
116
  $user = $order->get_billing_email();
117
  }
118
+ $is_new_customer = !$this->has_bought($order, $user);
119
 
120
  $order_total = 0 == $this->options_obj->shop->order_total_logic ? $order->get_subtotal() - $order->get_total_discount() : $order->get_total();
121
 
226
  }
227
 
228
  // https://stackoverflow.com/a/46216073/4688612
229
+ protected function has_bought($order, $value = 0): bool
230
  {
231
  global $wpdb;
232
 
289
 
290
  protected function find_matching_product_variation_id($product_id, $attributes): int
291
  {
292
+ return (new WC_Product_Data_Store_CPT())->find_matching_product_variation(
293
+ new WC_Product($product_id),
294
  $attributes
295
  );
296
  }
classes/pixels/class-pixel-manager.php CHANGED
@@ -4,6 +4,7 @@ namespace WGACT\Classes\Pixels;
4
 
5
  use stdClass ;
6
  use WC_Order ;
 
7
  use WGACT\Classes\Admin\Environment_Check ;
8
  use WGACT\Classes\Pixels\Bing\Bing_Pixel_Manager ;
9
  use WGACT\Classes\Pixels\Facebook\Facebook_Pixel_Manager ;
@@ -26,6 +27,7 @@ class Pixel_Manager extends Pixel_Manager_Base
26
  {
27
  use Trait_Product ;
28
  use Trait_Google ;
 
29
  protected $options ;
30
  protected $options_obj ;
31
  protected $cart ;
@@ -34,12 +36,14 @@ class Pixel_Manager extends Pixel_Manager_Base
34
  protected $transaction_deduper_timeout = 2000 ;
35
  protected $hotjar_pixel ;
36
  protected $dyn_r_ids ;
37
- public function __construct()
 
38
  {
39
  /*
40
  * Initialize options
41
  */
42
- $this->options = get_option( WGACT_DB_OPTIONS_NAME );
 
43
  $this->options_obj = json_decode( json_encode( $this->options ) );
44
  $this->options_obj->shop->currency = new stdClass();
45
  $this->options_obj->shop->currency = get_woocommerce_currency();
@@ -58,19 +62,20 @@ class Pixel_Manager extends Pixel_Manager_Base
58
  $this->inject_woopt_opening();
59
  $this->inject_data_layer_init();
60
  $this->inject_data_layer_shop();
61
- $this->inject_data_layer_product();
 
62
  } );
63
  /*
64
  * Initialize all pixels
65
  */
66
  if ( $this->google_active ) {
67
- new Google_Pixel_Manager();
68
  }
69
  if ( $this->facebook_active ) {
70
- new Facebook_Pixel_Manager();
71
  }
72
  if ( $this->options_obj->hotjar->site_id ) {
73
- $this->hotjar_pixel = new Hotjar_Pixel();
74
  }
75
  add_action( 'wp_head', function () {
76
  $this->inject_woopt_closing();
@@ -96,40 +101,149 @@ class Pixel_Manager extends Pixel_Manager_Base
96
  /*
97
  * Process short codes
98
  */
99
- new Shortcodes( $this->options, $this->options_obj );
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
 
102
- public function woopt_wp_footer()
 
103
  {
104
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
105
- ( new Google_Analytics_Refund() )->process_refund_to_frontend__premium_only();
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
107
  }
108
 
109
- public function output_gtag_login()
 
110
  {
111
- error_log( 'xxlog' );
112
- ?>
113
- xxlog
114
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
 
117
  private function inject_data_layer_init()
118
  {
 
 
 
 
 
 
 
 
 
119
  ?>
120
 
121
  <script>
122
- window.wooptpmDataLayer = window.wooptpmDataLayer || [];
123
- window.wooptpmDataLayer.cart = window.wooptpmDataLayer.cart || {};
124
- window.wooptpmDataLayer.pixels = window.wooptpmDataLayer.pixels || {};
125
- window.wooptpmDataLayer.orderDeduplication = <?php
126
- echo ( $this->options['shop']['order_deduplication'] && !$this->is_nodedupe_parameter_set() ? 'true' : 'false' ) ;
 
 
 
 
 
 
 
 
127
  ?>;
 
128
  </script>
129
 
130
  <?php
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  public function inject_woopt_opening()
134
  {
135
  if ( ( new Environment_Check() )->is_autoptimize_active() ) {
@@ -181,28 +295,36 @@ class Pixel_Manager extends Pixel_Manager_Base
181
  // error_log(print_r($value['data'], true));
182
  $product = wc_get_product( $value['data']->get_id() );
183
  $data['cart_item_keys'][$cart_item] = [
184
- 'id' => $product->get_id(),
185
- 'is_variation' => false,
186
  ];
187
  $data['cart'][$product->get_id()] = [
188
- 'id' => (string) $product->get_id(),
189
- 'dyn_r_ids' => (array) $this->get_dyn_r_ids( $product ),
190
- 'name' => (string) $product->get_name(),
191
- 'brand' => (string) $this->get_brand_name( $product->get_id() ),
192
- 'quantity' => (int) $value['quantity'],
193
- 'price' => (double) $product->get_price(),
194
- 'is_variation' => false,
195
  ];
196
- // error_log('id: ' . $product->get_id());
197
- // error_log('type: ' . $product->get_type());
198
 
199
- if ( $product->is_type( 'variation' ) ) {
200
- // error_log('is variation');
201
- $data['cart'][$product->get_id()]['parent_id'] = (string) $product->get_parent_id();
202
- $data['cart'][$product->get_id()]['is_variation'] = true;
203
- $data['cart'][$product->get_id()]['category'] = $this->get_product_category( $product->get_parent_id() );
204
- $data['cart_item_keys'][$cart_item]['parent_id'] = (string) $product->get_parent_id();
205
- $data['cart_item_keys'][$cart_item]['is_variation'] = true;
 
 
 
 
 
 
 
 
 
 
206
  } else {
207
  $data['cart'][$product->get_id()]['category'] = $this->get_product_category( $product->get_id() );
208
  }
@@ -215,13 +337,13 @@ class Pixel_Manager extends Pixel_Manager_Base
215
  public function wooptpm_front_end_scripts()
216
  {
217
  wp_enqueue_script(
218
- 'wooptpm-front-end-scripts',
219
  plugin_dir_url( __DIR__ ) . '../js/public/wooptpm.js',
220
- [],
221
  WGACT_CURRENT_VERSION,
222
  false
223
  );
224
- wp_localize_script( 'wooptpm-front-end-scripts', 'ajax_object', [
225
  'ajax_url' => admin_url( 'admin-ajax.php' ),
226
  ] );
227
  }
@@ -240,26 +362,51 @@ class Pixel_Manager extends Pixel_Manager_Base
240
  $data = [];
241
 
242
  if ( is_product_category() ) {
243
- $data['list_name'] = 'Product Category';
 
244
  $data['page_type'] = 'product_category';
245
  } elseif ( is_product_tag() ) {
246
- $data['list_name'] = 'Product Tag';
 
247
  $data['page_type'] = 'product_tag';
248
  } elseif ( is_search() ) {
249
  $data['list_name'] = 'Product Search';
 
250
  $data['page_type'] = 'search';
251
  } elseif ( is_shop() ) {
252
  $data['list_name'] = 'Shop';
 
253
  $data['page_type'] = 'product_shop';
254
  } elseif ( is_product() ) {
 
 
255
  $data['page_type'] = 'product';
256
  $product = wc_get_product();
257
  $data['product_type'] = $product->get_type();
258
  } elseif ( is_cart() ) {
259
- $data['list_name'] = '';
 
260
  $data['page_type'] = 'cart';
261
  } else {
262
- $data['list_name'] = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
 
265
  $data['currency'] = get_woocommerce_currency();
@@ -273,11 +420,27 @@ class Pixel_Manager extends Pixel_Manager_Base
273
  <?php
274
  }
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  private function inject_data_layer_product()
277
  {
278
  global $wp_query, $woocommerce ;
279
 
280
  if ( is_shop() || is_product_category() || is_product_tag() || is_search() ) {
 
281
  $product_ids = [];
282
  $posts = $wp_query->posts;
283
  foreach ( $posts as $key => $post ) {
@@ -391,11 +554,11 @@ class Pixel_Manager extends Pixel_Manager_Base
391
  <script>
392
  jQuery(function () {
393
  setTimeout(function () {
394
- if (typeof wooptpm !== "undefined") {
395
  wooptpm.writeOrderIdToStorage(<?php
396
  echo $order_id ;
397
  ?>);
398
- }
399
  }, <?php
400
  echo $this->transaction_deduper_timeout ;
401
  ?>);
4
 
5
  use stdClass ;
6
  use WC_Order ;
7
+ use WC_Product_Variation ;
8
  use WGACT\Classes\Admin\Environment_Check ;
9
  use WGACT\Classes\Pixels\Bing\Bing_Pixel_Manager ;
10
  use WGACT\Classes\Pixels\Facebook\Facebook_Pixel_Manager ;
27
  {
28
  use Trait_Product ;
29
  use Trait_Google ;
30
+ use Trait_Shop ;
31
  protected $options ;
32
  protected $options_obj ;
33
  protected $cart ;
36
  protected $transaction_deduper_timeout = 2000 ;
37
  protected $hotjar_pixel ;
38
  protected $dyn_r_ids ;
39
+ protected $position = 1 ;
40
+ public function __construct( $options )
41
  {
42
  /*
43
  * Initialize options
44
  */
45
+ // $this->options = get_option(WGACT_DB_OPTIONS_NAME);
46
+ $this->options = $options;
47
  $this->options_obj = json_decode( json_encode( $this->options ) );
48
  $this->options_obj->shop->currency = new stdClass();
49
  $this->options_obj->shop->currency = get_woocommerce_currency();
62
  $this->inject_woopt_opening();
63
  $this->inject_data_layer_init();
64
  $this->inject_data_layer_shop();
65
+ $this->inject_data_layer_general();
66
+ // $this->inject_data_layer_product();
67
  } );
68
  /*
69
  * Initialize all pixels
70
  */
71
  if ( $this->google_active ) {
72
+ new Google_Pixel_Manager( $this->options );
73
  }
74
  if ( $this->facebook_active ) {
75
+ new Facebook_Pixel_Manager( $this->options );
76
  }
77
  if ( $this->options_obj->hotjar->site_id ) {
78
+ $this->hotjar_pixel = new Hotjar_Pixel( $this->options );
79
  }
80
  add_action( 'wp_head', function () {
81
  $this->inject_woopt_closing();
101
  /*
102
  * Process short codes
103
  */
104
+ new Shortcodes( $this->options );
105
+ add_action(
106
+ 'woocommerce_after_shop_loop_item',
107
+ [ $this, 'action_woocommerce_after_shop_loop_item' ],
108
+ 10,
109
+ 1
110
+ );
111
+ add_filter(
112
+ 'woocommerce_blocks_product_grid_item_html',
113
+ [ $this, 'wc_add_date_to_gutenberg_block' ],
114
+ 10,
115
+ 3
116
+ );
117
+ add_filter( 'woocommerce_after_add_to_cart_form', [ $this, 'woocommerce_after_add_to_cart_form' ] );
118
  }
119
 
120
+ // on product page
121
+ public function woocommerce_after_add_to_cart_form()
122
  {
123
+ global $product ;
124
+ echo $this->get_product_data_layer_script( $product, false ) ;
125
+ if ( $product->is_type( 'grouped' ) ) {
126
+ foreach ( $product->get_children() as $product_id ) {
127
+ $product = wc_get_product( $product_id );
128
+ echo $this->get_product_data_layer_script( $product, false ) ;
129
+ }
130
+ }
131
+ if ( $product->is_type( 'variable' ) ) {
132
+ foreach ( $product->get_available_variations() as $key => $variation ) {
133
+ $variable_product = wc_get_product( $variation['variation_id'] );
134
+ if ( !is_bool( $variable_product ) ) {
135
+ echo $this->get_product_data_layer_script( $variable_product, false ) ;
136
+ }
137
+ }
138
  }
139
  }
140
 
141
+ // every product that's generated by the shop loop like shop page or a shortcode
142
+ public function action_woocommerce_after_shop_loop_item()
143
  {
144
+ global $product ;
145
+ echo $this->get_product_data_layer_script( $product ) ;
146
+ }
147
+
148
+ // product views generated by a gutenberg block instead of a shortcode
149
+ function wc_add_date_to_gutenberg_block( $html, $data, $product ) : string
150
+ {
151
+ return $html . $this->get_product_data_layer_script( $product );
152
+ }
153
+
154
+ private function get_product_data_layer_script( $product, $set_position = true ) : string
155
+ {
156
+ global $woocommerce_wpml ;
157
+ $this->dyn_r_ids = $this->get_dyn_r_ids( $product );
158
+
159
+ if ( ( new Environment_Check() )->is_wpml_woocommerce_multi_currency_active() ) {
160
+ $price = $woocommerce_wpml->multi_currency->prices->get_product_price_in_currency( $product->get_id(), get_woocommerce_currency() );
161
+ } else {
162
+ $price = $product->get_price();
163
+ }
164
+
165
+ $data = [
166
+ 'id' => (string) $product->get_id(),
167
+ 'sku' => (string) $product->get_sku(),
168
+ 'name' => (string) $product->get_name(),
169
+ 'price' => (int) $price,
170
+ 'brand' => $this->get_brand_name( $product->get_id() ),
171
+ 'category' => (array) $this->get_product_category( $product->get_id() ),
172
+ 'quantity' => (int) 1,
173
+ 'dyn_r_ids' => $this->dyn_r_ids,
174
+ 'isVariation' => false,
175
+ ];
176
+
177
+ if ( $product->get_type() == 'variation' ) {
178
+ $parent_product = wc_get_product( $product->get_parent_id() );
179
+ $data['name'] = $parent_product->get_name();
180
+ $data['isVariation'] = true;
181
+ $data['parentId'] = $parent_product->get_id();
182
+ $data['variant'] = $this->get_formatted_variant_text( $product );
183
+ }
184
+
185
+ $html = "\n <input type='hidden' class='wooptpmProductId' data-id='" . $product->get_id() . "'>\n <script>\n window.wooptpmDataLayer.products = window.wooptpmDataLayer.products || {};\n window.wooptpmDataLayer.products[" . $product->get_id() . "] = " . json_encode( $data ) . ";";
186
+ if ( $set_position === true ) {
187
+ $html .= "\n window.wooptpmDataLayer.products[{$product->get_id()}]['position'] = window.wooptpmDataLayer.position++;";
188
+ }
189
+ $html .= "</script>";
190
+ return $html;
191
+ }
192
+
193
+ public function woopt_wp_footer()
194
+ {
195
+ if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
196
+ ( new Google_Analytics_Refund( $this->options ) )->process_refund_to_frontend__premium_only();
197
+ }
198
  }
199
 
200
  private function inject_data_layer_init()
201
  {
202
+ $data = [
203
+ 'cart' => [],
204
+ 'cart_item_keys' => [],
205
+ 'pixels' => [],
206
+ 'orderDeduplication' => ( $this->options['shop']['order_deduplication'] && !$this->is_nodedupe_parameter_set() ? true : false ),
207
+ 'position' => (int) 1,
208
+ 'viewItemListTrigger' => (array) $this->view_item_list_trigger_settings(),
209
+ 'version' => (string) WGACT_CURRENT_VERSION,
210
+ ];
211
  ?>
212
 
213
  <script>
214
+
215
+ function wooptpmExists() {
216
+ return new Promise(function (resolve, reject) {
217
+ (function waitForWooptpm() {
218
+ if (window.wooptpm) return resolve();
219
+ setTimeout(waitForWooptpm, 30);
220
+ })();
221
+ });
222
+ }
223
+
224
+ window.wooptpmDataLayer = window.wooptpmDataLayer || {};
225
+ window.wooptpmDataLayer = <?php
226
+ echo json_encode( $data, JSON_FORCE_OBJECT ) ;
227
  ?>;
228
+
229
  </script>
230
 
231
  <?php
232
  }
233
 
234
+ public function view_item_list_trigger_settings() : array
235
+ {
236
+ $settings = [
237
+ 'testMode' => false,
238
+ 'backgroundColor' => 'green',
239
+ 'opacity' => 0.5,
240
+ 'repeat' => true,
241
+ 'timeout' => 1000,
242
+ 'threshold' => 0.8,
243
+ ];
244
+ return apply_filters( 'wooptpm_view_item_list_trigger_settings', $settings );
245
+ }
246
+
247
  public function inject_woopt_opening()
248
  {
249
  if ( ( new Environment_Check() )->is_autoptimize_active() ) {
295
  // error_log(print_r($value['data'], true));
296
  $product = wc_get_product( $value['data']->get_id() );
297
  $data['cart_item_keys'][$cart_item] = [
298
+ 'id' => (string) $product->get_id(),
299
+ 'isVariation' => false,
300
  ];
301
  $data['cart'][$product->get_id()] = [
302
+ 'id' => (string) $product->get_id(),
303
+ 'dyn_r_ids' => (array) $this->get_dyn_r_ids( $product ),
304
+ 'name' => (string) $product->get_name(),
305
+ 'brand' => (string) $this->get_brand_name( $product->get_id() ),
306
+ 'quantity' => (int) $value['quantity'],
307
+ 'price' => (double) $product->get_price(),
308
+ 'isVariation' => false,
309
  ];
 
 
310
 
311
+ if ( $product->get_type() == 'variation' ) {
312
+ $parent_product = wc_get_product( $product->get_parent_id() );
313
+ $data['cart'][$product->get_id()]['name'] = (string) $parent_product->get_name();
314
+ $data['cart'][$product->get_id()]['isVariation'] = true;
315
+ $data['cart'][$product->get_id()]['parentId'] = (string) $parent_product->get_id();
316
+ $data['cart'][$product->get_id()]['category'] = (array) $this->get_product_category( $product->get_parent_id() );
317
+ $variant_text_array = [];
318
+ $attributes = $product->get_attributes();
319
+ if ( $attributes ) {
320
+ foreach ( $attributes as $key => $value ) {
321
+ $key_name = str_replace( 'pa_', '', $key );
322
+ $variant_text_array[] = ucfirst( $key_name ) . ': ' . strtolower( $value );
323
+ }
324
+ }
325
+ $data['cart'][$product->get_id()]['variant'] = (string) implode( ' | ', $variant_text_array );
326
+ $data['cart_item_keys'][$cart_item]['parentId'] = (string) $product->get_parent_id();
327
+ $data['cart_item_keys'][$cart_item]['isVariation'] = true;
328
  } else {
329
  $data['cart'][$product->get_id()]['category'] = $this->get_product_category( $product->get_id() );
330
  }
337
  public function wooptpm_front_end_scripts()
338
  {
339
  wp_enqueue_script(
340
+ 'wooptpm',
341
  plugin_dir_url( __DIR__ ) . '../js/public/wooptpm.js',
342
+ [ 'jquery' ],
343
  WGACT_CURRENT_VERSION,
344
  false
345
  );
346
+ wp_localize_script( 'wooptpm', 'ajax_object', [
347
  'ajax_url' => admin_url( 'admin-ajax.php' ),
348
  ] );
349
  }
362
  $data = [];
363
 
364
  if ( is_product_category() ) {
365
+ $data['list_name'] = 'Product Category' . $this->get_list_name_suffix();
366
+ $data['list_id'] = 'product_category' . $this->get_list_id_suffix();
367
  $data['page_type'] = 'product_category';
368
  } elseif ( is_product_tag() ) {
369
+ $data['list_name'] = 'Product Tag' . $this->get_list_name_suffix();
370
+ $data['list_id'] = 'product_tag' . $this->get_list_id_suffix();
371
  $data['page_type'] = 'product_tag';
372
  } elseif ( is_search() ) {
373
  $data['list_name'] = 'Product Search';
374
+ $data['list_id'] = 'search';
375
  $data['page_type'] = 'search';
376
  } elseif ( is_shop() ) {
377
  $data['list_name'] = 'Shop';
378
+ $data['list_id'] = 'product_shop';
379
  $data['page_type'] = 'product_shop';
380
  } elseif ( is_product() ) {
381
+ $data['list_name'] = 'Product';
382
+ $data['list_id'] = 'product';
383
  $data['page_type'] = 'product';
384
  $product = wc_get_product();
385
  $data['product_type'] = $product->get_type();
386
  } elseif ( is_cart() ) {
387
+ $data['list_name'] = 'Cart';
388
+ $data['list_id'] = 'cart';
389
  $data['page_type'] = 'cart';
390
  } else {
391
+
392
+ if ( is_front_page() ) {
393
+ $data['list_name'] = 'Front Page';
394
+ $data['list_id'] = 'front_page';
395
+ $data['page_type'] = 'front_page';
396
+ } else {
397
+
398
+ if ( is_checkout() ) {
399
+ $data['list_name'] = 'Checkout Page';
400
+ $data['list_id'] = 'checkout';
401
+ $data['page_type'] = 'checkout';
402
+ } else {
403
+ $data['list_name'] = '';
404
+ $data['list_id'] = '';
405
+ $data['page_type'] = '';
406
+ }
407
+
408
+ }
409
+
410
  }
411
 
412
  $data['currency'] = get_woocommerce_currency();
420
  <?php
421
  }
422
 
423
+ private function inject_data_layer_general()
424
+ {
425
+ $data = [
426
+ 'variationsOutput' => ( $this->options_obj->general->variations_output ? true : false ),
427
+ ];
428
+ ?>
429
+
430
+ <script>
431
+ wooptpmDataLayer.general = <?php
432
+ echo json_encode( $data ) ;
433
+ ?>;
434
+ </script>
435
+ <?php
436
+ }
437
+
438
  private function inject_data_layer_product()
439
  {
440
  global $wp_query, $woocommerce ;
441
 
442
  if ( is_shop() || is_product_category() || is_product_tag() || is_search() ) {
443
+ // if (!is_cart() || !is_order_received_page()) {
444
  $product_ids = [];
445
  $posts = $wp_query->posts;
446
  foreach ( $posts as $key => $post ) {
554
  <script>
555
  jQuery(function () {
556
  setTimeout(function () {
557
+ wooptpmExists().then(function () {
558
  wooptpm.writeOrderIdToStorage(<?php
559
  echo $order_id ;
560
  ?>);
561
+ });
562
  }, <?php
563
  echo $this->transaction_deduper_timeout ;
564
  ?>);
classes/pixels/class-pixel.php CHANGED
@@ -4,7 +4,6 @@ namespace WGACT\Classes\Pixels;
4
 
5
  use stdClass;
6
  use WC_Geolocation;
7
- use WGACT\Classes\Admin\Environment_Check;
8
 
9
  if (!defined('ABSPATH')) {
10
  exit; // Exit if accessed directly
@@ -29,13 +28,13 @@ class Pixel
29
  protected $dyn_r_id_type;
30
  protected $pixel_name = '';
31
 
32
- public function __construct()
33
  {
34
  /*
35
  * Initialize options
36
  */
37
- $this->options = get_option(WGACT_DB_OPTIONS_NAME);
38
-
39
  $this->options_obj = json_decode(json_encode($this->options));
40
 
41
  $this->options_obj->shop->currency = new stdClass();
@@ -54,7 +53,10 @@ class Pixel
54
  $this->conversion_label = $this->options['google']['ads']['conversion_label'];
55
  $this->dynamic_remarketing = $this->options['google']['ads']['dynamic_remarketing'];
56
  $this->product_identifier = $this->options['google']['ads']['product_identifier'];
57
- $this->gtag_deactivation = $this->options['google']['gtag']['deactivation'];
 
 
 
58
  }
59
 
60
  // get an array with all cart product ids
@@ -70,7 +72,7 @@ class Pixel
70
  $product_id = $this->get_variation_or_product_id($cart_item, $this->options_obj->general->variations_output);
71
  $product = wc_get_product($product_id);
72
 
73
- $product_id_compiled = $this->get_compiled_product_id($product_id, $product->get_sku(),'', $this->options);
74
 
75
  array_push($cart_items, $product_id_compiled);
76
  }
@@ -98,47 +100,9 @@ class Pixel
98
 
99
 
100
 
101
- protected function get_order_item_ids($order): array
102
- {
103
- $order_items = $order->get_items();
104
- $order_items_array = [];
105
-
106
- foreach ((array)$order_items as $order_item) {
107
-
108
- $product_id = $this->get_variation_or_product_id($order_item->get_data(), $this->options_obj->general->variations_output);
109
 
110
- $product = wc_get_product($product_id);
111
 
112
- // only continue if WC retrieves a valid product
113
- if (!is_bool($product)) {
114
-
115
- $dyn_r_ids = $this->get_dyn_r_ids($product);
116
- $product_id_compiled = $dyn_r_ids[$this->get_dyn_r_id_type()];
117
- // $product_id_compiled = $this->get_compiled_product_id($product_id, $product->get_sku(), '', $this->options);
118
- array_push($order_items_array, $product_id_compiled);
119
- }
120
- }
121
 
122
- return $order_items_array;
123
- }
124
-
125
- protected function get_dyn_r_id_type (): string
126
- {
127
- // $dyn_r_id_type = '';
128
-
129
- if($this->options_obj->google->ads->product_identifier == 0) {
130
- $this->dyn_r_id_type = 'post_id';
131
- } elseif ($this->options_obj->google->ads->product_identifier == 1) {
132
- $this->dyn_r_id_type = 'gpf';
133
- } elseif ($this->options_obj->google->ads->product_identifier == 2) {
134
- $this->dyn_r_id_type = 'sku';
135
- }
136
-
137
- // if you want to change the dyn_r_id type for Google programmatically
138
- $this->dyn_r_id_type = apply_filters('wooptpm_product_id_type_for_' . $this->pixel_name, $this->dyn_r_id_type);
139
-
140
- return $this->dyn_r_id_type;
141
- }
142
 
143
 
144
  }
4
 
5
  use stdClass;
6
  use WC_Geolocation;
 
7
 
8
  if (!defined('ABSPATH')) {
9
  exit; // Exit if accessed directly
28
  protected $dyn_r_id_type;
29
  protected $pixel_name = '';
30
 
31
+ public function __construct($options)
32
  {
33
  /*
34
  * Initialize options
35
  */
36
+ // $this->options = get_option(WGACT_DB_OPTIONS_NAME);
37
+ $this->options = $options;
38
  $this->options_obj = json_decode(json_encode($this->options));
39
 
40
  $this->options_obj->shop->currency = new stdClass();
53
  $this->conversion_label = $this->options['google']['ads']['conversion_label'];
54
  $this->dynamic_remarketing = $this->options['google']['ads']['dynamic_remarketing'];
55
  $this->product_identifier = $this->options['google']['ads']['product_identifier'];
56
+
57
+ if(array_key_exists('gtag', $this->options['google'])){
58
+ $this->gtag_deactivation = $this->options['google']['gtag']['deactivation'];
59
+ }
60
  }
61
 
62
  // get an array with all cart product ids
72
  $product_id = $this->get_variation_or_product_id($cart_item, $this->options_obj->general->variations_output);
73
  $product = wc_get_product($product_id);
74
 
75
+ $product_id_compiled = $this->get_compiled_product_id($product_id, $product->get_sku(), $this->options,'');
76
 
77
  array_push($cart_items, $product_id_compiled);
78
  }
100
 
101
 
102
 
 
 
 
 
 
 
 
 
103
 
 
104
 
 
 
 
 
 
 
 
 
 
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
 
108
  }
classes/pixels/class-shortcodes.php CHANGED
@@ -12,9 +12,9 @@ class Shortcodes extends Pixel
12
  {
13
  use Trait_Google;
14
 
15
- public function __construct($options, $options_obj)
16
  {
17
- parent::__construct($options, $options_obj);
18
 
19
  add_shortcode('conversion-pixel', [$this, 'woopt_conversion_pixel']);
20
  }
12
  {
13
  use Trait_Google;
14
 
15
+ public function __construct($options)
16
  {
17
+ parent::__construct($options);
18
 
19
  add_shortcode('conversion-pixel', [$this, 'woopt_conversion_pixel']);
20
  }
classes/pixels/facebook/class-facebook-browser-pixel.php CHANGED
@@ -12,22 +12,26 @@ class Facebook_Browser_Pixel extends Pixel
12
  {
13
  protected $pixel_name;
14
 
15
- public function __construct()
16
  {
17
- parent::__construct();
18
 
19
  $this->pixel_name = 'facebook';
20
  }
21
 
22
  public function inject_everywhere()
23
  {
 
 
 
 
 
 
 
 
24
  // @formatter:off
25
  ?>
26
- wooptpmDataLayer.pixels.<?php echo $this->pixel_name ?> = {
27
- 'dynamic_remarketing': {
28
- 'id_type': '<?php echo $this->get_dyn_r_id_type() ?>'
29
- }
30
- };
31
 
32
  !function(f,b,e,v,n,t,s)
33
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
@@ -46,80 +50,35 @@ class Facebook_Browser_Pixel extends Pixel
46
 
47
  public function inject_search()
48
  {
49
- ?>
50
-
51
- fbq('track', 'Search');
52
- <?php
53
  }
54
 
55
- public function inject_product($product, $product_attributes)
56
  {
57
- $data = [
58
- 'content_type' => 'product',
59
- 'content_name' => (string)$product->get_name(),
60
- 'content_category' => $this->get_product_category($product->get_id()),
61
- 'content_ids' => $product_attributes['dyn_r_ids'][$this->get_dyn_r_id_type()],
62
- 'currency' => (string)$this->options_obj->shop->currency,
63
- 'value' => (float)$product->get_price(),
64
- ];
65
-
66
- ?>
67
-
68
- fbq('track', 'ViewContent', <?php echo json_encode($data) ?>);
69
- <?php
70
  }
71
 
72
- public function inject_cart($cart, $cart_total)
73
  {
74
- // AddToCart event is triggered in front-end event layer
75
  }
76
 
77
  public function inject_order_received_page($order, $order_total, $is_new_customer)
78
  {
79
  $data = [
80
  'value' => $order_total,
81
- 'currency' => $this->options_obj->shop->currency,
82
  'content_ids' => $this->get_order_item_ids($order),
83
  'content_type' => 'product',
84
  ];
85
 
86
- ?>
87
-
88
- if ((typeof wooptpm !== "undefined") && !wooptpm.isOrderIdStored(<?php echo $order->get_order_number() ?>)) {
89
- fbq('track', 'Purchase', <?php echo json_encode($data) ?>);
90
- }
91
-
92
- <?php
93
 
94
- // $html = "
95
- // if ((typeof wooptpm !== \"undefined\") && !wooptpm.isOrderIdStored(" . $order->get_order_number() . ")) {
96
- // fbq('track', 'Purchase', " . json_encode($data) . ");
97
- // }";
98
- //
99
- // echo $html;
100
  }
101
-
102
- // protected function get_order_item_ids($order): array
103
- // {
104
- // $order_items = $order->get_items();
105
- // $order_items_array = [];
106
- //
107
- // foreach ((array)$order_items as $order_item) {
108
- //
109
- // $product_id = $this->get_variation_or_product_id($order_item->get_data(), $this->options_obj->general->variations_output);
110
- //
111
- // $product = wc_get_product($product_id);
112
- //
113
- // // only continue if WC retrieves a valid product
114
- // if (!is_bool($product)) {
115
- //
116
- // $dyn_r_ids = $this->get_dyn_r_ids($product);
117
- // $product_id_compiled = $dyn_r_ids[$this->get_dyn_r_id_type()];
118
- //
119
- // array_push($order_items_array, $product_id_compiled);
120
- // }
121
- // }
122
- //
123
- // return $order_items_array;
124
- // }
125
  }
12
  {
13
  protected $pixel_name;
14
 
15
+ public function __construct($options)
16
  {
17
+ parent::__construct($options);
18
 
19
  $this->pixel_name = 'facebook';
20
  }
21
 
22
  public function inject_everywhere()
23
  {
24
+ $facebook_data_layer = [
25
+ 'dynamic_remarketing' => [
26
+ 'id_type' => $this->get_dyn_r_id_type(),
27
+ ],
28
+ 'pixel_id' => $this->options_obj->facebook->pixel_id,
29
+ ];
30
+
31
+
32
  // @formatter:off
33
  ?>
34
+ wooptpmDataLayer.pixels.<?php echo $this->pixel_name ?> = <?php echo json_encode($facebook_data_layer) ?>;
 
 
 
 
35
 
36
  !function(f,b,e,v,n,t,s)
37
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
50
 
51
  public function inject_search()
52
  {
53
+ // handled on front-end
 
 
 
54
  }
55
 
56
+ public function inject_cart($cart, $cart_total)
57
  {
58
+ // AddToCart event is triggered in front-end event layer
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
 
61
+ public function inject_product($product, $product_attributes)
62
  {
63
+ // handled on front-end
64
  }
65
 
66
  public function inject_order_received_page($order, $order_total, $is_new_customer)
67
  {
68
  $data = [
69
  'value' => $order_total,
70
+ 'currency' => get_woocommerce_currency(),
71
  'content_ids' => $this->get_order_item_ids($order),
72
  'content_type' => 'product',
73
  ];
74
 
75
+ echo "
76
+ wooptpmExists().then(function(){
77
+ if (!wooptpm.isOrderIdStored(". $order->get_order_number() . ")) {
78
+ fbq('track', 'Purchase', " . json_encode($data) . ");
79
+ }
80
+ });
 
81
 
82
+ ";
 
 
 
 
 
83
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  }
classes/pixels/facebook/class-facebook-pixel-manager-microdata.php CHANGED
@@ -12,10 +12,10 @@ class Facebook_Pixel_Manager_Microdata extends Pixel_Manager_Base
12
  {
13
  protected $facebook_microdata_pixel;
14
 
15
- public function __construct()
16
  {
17
- parent::__construct();
18
- $this->facebook_microdata_pixel = new Facebook_Microdata();
19
  }
20
 
21
  public function inject_product($product, $product_attributes)
12
  {
13
  protected $facebook_microdata_pixel;
14
 
15
+ public function __construct($options)
16
  {
17
+ parent::__construct($options);
18
+ $this->facebook_microdata_pixel = new Facebook_Microdata($options);
19
  }
20
 
21
  public function inject_product($product, $product_attributes)
classes/pixels/facebook/class-facebook-pixel-manager.php CHANGED
@@ -2,73 +2,95 @@
2
 
3
  namespace WGACT\Classes\Pixels\Facebook;
4
 
5
- use WGACT\Classes\Pixels\Pixel_Manager_Base;
 
6
 
7
- if (!defined('ABSPATH')) {
8
- exit; // Exit if accessed directly
 
9
  }
10
 
11
  class Facebook_Pixel_Manager extends Pixel_Manager_Base
12
  {
13
- protected $facebook_browser_pixel;
14
-
15
- public function __construct()
16
  {
17
- parent::__construct();
18
-
19
- add_action('wp_enqueue_scripts', [$this, 'wooptpm_facebook_front_end_scripts']);
20
-
21
- $this->facebook_browser_pixel = new Facebook_Browser_Pixel();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
-
24
  public function wooptpm_facebook_front_end_scripts()
25
  {
26
- wp_enqueue_script('facebook', plugin_dir_url(__DIR__) . '../../js/public/facebook.js', [], WGACT_CURRENT_VERSION, false);
 
 
 
 
 
 
27
  }
28
-
29
  public function inject_everywhere()
30
  {
31
  $this->facebook_browser_pixel->inject_everywhere();
32
  }
33
-
34
  public function inject_search()
35
  {
36
  $this->facebook_browser_pixel->inject_search();
37
  }
38
-
39
- public function inject_product($product, $product_attributes)
40
  {
41
- $this->facebook_browser_pixel->inject_product($product, $product_attributes);
42
  }
43
-
44
- public function inject_cart($cart, $cart_total)
45
  {
46
- $this->facebook_browser_pixel->inject_cart($cart, $cart_total);
47
  }
48
-
49
- public function inject_order_received_page($order, $order_total, $is_new_customer)
50
  {
51
- $this->facebook_browser_pixel->inject_order_received_page($order, $order_total, $is_new_customer);
52
  }
53
-
54
  protected function inject_opening_script_tag()
55
  {
56
- echo PHP_EOL;
57
- echo ' <!-- START Facebook scripts -->' . PHP_EOL;
58
- echo ' <script>';
59
- echo PHP_EOL;
60
  }
61
-
62
  protected function inject_closing_script_tag()
63
  {
64
- echo PHP_EOL;
65
- echo ' </script>';
66
- echo PHP_EOL;
67
- echo ' <!-- END Facebook scripts -->' . PHP_EOL;
68
  }
69
-
70
  protected function inject_closing_script_after_tag()
71
  {
72
-
73
  }
 
74
  }
2
 
3
  namespace WGACT\Classes\Pixels\Facebook;
4
 
5
+ use WGACT\Classes\Http\Facebook_CAPI ;
6
+ use WGACT\Classes\Pixels\Pixel_Manager_Base ;
7
 
8
+ if ( !defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ // Exit if accessed directly
11
  }
12
 
13
  class Facebook_Pixel_Manager extends Pixel_Manager_Base
14
  {
15
+ protected $facebook_browser_pixel ;
16
+ protected $facebook_capi ;
17
+ public function __construct( $options )
18
  {
19
+ parent::__construct( $options );
20
+ add_action( 'wp_enqueue_scripts', [ $this, 'wooptpm_facebook_front_end_scripts' ] );
21
+ $this->facebook_browser_pixel = new Facebook_Browser_Pixel( $options );
22
+
23
+ if ( wga_fs()->is__premium_only() && $this->options_obj->facebook->capi_token ) {
24
+ $this->facebook_capi = new Facebook_CAPI( $options );
25
+ // Save the Facebook session identifiers on the order so that we can use them later when the order gets paid or completed
26
+ // https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-checkout.html#source-view.403
27
+ add_action( 'woocommerce_checkout_order_created', [ $this, 'facebook_save_session_identifiers_on_order__premium_only' ] );
28
+ // Process the purchase through Facebook CAPI when they are paid,
29
+ // or when they are manually completed.
30
+ add_action( 'woocommerce_order_status_processing', [ $this, 'facebook_capi_report_purchase__premium_only' ] );
31
+ add_action( 'woocommerce_payment_complete', [ $this, 'facebook_capi_report_purchase__premium_only' ] );
32
+ add_action( 'woocommerce_order_status_completed', [ $this, 'facebook_capi_report_purchase__premium_only' ] );
33
+ // Process subscription renewals
34
+ // https://docs.woocommerce.com/document/subscriptions/develop/action-reference/
35
+ // add_action('woocommerce_subscription_renewal_payment_complete', [$this, 'facebook_capi_report_subscription_purchase_renewal__premium_only']);
36
+ }
37
+
38
  }
39
+
40
  public function wooptpm_facebook_front_end_scripts()
41
  {
42
+ wp_enqueue_script(
43
+ 'wooptpm-facebook',
44
+ plugin_dir_url( __DIR__ ) . '../../js/public/facebook.js',
45
+ [ 'jquery', 'wooptpm' ],
46
+ WGACT_CURRENT_VERSION,
47
+ true
48
+ );
49
  }
50
+
51
  public function inject_everywhere()
52
  {
53
  $this->facebook_browser_pixel->inject_everywhere();
54
  }
55
+
56
  public function inject_search()
57
  {
58
  $this->facebook_browser_pixel->inject_search();
59
  }
60
+
61
+ public function inject_product( $product, $product_attributes )
62
  {
63
+ $this->facebook_browser_pixel->inject_product( $product, $product_attributes );
64
  }
65
+
66
+ public function inject_cart( $cart, $cart_total )
67
  {
68
+ $this->facebook_browser_pixel->inject_cart( $cart, $cart_total );
69
  }
70
+
71
+ public function inject_order_received_page( $order, $order_total, $is_new_customer )
72
  {
73
+ $this->facebook_browser_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
74
  }
75
+
76
  protected function inject_opening_script_tag()
77
  {
78
+ echo PHP_EOL ;
79
+ echo ' <!-- START Facebook scripts -->' . PHP_EOL ;
80
+ echo ' <script>' ;
81
+ echo PHP_EOL ;
82
  }
83
+
84
  protected function inject_closing_script_tag()
85
  {
86
+ echo PHP_EOL ;
87
+ echo ' </script>' ;
88
+ echo PHP_EOL ;
89
+ echo ' <!-- END Facebook scripts -->' . PHP_EOL ;
90
  }
91
+
92
  protected function inject_closing_script_after_tag()
93
  {
 
94
  }
95
+
96
  }
classes/pixels/google/class-google-ads.php CHANGED
@@ -12,9 +12,9 @@ class Google_Ads extends Google
12
 
13
  protected $google_business_vertical;
14
 
15
- public function __construct()
16
  {
17
- parent::__construct();
18
 
19
  add_action('wp_enqueue_scripts', [$this, 'wooptpm_google_ads_front_end_scripts']);
20
 
@@ -23,39 +23,22 @@ class Google_Ads extends Google
23
 
24
  public function wooptpm_google_ads_front_end_scripts()
25
  {
26
- wp_enqueue_script('google-ads', plugin_dir_url(__DIR__) . '../../js/public/google_ads.js', [], WGACT_CURRENT_VERSION, false);
27
  }
28
 
29
  public function inject_product_list($list_name)
30
  {
31
- global $wp_query;
32
-
33
- ?>
34
-
35
- gtag('event', '<?php echo $list_name ?>', {
36
- 'send_to': <?php echo json_encode($this->get_google_ads_conversion_ids()) ?>,
37
- 'items' : <?php echo json_encode($this->get_products_from_wp_query($wp_query)) . PHP_EOL ?>
38
- });
39
- <?php
40
  }
41
 
42
  public function inject_product($product, $product_attributes)
43
  {
44
- $product_details = $this->get_gads_formatted_product_details_from_product_id($product->get_id());
45
-
46
- ?>
47
-
48
- gtag('event', 'view_item', {
49
- 'send_to': <?php echo json_encode($this->get_google_ads_conversion_ids()) ?>,
50
- 'value' : <?php echo $product_details['price'] ?>,
51
- 'items' : [<?php echo(json_encode($product_details)) ?>]
52
- });
53
- <?php
54
  }
55
 
56
  public function inject_cart($cart, $cart_total)
57
  {
58
- // triggered by front-end scripts
59
  }
60
 
61
  public function inject_order_received_page($order, $order_total, $is_new_customer)
@@ -177,15 +160,16 @@ class Google_Ads extends Google
177
 
178
  protected function get_dyn_remarketing_purchase_script($order, $order_total)
179
  {
180
- ?>
181
-
182
- if ((typeof wooptpm !== "undefined") && !wooptpm.isOrderIdStored(<?php echo $order->get_order_number() ?>)) {
183
- gtag('event', 'purchase', {
184
- 'send_to': <?php echo json_encode($this->get_google_ads_conversion_ids()) ?>,
185
- 'value' : <?php echo $order_total; ?>,
186
- 'items' : <?php echo (json_encode($this->get_formatted_order_items($order, 'ads'))) . PHP_EOL ?>
187
- });
188
- }
189
- <?php
 
190
  }
191
  }
12
 
13
  protected $google_business_vertical;
14
 
15
+ public function __construct($options)
16
  {
17
+ parent::__construct($options);
18
 
19
  add_action('wp_enqueue_scripts', [$this, 'wooptpm_google_ads_front_end_scripts']);
20
 
23
 
24
  public function wooptpm_google_ads_front_end_scripts()
25
  {
26
+ wp_enqueue_script('wooptpm-google-ads', plugin_dir_url(__DIR__) . '../../js/public/google-ads.js', ['jquery', 'wooptpm'], WGACT_CURRENT_VERSION, true);
27
  }
28
 
29
  public function inject_product_list($list_name)
30
  {
31
+ // handled on front-end
 
 
 
 
 
 
 
 
32
  }
33
 
34
  public function inject_product($product, $product_attributes)
35
  {
36
+ // handled on front-end
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
  public function inject_cart($cart, $cart_total)
40
  {
41
+ // handled on front-end
42
  }
43
 
44
  public function inject_order_received_page($order, $order_total, $is_new_customer)
160
 
161
  protected function get_dyn_remarketing_purchase_script($order, $order_total)
162
  {
163
+ echo "
164
+ wooptpmExists().then(function(){
165
+ if (!wooptpm.isOrderIdStored(" . $order->get_order_number() . ")) {
166
+ gtag('event', 'purchase', {
167
+ 'send_to': " . json_encode($this->get_google_ads_conversion_ids()) . ",
168
+ 'value' : " . $order_total . ",
169
+ 'items' : " . (json_encode($this->get_formatted_order_items($order, 'ads'))) . "
170
+ });
171
+ }
172
+ });
173
+ ";
174
  }
175
  }
classes/pixels/google/class-google-analytics-4-eec.php CHANGED
@@ -11,93 +11,23 @@ class Google_Analytics_4_EEC extends Google_Analytics_4
11
  {
12
  use Trait_Google;
13
 
14
- public function __construct()
15
  {
16
- parent::__construct();
17
  }
18
 
19
  protected function output_view_item_list_html($items, $list_id)
20
  {
21
- $data = [
22
- 'send_to' => $this->options_obj->google->analytics->ga4->measurement_id,
23
- 'item_list_name' => $this->get_list_name_by_current_page_type($list_id),
24
- 'item_list_id' => $list_id,
25
- 'items' => $items
26
- ];
27
-
28
- //@formatter:off
29
- ?>
30
-
31
- gtag('event', 'view_item_list', <?php echo json_encode($data) ?>);
32
- <?php
33
- //@formatter:on
34
- }
35
-
36
- public function inject_product($product, $product_attributes)
37
- {
38
- $data = [
39
- 'send_to' => $this->options_obj->google->analytics->ga4->measurement_id,
40
- // 'value' => 0,
41
- // 'currency' => '',
42
- 'items' => [
43
- [
44
- 'item_id' => (string)$product->get_id(),
45
- 'item_name' => (string)$product->get_name(),
46
- 'quantity' => 1,
47
- // 'affiliation' => (string)'',
48
- // 'coupon' => '',
49
- // 'discount' => (float)0,
50
- 'item_brand' => (string)$product_attributes['brand'],
51
- 'item_category' => (array)$this->get_product_category($product->get_id()),
52
- // 'item_variant' => 'Black',
53
- 'price' => (int)$product->get_price(),
54
- // 'currency' => (string)'',
55
- ],
56
- ],
57
- ];
58
-
59
- //@formatter:off
60
- ?>
61
-
62
- gtag('event', 'view_item', <?php echo json_encode($data) ?>);
63
- <?php
64
- //@formatter:on
65
  }
66
 
67
  public function inject_cart($cart, $cart_total)
68
  {
69
- // triggered by front-end script
70
  }
71
 
72
- protected function eec_appweb_get_product_details_array($product_id, $list_id, $position = null): array
73
  {
74
- $list = $this->get_list_name_by_current_page_type($list_id);
75
-
76
- $product = wc_get_product($product_id);
77
-
78
- $data = [
79
- 'item_id' => (string)$product_id,
80
- 'item_name' => (string)$product->get_name(),
81
- 'quantity' => 1,
82
- // 'affiliation' => '',
83
- // 'coupon' => '',
84
- // 'discount' => 0,
85
- 'index' => (int)$position,
86
- 'item_brand' => (string)$this->get_brand_name($product_id),
87
- 'item_category' => (array)$this->get_product_category($product_id),
88
- 'item_list_name' => (string)$list,
89
- 'item_list_id' => (string)$list_id,
90
- // 'item_variant' => (string) $item['variant'],
91
- 'price' => (float)$product->get_price(),
92
- // 'currency' => '',
93
- ];
94
-
95
-
96
- if ($list) {
97
- $data['item_list_name'] = $list . $this->get_list_name_suffix();
98
- $data['item_list_id'] = $list_id . $this->get_list_id_suffix();
99
- }
100
-
101
- return $data;
102
  }
103
  }
11
  {
12
  use Trait_Google;
13
 
14
+ public function __construct($options)
15
  {
16
+ parent::__construct($options);
17
  }
18
 
19
  protected function output_view_item_list_html($items, $list_id)
20
  {
21
+ // handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
  public function inject_cart($cart, $cart_total)
25
  {
26
+ // handled on front-end
27
  }
28
 
29
+ public function inject_product($product, $product_attributes)
30
  {
31
+ // handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
  }
classes/pixels/google/class-google-analytics-4-standard.php CHANGED
@@ -9,8 +9,8 @@ if (!defined('ABSPATH')) {
9
 
10
  class Google_Analytics_4_Standard extends Google_Analytics_4
11
  {
12
- public function __construct()
13
  {
14
- parent::__construct();
15
  }
16
  }
9
 
10
  class Google_Analytics_4_Standard extends Google_Analytics_4
11
  {
12
+ public function __construct($options)
13
  {
14
+ parent::__construct($options);
15
  }
16
  }
classes/pixels/google/class-google-analytics-4.php CHANGED
@@ -11,23 +11,22 @@ class Google_Analytics_4 extends Google_Analytics
11
  {
12
  use Trait_Google;
13
 
14
- public function __construct()
15
  {
16
- parent::__construct();
17
  }
18
 
19
  public function inject_order_received_page($order, $order_total, $is_new_customer)
20
  {
21
  $order_currency = $this->get_order_currency($order);
22
- //@formatter:off
23
- ?>
24
-
25
- if ((typeof wooptpm !== "undefined") && !wooptpm.isOrderIdStored(<?php echo $order->get_order_number() ?>)) {
26
- gtag('event', 'purchase', <?php echo $this->get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer) ?>);
27
- }
28
- <?php
29
- //@formatter:on
30
 
 
 
 
 
 
 
 
31
  }
32
 
33
  protected function get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer, $channel = null)
@@ -67,16 +66,16 @@ class Google_Analytics_4 extends Google_Analytics
67
  'item_id' => $order_item_data['id'],
68
  'item_name' => $order_item_data['name'],
69
  'quantity' => $order_item_data['quantity'],
70
- // 'affiliation' => '',
71
  // 'coupon' => '',
72
  // 'discount' => 0,
73
  'item_brand' => $order_item_data['brand'],
74
  'item_category' => $order_item_data['category'],
75
- // 'item_variant' => '',
76
- // 'tax' => 0,
77
  'price' => $order_item_data['price'],
78
  // 'list_name' => ,
79
- // 'currency' => '',
80
  ];
81
 
82
  array_push($order_items_array, $item_details_array);
11
  {
12
  use Trait_Google;
13
 
14
+ public function __construct($options)
15
  {
16
+ parent::__construct($options);
17
  }
18
 
19
  public function inject_order_received_page($order, $order_total, $is_new_customer)
20
  {
21
  $order_currency = $this->get_order_currency($order);
 
 
 
 
 
 
 
 
22
 
23
+ echo "
24
+ wooptpmExists().then(function(){
25
+ if (!wooptpm.isOrderIdStored(" . $order->get_order_number() . ")) {
26
+ gtag('event', 'purchase', " . $this->get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer) . ");
27
+ }
28
+ });
29
+ ";
30
  }
31
 
32
  protected function get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer, $channel = null)
66
  'item_id' => $order_item_data['id'],
67
  'item_name' => $order_item_data['name'],
68
  'quantity' => $order_item_data['quantity'],
69
+ // 'affiliation' => $order_item_data['affiliation'],
70
  // 'coupon' => '',
71
  // 'discount' => 0,
72
  'item_brand' => $order_item_data['brand'],
73
  'item_category' => $order_item_data['category'],
74
+ 'item_variant' => $order_item_data['variant'],
75
+ // 'tax' => 0,
76
  'price' => $order_item_data['price'],
77
  // 'list_name' => ,
78
+ 'currency' => get_woocommerce_currency(),
79
  ];
80
 
81
  array_push($order_items_array, $item_details_array);
classes/pixels/google/class-google-analytics-refund-4.php CHANGED
@@ -2,19 +2,15 @@
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
- use WC_Order;
6
- use WC_Order_Refund;
7
- use WC_Product;
8
-
9
  if (!defined('ABSPATH')) {
10
  exit; // Exit if accessed directly
11
  }
12
 
13
  class Google_Analytics_Refund_4 extends Google_Analytics
14
  {
15
- public function __construct()
16
  {
17
- parent::__construct();
18
  }
19
 
20
  public function output_refund_to_frontend($order, $refund, $dataLayer_refund_items = null)
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
 
 
 
 
5
  if (!defined('ABSPATH')) {
6
  exit; // Exit if accessed directly
7
  }
8
 
9
  class Google_Analytics_Refund_4 extends Google_Analytics
10
  {
11
+ public function __construct($options)
12
  {
13
+ parent::__construct($options);
14
  }
15
 
16
  public function output_refund_to_frontend($order, $refund, $dataLayer_refund_items = null)
classes/pixels/google/class-google-analytics-refund-ua.php CHANGED
@@ -2,19 +2,15 @@
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
- use WC_Order;
6
- use WC_Order_Refund;
7
- use WC_Product;
8
-
9
  if (!defined('ABSPATH')) {
10
  exit; // Exit if accessed directly
11
  }
12
 
13
  class Google_Analytics_Refund_UA extends Google_Analytics
14
  {
15
- public function __construct()
16
  {
17
- parent::__construct();
18
  }
19
 
20
  public function output_refund_to_frontend($order, $refund, $dataLayer_refund_items = null)
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
 
 
 
 
5
  if (!defined('ABSPATH')) {
6
  exit; // Exit if accessed directly
7
  }
8
 
9
  class Google_Analytics_Refund_UA extends Google_Analytics
10
  {
11
+ public function __construct($options)
12
  {
13
+ parent::__construct($options);
14
  }
15
 
16
  public function output_refund_to_frontend($order, $refund, $dataLayer_refund_items = null)
classes/pixels/google/class-google-analytics-refund.php CHANGED
@@ -14,9 +14,9 @@ if ( !defined( 'ABSPATH' ) ) {
14
  class Google_Analytics_Refund extends Google_Analytics
15
  {
16
  use Trait_Google ;
17
- public function __construct()
18
  {
19
- parent::__construct();
20
  }
21
 
22
  }
14
  class Google_Analytics_Refund extends Google_Analytics
15
  {
16
  use Trait_Google ;
17
+ public function __construct( $options )
18
  {
19
+ parent::__construct( $options );
20
  }
21
 
22
  }
classes/pixels/google/class-google-analytics-ua-eec.php CHANGED
@@ -11,81 +11,22 @@ class Google_Analytics_UA_EEC extends Google_Analytics_UA
11
  {
12
  use Trait_Google;
13
 
14
- public function __construct()
15
  {
16
- parent::__construct();
17
  }
18
 
19
  protected function output_view_item_list_html($items, $list_id){
20
- //@formatter:off
21
- ?>
22
-
23
- gtag('event', 'view_item_list', {
24
- "send_to": '<?php echo $this->options_obj->google->analytics->universal->property_id ?>',
25
- "items": <?php echo json_encode($items) . PHP_EOL ?>
26
- });
27
- <?php
28
- //@formatter:on
29
- }
30
-
31
- public function inject_product($product, $product_attributes)
32
- {
33
- $data = [
34
- 'id' => (string)$product->get_id(),
35
- 'name' => (string)$product->get_name(),
36
- // 'list_name' => 'Search Results', // should probably be empty
37
- 'brand' => (string)$product_attributes['brand'],
38
- 'category' => $this->get_product_category($product->get_id()),
39
- // 'variant' => 'Black',
40
- 'list_position' => 1,
41
- 'quantity' => 1,
42
- 'price' => (int)$product->get_price(),
43
- ];
44
-
45
- //@formatter:off
46
- ?>
47
-
48
- gtag('event', 'view_item', {
49
- "send_to": '<?php echo $this->options_obj->google->analytics->universal->property_id ?>',
50
- "items": [<?php echo json_encode($data) ?>]
51
- });
52
- <?php
53
- //@formatter:on
54
  }
55
 
56
  public function inject_cart($cart, $cart_total)
57
  {
58
- // triggered by front-end script
59
  }
60
 
61
- protected function eec_appweb_get_product_details_array($product_id, $list_id, $position = null): array
62
  {
63
- $list = $this->get_list_name_by_current_page_type($list_id);
64
-
65
- $product = wc_get_product($product_id);
66
-
67
- $data = [
68
- 'id' => (string)$product_id,
69
- 'name' => (string)$product->get_name(),
70
- // 'list_name' => (string)$list,
71
- 'brand' => (string)$this->get_brand_name($product_id),
72
- 'category' => $this->get_product_category($product_id),
73
- // 'variant' => (string) $item['variant'],
74
- 'list_position' => (int)$position,
75
- 'quantity' => 1,
76
- 'price' => (float)$product->get_price(),
77
- ];
78
-
79
- // $data = $this->eec_add_product_categories_to_product_item($data, $product_id);
80
-
81
- if ($list) {
82
- $data['list_name'] = $list . $this->get_list_name_suffix();
83
- }
84
- // if ($list) $data['item_list_id'] = '';
85
- // if ($position) {
86
- // $data['index'] = $position;
87
- // }
88
-
89
- return $data;
90
  }
91
  }
11
  {
12
  use Trait_Google;
13
 
14
+ public function __construct($options)
15
  {
16
+ parent::__construct($options);
17
  }
18
 
19
  protected function output_view_item_list_html($items, $list_id){
20
+ // handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  public function inject_cart($cart, $cart_total)
24
  {
25
+ // handled on front-end
26
  }
27
 
28
+ public function inject_product($product, $product_attributes)
29
  {
30
+ // handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
  }
classes/pixels/google/class-google-analytics-ua-standard.php CHANGED
@@ -9,8 +9,8 @@ if (!defined('ABSPATH')) {
9
 
10
  class Google_Analytics_UA_Standard extends Google_Analytics_UA
11
  {
12
- public function __construct()
13
  {
14
- parent::__construct();
15
  }
16
  }
9
 
10
  class Google_Analytics_UA_Standard extends Google_Analytics_UA
11
  {
12
+ public function __construct($options)
13
  {
14
+ parent::__construct($options);
15
  }
16
  }
classes/pixels/google/class-google-analytics-ua.php CHANGED
@@ -9,23 +9,24 @@ if (!defined('ABSPATH')) {
9
 
10
  class Google_Analytics_UA extends Google_Analytics
11
  {
12
- public function __construct()
13
  {
14
- parent::__construct();
15
  }
16
 
17
  public function inject_order_received_page($order, $order_total, $is_new_customer)
18
  {
19
  $order_currency = $this->get_order_currency($order);
20
- //@formatter:off
21
- ?>
22
-
23
- if ((typeof wooptpm !== "undefined") && !wooptpm.isOrderIdStored(<?php echo $order->get_order_number() ?>)) {
24
- gtag('event', 'purchase', <?php echo $this->get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer) ?>);
25
- }
26
- <?php
27
- //@formatter:on
28
 
 
 
 
 
 
 
 
 
 
29
  }
30
 
31
  protected function get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer, $channel = null)
@@ -34,7 +35,7 @@ class Google_Analytics_UA extends Google_Analytics
34
  'send_to' => [],
35
  'transaction_id' => (string)$order->get_order_number(),
36
  'affiliation' => (string)get_bloginfo('name'),
37
- 'currency' => (string)$order_currency,
38
  'value' => (float)$order->get_total(),
39
  'discount' => (float)$order->get_total_discount(),
40
  'tax' => (float)$order->get_total_tax(),
@@ -62,14 +63,15 @@ class Google_Analytics_UA extends Google_Analytics
62
 
63
  $item_details_array = [
64
  'id' => $order_item_data['id'],
65
- 'quantity' => $order_item_data['quantity'],
66
- 'price' => $order_item_data['price'],
67
  'name' => $order_item_data['name'],
68
- // 'list_name' => ,
69
  'brand' => $order_item_data['brand'],
70
  'category' => $order_item_data['category'],
71
- // 'variant' => ,
 
72
  'list_position' => (int)$list_position++,
 
 
 
73
  ];
74
 
75
  array_push($order_items_array, $item_details_array);
9
 
10
  class Google_Analytics_UA extends Google_Analytics
11
  {
12
+ public function __construct($options)
13
  {
14
+ parent::__construct($options);
15
  }
16
 
17
  public function inject_order_received_page($order, $order_total, $is_new_customer)
18
  {
19
  $order_currency = $this->get_order_currency($order);
 
 
 
 
 
 
 
 
20
 
21
+ echo "
22
+ wooptpmExists().then(function(){
23
+ if (!wooptpm.isOrderIdStored(" . $order->get_order_number() . ")) {
24
+ gtag('event', 'purchase', " . $this->get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer) . ")
25
+ }
26
+ }).catch(() => {
27
+ console.log('couldn\'t run gtag for GA UA');
28
+ });
29
+ ";
30
  }
31
 
32
  protected function get_event_purchase_json($order, $order_total, $order_currency, $is_new_customer, $channel = null)
35
  'send_to' => [],
36
  'transaction_id' => (string)$order->get_order_number(),
37
  'affiliation' => (string)get_bloginfo('name'),
38
+ 'currency' => (string)$this->get_order_currency($order),
39
  'value' => (float)$order->get_total(),
40
  'discount' => (float)$order->get_total_discount(),
41
  'tax' => (float)$order->get_total_tax(),
63
 
64
  $item_details_array = [
65
  'id' => $order_item_data['id'],
 
 
66
  'name' => $order_item_data['name'],
 
67
  'brand' => $order_item_data['brand'],
68
  'category' => $order_item_data['category'],
69
+ // 'coupon' => '',
70
+ // 'list_name' => '',
71
  'list_position' => (int)$list_position++,
72
+ 'price' => $order_item_data['price'],
73
+ 'quantity' => $order_item_data['quantity'],
74
+ 'variant' => $order_item_data['variant'],
75
  ];
76
 
77
  array_push($order_items_array, $item_details_array);
classes/pixels/google/class-google-analytics.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
  use WGACT\Classes\Admin\Environment_Check;
 
6
 
7
  if (!defined('ABSPATH')) {
8
  exit; // Exit if accessed directly
@@ -10,9 +11,11 @@ if (!defined('ABSPATH')) {
10
 
11
  class Google_Analytics extends Google
12
  {
13
- public function __construct()
 
 
14
  {
15
- parent::__construct();
16
 
17
  $this->pixel_name = 'google_analytics';
18
  }
@@ -38,125 +41,30 @@ class Google_Analytics extends Google
38
  return $list_names[$list_id];
39
  }
40
 
41
- protected function wooptpm_get_order_item_price($order_item, $product): float
42
- {
43
- if ((new Environment_Check())->is_woo_discount_rules_active()) {
44
- $item_value = $order_item->get_meta('_advanced_woo_discount_item_total_discount');
45
- if (is_array($item_value) && array_key_exists('discounted_price', $item_value) && $item_value['discounted_price'] != 0) {
46
- return $item_value['discounted_price'];
47
- } elseif (is_array($item_value) && array_key_exists('initial_price', $item_value) && $item_value['initial_price'] != 0) {
48
- return $item_value['initial_price'];
49
- } else {
50
- return $product->get_price();
51
- }
52
- } else {
53
- return $product->get_price();
54
- }
55
- }
56
-
57
- protected function get_order_item_data($order_item): array
58
- {
59
- $product = $order_item->get_product();
60
-
61
- $dyn_r_ids = $this->get_dyn_r_ids($product);
62
-
63
- return [
64
- 'id' => (string)$dyn_r_ids[$this->get_ga_id_type()],
65
- 'name' => (string)$product->get_name(),
66
- 'quantity' => (int)$order_item['quantity'],
67
- // 'affiliation' => '',
68
- // 'coupon' => '',
69
- // 'discount' => 0,
70
- 'brand' => (string)$this->get_brand_name($product->get_id()),
71
- 'category' => (array)$this->get_product_category($product->get_id()),
72
- // 'variant' => ,
73
- // 'tax' => 0,
74
- 'price' => (float)$this->wooptpm_get_order_item_price($order_item, $product),
75
- // 'list_name' => ,
76
- // 'currency' => '',
77
-
78
- ];
79
- }
80
-
81
- protected function get_list_name_suffix(): string
82
- {
83
- $list_suffix = '';
84
-
85
- if (is_product_category()) {
86
-
87
- $category = get_queried_object();
88
- $list_suffix = ' | ' . $category->name;
89
- $list_suffix = $this->add_parent_category_name($category, $list_suffix);
90
- } else if (is_product_tag()) {
91
- $tag = get_queried_object();
92
- $list_suffix = ' | ' . $tag->name;
93
- }
94
-
95
- return $list_suffix;
96
- }
97
-
98
- protected function add_parent_category_name($category, $list_suffix)
99
- {
100
- if ($category->parent > 0) {
101
 
102
- $parent_category = get_term_by('id', $category->parent, 'product_cat');
103
- $list_suffix = ' | ' . $parent_category->name . $list_suffix;
104
- $list_suffix = $this->add_parent_category_name($parent_category, $list_suffix);
105
- }
106
 
107
- return $list_suffix;
108
- }
109
 
110
- protected function get_list_id_suffix(): string
111
- {
112
- $list_suffix = '';
113
 
114
- if (is_product_category()) {
115
-
116
- $category = get_queried_object();
117
- $list_suffix = '.' . $category->slug;
118
- $list_suffix = $this->add_parent_category_id($category, $list_suffix);
119
- } else if (is_product_tag()) {
120
- $tag = get_queried_object();
121
- $list_suffix = '.' . $tag->slug;
122
- }
123
-
124
- return $list_suffix;
125
- }
126
-
127
- protected function add_parent_category_id($category, $list_suffix)
128
- {
129
- if ($category->parent > 0) {
130
-
131
- $parent_category = get_term_by('id', $category->parent, 'product_cat');
132
- // error_log(print_r($parent_category, true));
133
- $list_suffix = '.' . $parent_category->slug . $list_suffix;
134
- $list_suffix = $this->add_parent_category_id($parent_category, $list_suffix);
135
- }
136
-
137
- return $list_suffix;
138
- }
139
-
140
- public function inject_product_list_object($list_id)
141
- {
142
- global $wp_query;
143
-
144
- $items = [];
145
-
146
- $position = 1;
147
-
148
- $posts = $wp_query->posts;
149
-
150
- foreach ($posts as $key => $post) {
151
-
152
- if ($post->post_type == 'product' || $post->post_type == 'product_variation') {
153
-
154
- array_push($items, $this->eec_appweb_get_product_details_array($post->ID, $list_id, $position));
155
-
156
- $position++;
157
- }
158
- }
159
-
160
- $this->output_view_item_list_html($items, $list_id);
161
- }
162
  }
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
  use WGACT\Classes\Admin\Environment_Check;
6
+ use WGACT\Classes\Pixels\Trait_Shop;
7
 
8
  if (!defined('ABSPATH')) {
9
  exit; // Exit if accessed directly
11
 
12
  class Google_Analytics extends Google
13
  {
14
+ use Trait_Shop;
15
+
16
+ public function __construct($options)
17
  {
18
+ parent::__construct($options);
19
 
20
  $this->pixel_name = 'google_analytics';
21
  }
41
  return $list_names[$list_id];
42
  }
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
 
 
 
 
45
 
 
 
46
 
 
 
 
47
 
48
+ // public function inject_product_list_object($list_id)
49
+ // {
50
+ // global $wp_query;
51
+ //
52
+ // $items = [];
53
+ //
54
+ // $position = 1;
55
+ //
56
+ // $posts = $wp_query->posts;
57
+ //
58
+ // foreach ($posts as $key => $post) {
59
+ //
60
+ // if ($post->post_type == 'product' || $post->post_type == 'product_variation') {
61
+ //
62
+ // array_push($items, $this->eec_appweb_get_product_details_array($post->ID, $list_id, $position));
63
+ //
64
+ // $position++;
65
+ // }
66
+ // }
67
+ //
68
+ // $this->output_view_item_list_html($items, $list_id);
69
+ // }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
classes/pixels/google/class-google-pixel-manager.php CHANGED
@@ -2,9 +2,8 @@
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
- use WC_Order ;
6
- use WC_Order_Refund ;
7
- use WC_Product ;
8
  use WGACT\Classes\Pixels\Pixel_Manager_Base ;
9
 
10
  if ( !defined( 'ABSPATH' ) ) {
@@ -20,35 +19,73 @@ class Google_Pixel_Manager extends Pixel_Manager_Base
20
  private $google_analytics_ua_standard_pixel ;
21
  private $google_analytics_4_standard_pixel ;
22
  private $google_analytics_ua_eec_pixel ;
 
 
23
  // private $google_analytics_ua_refund_pixel;
24
  private $google_analytics_4_eec_pixel ;
25
- public function __construct()
26
  {
27
- parent::__construct();
28
- $this->google_pixel = new Google();
29
  if ( $this->is_google_ads_active() ) {
30
  if ( $this->is_google_ads_active() ) {
31
- $this->google_ads_pixel = new Google_Ads();
32
  }
33
  }
34
  add_action( 'wp_enqueue_scripts', [ $this, 'google_front_end_scripts' ] );
35
 
36
- if ( !$this->options_obj->google->analytics->eec ) {
37
- $this->google_analytics_ua_standard_pixel = new Google_Analytics_UA_Standard();
38
- $this->google_analytics_4_standard_pixel = new Google_Analytics_4_Standard();
 
 
 
 
39
  } else {
 
 
 
40
 
41
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
42
- $this->google_analytics_ua_eec_pixel = new Google_Analytics_UA_EEC();
43
- // $this->google_analytics_ua_refund_pixel = new Google_Analytics_UA_Refund_Pixel();
44
- $this->google_analytics_4_eec_pixel = new Google_Analytics_4_EEC();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  add_action(
46
- 'woocommerce_order_refunded',
47
- [ $this, 'google_analytics_eec_action_woocommerce_order_refunded__premium_only' ],
48
  10,
49
  2
50
  );
51
- // add_action('wp_login', [$this,'output_gtag_login']);
 
 
52
  }
53
 
54
  }
@@ -101,102 +138,32 @@ class Google_Pixel_Manager extends Pixel_Manager_Base
101
 
102
  public function inject_product_category()
103
  {
104
- if ( $this->is_dynamic_remarketing_active() ) {
105
- $this->google_ads_pixel->inject_product_list( 'view_item_list' );
106
- }
107
-
108
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
109
- if ( $this->is_google_analytics_ua_active() ) {
110
- $this->google_analytics_ua_eec_pixel->inject_product_list_object( 'product_category' );
111
- }
112
- if ( $this->is_google_analytics_4_active() ) {
113
- $this->google_analytics_4_eec_pixel->inject_product_list_object( 'product_category' );
114
- }
115
- }
116
-
117
  }
118
 
119
  public function inject_product_tag()
120
  {
121
- if ( $this->is_dynamic_remarketing_active() ) {
122
- $this->google_ads_pixel->inject_product_list( 'view_item_list' );
123
- }
124
-
125
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
126
- if ( $this->is_google_analytics_ua_active() ) {
127
- $this->google_analytics_ua_eec_pixel->inject_product_list_object( 'product_tag' );
128
- }
129
- if ( $this->is_google_analytics_4_active() ) {
130
- $this->google_analytics_4_eec_pixel->inject_product_list_object( 'product_tag' );
131
- }
132
- }
133
-
134
  }
135
 
136
  public function inject_shop_top_page()
137
  {
138
- if ( $this->is_dynamic_remarketing_active() ) {
139
- $this->google_ads_pixel->inject_product_list( 'view_item_list' );
140
- }
141
-
142
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
143
- if ( $this->is_google_analytics_ua_active() ) {
144
- $this->google_analytics_ua_eec_pixel->inject_product_list_object( 'shop' );
145
- }
146
- if ( $this->is_google_analytics_4_active() ) {
147
- $this->google_analytics_4_eec_pixel->inject_product_list_object( 'shop' );
148
- }
149
- }
150
-
151
  }
152
 
153
  public function inject_search()
154
  {
155
- if ( $this->is_dynamic_remarketing_active() ) {
156
- $this->google_ads_pixel->inject_product_list( 'view_search_results' );
157
- }
158
-
159
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
160
- if ( $this->is_google_analytics_ua_active() ) {
161
- $this->google_analytics_ua_eec_pixel->inject_product_list_object( 'search' );
162
- }
163
- if ( $this->is_google_analytics_4_active() ) {
164
- $this->google_analytics_4_eec_pixel->inject_product_list_object( 'search' );
165
- }
166
- }
167
-
168
  }
169
 
170
  public function inject_product( $product, $product_attributes )
171
  {
172
- if ( $this->is_dynamic_remarketing_active() ) {
173
- $this->google_ads_pixel->inject_product( $product, $product_attributes );
174
- }
175
-
176
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
177
- if ( $this->is_google_analytics_ua_active() ) {
178
- $this->google_analytics_ua_eec_pixel->inject_product( $product, $product_attributes );
179
- }
180
- if ( $this->is_google_analytics_4_active() ) {
181
- $this->google_analytics_4_eec_pixel->inject_product( $product, $product_attributes );
182
- }
183
- }
184
-
185
  }
186
 
187
  public function inject_cart( $cart, $cart_total )
188
  {
189
- // Google Ads triggered by front-end scripts
190
-
191
- if ( wga_fs()->is__premium_only() && $this->options_obj->google->analytics->eec ) {
192
- if ( $this->is_google_analytics_ua_active() ) {
193
- $this->google_analytics_ua_eec_pixel->inject_cart( $cart, $cart_total );
194
- }
195
- if ( $this->is_google_analytics_4_active() ) {
196
- $this->google_analytics_4_eec_pixel->inject_cart( $cart, $cart_total );
197
- }
198
- }
199
-
200
  }
201
 
202
  public function inject_order_received_page( $order, $order_total, $is_new_customer )
@@ -205,7 +172,7 @@ class Google_Pixel_Manager extends Pixel_Manager_Base
205
  $this->google_ads_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
206
  }
207
 
208
- if ( !$this->options_obj->google->analytics->eec ) {
209
  if ( $this->is_google_analytics_ua_active() ) {
210
  $this->google_analytics_ua_standard_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
211
  }
@@ -213,6 +180,9 @@ class Google_Pixel_Manager extends Pixel_Manager_Base
213
  $this->google_analytics_4_standard_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
214
  }
215
  } else {
 
 
 
216
  }
217
 
218
  }
@@ -227,9 +197,10 @@ class Google_Pixel_Manager extends Pixel_Manager_Base
227
  protected function inject_closing_script_tag()
228
  {
229
  echo PHP_EOL ;
230
- echo ' </script>' ;
 
231
  echo PHP_EOL . PHP_EOL ;
232
- echo ' <!-- END Google scripts -->' . PHP_EOL ;
233
  }
234
 
235
  }
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
+ use WGACT\Classes\Http\Google_MP_GA4 ;
6
+ use WGACT\Classes\Http\Google_MP_UA ;
 
7
  use WGACT\Classes\Pixels\Pixel_Manager_Base ;
8
 
9
  if ( !defined( 'ABSPATH' ) ) {
19
  private $google_analytics_ua_standard_pixel ;
20
  private $google_analytics_4_standard_pixel ;
21
  private $google_analytics_ua_eec_pixel ;
22
+ private $google_analytics_ua_http_mp ;
23
+ private $google_analytics_4_http_mp ;
24
  // private $google_analytics_ua_refund_pixel;
25
  private $google_analytics_4_eec_pixel ;
26
+ public function __construct( $options )
27
  {
28
+ parent::__construct( $options );
29
+ $this->google_pixel = new Google( $options );
30
  if ( $this->is_google_ads_active() ) {
31
  if ( $this->is_google_ads_active() ) {
32
+ $this->google_ads_pixel = new Google_Ads( $options );
33
  }
34
  }
35
  add_action( 'wp_enqueue_scripts', [ $this, 'google_front_end_scripts' ] );
36
 
37
+ if ( !wga_fs()->is__premium_only() || !$this->options_obj->google->analytics->eec ) {
38
+ if ( $this->is_google_analytics_ua_active() ) {
39
+ $this->google_analytics_ua_standard_pixel = new Google_Analytics_UA_Standard( $options );
40
+ }
41
+ if ( $this->is_google_analytics_4_active() ) {
42
+ $this->google_analytics_4_standard_pixel = new Google_Analytics_4_Standard( $options );
43
+ }
44
  } else {
45
+ $this->google_analytics_ua_eec_pixel = new Google_Analytics_UA_EEC( $options );
46
+ // $this->google_analytics_ua_refund_pixel = new Google_Analytics_UA_Refund_Pixel();
47
+ $this->google_analytics_4_eec_pixel = new Google_Analytics_4_EEC( $options );
48
 
49
+ if ( $this->is_google_analytics_active() ) {
50
+ // woocommerce_order_status_refunded
51
+ // woocommerce_order_refunded
52
+ // woocommerce_order_partially_refunded
53
+ // https://github.com/woocommerce/woocommerce/blob/b19500728b4b292562afb65eb3a0c0f50d5859de/includes/wc-order-functions.php#L614
54
+ // woocommerce_order_fully_refunded
55
+ // https://github.com/woocommerce/woocommerce/blob/b19500728b4b292562afb65eb3a0c0f50d5859de/includes/wc-order-functions.php#L616
56
+ // how to tell if order is fully refunded
57
+ // https://github.com/woocommerce/woocommerce/blob/b19500728b4b292562afb65eb3a0c0f50d5859de/includes/wc-order-functions.php#L774
58
+ $this->google_analytics_ua_http_mp = new Google_MP_UA( $options );
59
+ $this->google_analytics_4_http_mp = new Google_MP_GA4( $options );
60
+ // error_log('running mp scripts');
61
+ // add_action('woocommerce_order_refunded', [$this, 'google_analytics_eec_action_woocommerce_order_refunded__premium_only'], 10, 2);
62
+ // Save the Google cid on the order so that we can use it later when the order gets paid or completed
63
+ // https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-checkout.html#source-view.403
64
+ add_action( 'woocommerce_checkout_order_created', [ $this, 'google_analytics_save_cid_on_order__premium_only' ] );
65
+ // Process the purchase through the GA Measurement Protocol when they are paid, when they change to processing, or
66
+ // when they are manually set to completed.
67
+ // https://docs.woocommerce.com/document/managing-orders/
68
+ // Maybe also use woocommerce_pre_payment_complete
69
+ // https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-order.html#source-view.105
70
+ add_action( 'woocommerce_order_status_processing', [ $this, 'google_analytics_mp_report_purchase__premium_only' ] );
71
+ add_action( 'woocommerce_payment_complete', [ $this, 'google_analytics_mp_report_purchase__premium_only' ] );
72
+ add_action( 'woocommerce_order_status_completed', [ $this, 'google_analytics_mp_report_purchase__premium_only' ] );
73
+ // Process total an partial refunds
74
+ add_action(
75
+ 'woocommerce_order_fully_refunded',
76
+ [ $this, 'google_analytics_mp_send_full_refund__premium_only' ],
77
+ 10,
78
+ 2
79
+ );
80
  add_action(
81
+ 'woocommerce_order_partially_refunded',
82
+ [ $this, 'google_analytics_mp_send_partial_refund__premium_only' ],
83
  10,
84
  2
85
  );
86
+ // Process subscription renewals
87
+ // https://docs.woocommerce.com/document/subscriptions/develop/action-reference/
88
+ add_action( 'woocommerce_subscription_renewal_payment_complete', [ $this, 'google_analytics_mp_report_subscription_purchase_renewal__premium_only' ] );
89
  }
90
 
91
  }
138
 
139
  public function inject_product_category()
140
  {
141
+ // all handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
 
144
  public function inject_product_tag()
145
  {
146
+ // all handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
  public function inject_shop_top_page()
150
  {
151
+ // all handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
  public function inject_search()
155
  {
156
+ // all handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
 
159
  public function inject_product( $product, $product_attributes )
160
  {
161
+ // handled on front-end
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
163
 
164
  public function inject_cart( $cart, $cart_total )
165
  {
166
+ // all handled on front-end
 
 
 
 
 
 
 
 
 
 
167
  }
168
 
169
  public function inject_order_received_page( $order, $order_total, $is_new_customer )
172
  $this->google_ads_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
173
  }
174
 
175
+ if ( !wga_fs()->is__premium_only() || !$this->options_obj->google->analytics->eec ) {
176
  if ( $this->is_google_analytics_ua_active() ) {
177
  $this->google_analytics_ua_standard_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
178
  }
180
  $this->google_analytics_4_standard_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
181
  }
182
  } else {
183
+ if ( $this->is_google_analytics_4_active() && !$this->options_obj->google->analytics->ga4->api_secret ) {
184
+ $this->google_analytics_4_eec_pixel->inject_order_received_page( $order, $order_total, $is_new_customer );
185
+ }
186
  }
187
 
188
  }
197
  protected function inject_closing_script_tag()
198
  {
199
  echo PHP_EOL ;
200
+ echo "\t\t" . '//# sourceURL=wooptpmGoogleInlineScripts.js' . PHP_EOL ;
201
+ echo "\t\t" . '</script>' ;
202
  echo PHP_EOL . PHP_EOL ;
203
+ echo "\t" . '<!-- END Google scripts -->' . PHP_EOL ;
204
  }
205
 
206
  }
classes/pixels/google/class-google.php CHANGED
@@ -14,9 +14,9 @@ class Google extends Pixel
14
  {
15
  use Trait_Google ;
16
  protected $google_ads_conversion_identifiers ;
17
- public function __construct()
18
  {
19
- parent::__construct();
20
  $this->google_business_vertical = $this->get_google_business_vertical( $this->options['google']['ads']['google_business_vertical'] );
21
  $this->google_ads_conversion_identifiers[$this->conversion_id] = $this->conversion_label;
22
  $this->google_ads_conversion_identifiers = apply_filters( 'wgact_google_ads_conversion_identifiers', $this->google_ads_conversion_identifiers );
@@ -26,30 +26,12 @@ class Google extends Pixel
26
  public function inject_everywhere()
27
  {
28
  $this->inject_data_layer_pixels();
29
-
30
  if ( $this->options_obj->google->optimize->container_id ) {
31
- $opt = "<script async src='https://www.googleoptimize.com/optimize.js?id=" . $this->options_obj->google->optimize->container_id . "'></script>";
32
- echo $opt ;
33
- }
34
-
35
-
36
- if ( !$this->options_obj->google->gtag->deactivation ) {
37
- ?>
38
-
39
- <script async src="https://www.googletagmanager.com/gtag/js?id=<?php
40
- echo $this->get_gtag_id() ;
41
- ?>"></script>
42
-
43
- <?php
44
- echo $this->get_modified_script_opening_tag() . PHP_EOL ;
45
- ?>
46
-
47
- <?php
48
- echo $this->get_google_init_js() ;
49
- } else {
50
- echo '<script>' ;
51
  }
52
-
 
 
53
  foreach ( $this->google_ads_conversion_identifiers as $conversion_id => $conversion_label ) {
54
  ?>
55
  <?php
@@ -79,12 +61,12 @@ class Google extends Pixel
79
  private function get_modified_script_opening_tag() : string
80
  {
81
  $cookiebot_snippet = ( $this->options_obj->shop->cookie_consent_mgmt->cookiebot->active ? ' data-cookieconsent="ignore"' : '' );
82
- return "<script" . $cookiebot_snippet . ">";
83
  }
84
 
85
  protected function get_google_init_js() : string
86
  {
87
- return "window.dataLayer = window.dataLayer || [];\n\n function gtag() {\n dataLayer.push(arguments);\n }\n " . $this->consent_mode_gtag_html() . "\n gtag('js', new Date());";
88
  }
89
 
90
  private function consent_mode_gtag_html() : string
@@ -165,13 +147,6 @@ class Google extends Pixel
165
  return $order_items_array;
166
  }
167
 
168
- protected function get_ga_id_type() : string
169
- {
170
- $ga_id_type = 'post_id';
171
- $ga_id_type = apply_filters( 'wooptpm_product_id_type_for_google_analytics', $ga_id_type );
172
- return $ga_id_type;
173
- }
174
-
175
  protected function get_event_purchase_json(
176
  $order,
177
  $order_total,
@@ -189,7 +164,7 @@ class Google extends Pixel
189
  ];
190
 
191
  if ( 'ads' === $channel ) {
192
- array_push( $gtag_data['send_to'], $this->get_google_ads_conversion_ids( true ) );
193
  $gtag_data['value'] = (double) $order_total;
194
  $gtag_data['aw_merchant_id'] = (int) $this->aw_merchant_id;
195
  $gtag_data['aw_feed_country'] = (string) $this->get_visitor_country();
@@ -267,7 +242,7 @@ class Google extends Pixel
267
  'google' => [
268
  'ads' => [
269
  'dynamic_remarketing' => [
270
- 'status' => $this->options_obj->google->ads->dynamic_remarketing,
271
  'id_type' => $this->get_dyn_r_id_type(),
272
  ],
273
  'conversionIds' => $this->get_google_ads_conversion_ids(),
@@ -281,6 +256,7 @@ class Google extends Pixel
281
  'measurement_id' => $this->options_obj->google->analytics->ga4->measurement_id,
282
  ],
283
  'id_type' => $this->get_ga_id_type(),
 
284
  ],
285
  ],
286
  ];
@@ -298,7 +274,7 @@ class Google extends Pixel
298
  {
299
 
300
  if ( 'ads' === $channel ) {
301
- return PHP_EOL . "\t\t\t\t" . "gtag('config', 'AW-" . $id . "');" . PHP_EOL;
302
  } elseif ( 'ga_ua' === $channel ) {
303
  $ga_ua_parameters = [
304
  'anonymize_ip' => 'true',
@@ -308,7 +284,7 @@ class Google extends Pixel
308
  $ga_ua_parameters['user_id'] = get_current_user_id();
309
  }
310
  $ga_ua_parameters = apply_filters( 'woopt_pm_analytics_parameters', $ga_ua_parameters, $id );
311
- return "\t\t" . "gtag('config', '" . $id . "', " . json_encode( $ga_ua_parameters ) . ");";
312
  } elseif ( 'ga_4' === $channel ) {
313
  if ( $this->options_obj->google->user_id && is_user_logged_in() ) {
314
  $ga_4_parameters = [
@@ -317,9 +293,9 @@ class Google extends Pixel
317
  }
318
 
319
  if ( empty($ga_4_parameters) ) {
320
- return "\t\t" . "gtag('config', '" . $id . "');";
321
  } else {
322
- return "\t\t" . "gtag('config', '" . $id . "', " . json_encode( $ga_4_parameters ) . ");";
323
  }
324
 
325
  }
14
  {
15
  use Trait_Google ;
16
  protected $google_ads_conversion_identifiers ;
17
+ public function __construct( $options )
18
  {
19
+ parent::__construct( $options );
20
  $this->google_business_vertical = $this->get_google_business_vertical( $this->options['google']['ads']['google_business_vertical'] );
21
  $this->google_ads_conversion_identifiers[$this->conversion_id] = $this->conversion_label;
22
  $this->google_ads_conversion_identifiers = apply_filters( 'wgact_google_ads_conversion_identifiers', $this->google_ads_conversion_identifiers );
26
  public function inject_everywhere()
27
  {
28
  $this->inject_data_layer_pixels();
 
29
  if ( $this->options_obj->google->optimize->container_id ) {
30
+ echo "<script async src='https://www.googleoptimize.com/optimize.js?id=" . $this->options_obj->google->optimize->container_id . "'></script>" . PHP_EOL ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
+ echo "\n <script async src='https://www.googletagmanager.com/gtag/js?id=" . $this->get_gtag_id() . "'></script>" ;
33
+ echo $this->get_modified_script_opening_tag() . PHP_EOL ;
34
+ echo $this->get_google_init_js() ;
35
  foreach ( $this->google_ads_conversion_identifiers as $conversion_id => $conversion_label ) {
36
  ?>
37
  <?php
61
  private function get_modified_script_opening_tag() : string
62
  {
63
  $cookiebot_snippet = ( $this->options_obj->shop->cookie_consent_mgmt->cookiebot->active ? ' data-cookieconsent="ignore"' : '' );
64
+ return "\n <script" . $cookiebot_snippet . ">";
65
  }
66
 
67
  protected function get_google_init_js() : string
68
  {
69
+ return "\n window.dataLayer = window.dataLayer || [];\n\n window.gtag = function gtag() {\n dataLayer.push(arguments);\n }\n " . $this->consent_mode_gtag_html() . "\n gtag('js', new Date());";
70
  }
71
 
72
  private function consent_mode_gtag_html() : string
147
  return $order_items_array;
148
  }
149
 
 
 
 
 
 
 
 
150
  protected function get_event_purchase_json(
151
  $order,
152
  $order_total,
164
  ];
165
 
166
  if ( 'ads' === $channel ) {
167
+ $gtag_data['send_to'] = $this->get_google_ads_conversion_ids( true );
168
  $gtag_data['value'] = (double) $order_total;
169
  $gtag_data['aw_merchant_id'] = (int) $this->aw_merchant_id;
170
  $gtag_data['aw_feed_country'] = (string) $this->get_visitor_country();
242
  'google' => [
243
  'ads' => [
244
  'dynamic_remarketing' => [
245
+ 'status' => ( $this->options_obj->google->ads->dynamic_remarketing ? true : false ),
246
  'id_type' => $this->get_dyn_r_id_type(),
247
  ],
248
  'conversionIds' => $this->get_google_ads_conversion_ids(),
256
  'measurement_id' => $this->options_obj->google->analytics->ga4->measurement_id,
257
  ],
258
  'id_type' => $this->get_ga_id_type(),
259
+ 'eec' => ( $this->options_obj->google->analytics->eec ? true : false ),
260
  ],
261
  ],
262
  ];
274
  {
275
 
276
  if ( 'ads' === $channel ) {
277
+ return PHP_EOL . "\t\t\t" . "gtag('config', 'AW-" . $id . "');" . PHP_EOL;
278
  } elseif ( 'ga_ua' === $channel ) {
279
  $ga_ua_parameters = [
280
  'anonymize_ip' => 'true',
284
  $ga_ua_parameters['user_id'] = get_current_user_id();
285
  }
286
  $ga_ua_parameters = apply_filters( 'woopt_pm_analytics_parameters', $ga_ua_parameters, $id );
287
+ return "\t" . "gtag('config', '" . $id . "', " . json_encode( $ga_ua_parameters ) . ");";
288
  } elseif ( 'ga_4' === $channel ) {
289
  if ( $this->options_obj->google->user_id && is_user_logged_in() ) {
290
  $ga_4_parameters = [
293
  }
294
 
295
  if ( empty($ga_4_parameters) ) {
296
+ return "\t" . "gtag('config', '" . $id . "');";
297
  } else {
298
+ return "\t" . "gtag('config', '" . $id . "', " . json_encode( $ga_4_parameters ) . ");";
299
  }
300
 
301
  }
classes/pixels/google/trait-google.php CHANGED
@@ -2,12 +2,23 @@
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
 
 
5
  if (!defined('ABSPATH')) {
6
  exit; // Exit if accessed directly
7
  }
8
 
9
  trait Trait_Google
10
  {
 
 
 
 
 
 
 
 
 
11
  protected function google_active(): bool
12
  {
13
  if ($this->options_obj->google->analytics->universal->property_id) {
@@ -76,6 +87,15 @@ trait Trait_Google
76
  }
77
  }
78
 
 
 
 
 
 
 
 
 
 
79
  protected function get_order_currency($order)
80
  {
81
  // use the right function to get the currency depending on the WooCommerce version
@@ -91,4 +111,51 @@ trait Trait_Google
91
  return false;
92
  }
93
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
2
 
3
  namespace WGACT\Classes\Pixels\Google;
4
 
5
+ use WGACT\Classes\Admin\Environment_Check;
6
+
7
  if (!defined('ABSPATH')) {
8
  exit; // Exit if accessed directly
9
  }
10
 
11
  trait Trait_Google
12
  {
13
+ protected function get_ga_id_type(): string
14
+ {
15
+ $ga_id_type = 'post_id';
16
+
17
+ $ga_id_type = apply_filters('wooptpm_product_id_type_for_google_analytics', $ga_id_type);
18
+
19
+ return $ga_id_type;
20
+ }
21
+
22
  protected function google_active(): bool
23
  {
24
  if ($this->options_obj->google->analytics->universal->property_id) {
87
  }
88
  }
89
 
90
+ protected function is_google_analytics_4_mp_active(): bool
91
+ {
92
+ if ($this->options_obj->google->analytics->ga4->measurement_id && $this->options_obj->google->analytics->ga4->api_secret) {
93
+ return true;
94
+ } else {
95
+ return false;
96
+ }
97
+ }
98
+
99
  protected function get_order_currency($order)
100
  {
101
  // use the right function to get the currency depending on the WooCommerce version
111
  return false;
112
  }
113
  }
114
+
115
+ protected function get_order_item_data($order_item): array
116
+ {
117
+ $product = $order_item->get_product();
118
+
119
+ $dyn_r_ids = $this->get_dyn_r_ids($product);
120
+
121
+ if ($product->get_type() === 'variation') {
122
+ $parent_product = wc_get_product($product->get_parent_id());
123
+ $name = $parent_product->get_name();
124
+ } else {
125
+ $name = $product->get_name();
126
+ }
127
+
128
+ return [
129
+ 'id' => (string)$dyn_r_ids[$this->get_ga_id_type()],
130
+ 'name' => (string)$name,
131
+ 'quantity' => (int)$order_item['quantity'],
132
+ 'affiliation' => (string)get_bloginfo('name'),
133
+ // 'coupon' => '',
134
+ // 'discount' => 0,
135
+ 'brand' => (string)$this->get_brand_name($product->get_id()),
136
+ // https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#pr_ca
137
+ 'category' => (string)implode(' | ', $this->get_product_category($product->get_id())),
138
+ 'variant' => (string)($product->get_type() === 'variation') ? $this->get_formatted_variant_text($product) : '',
139
+ // 'tax' => 0,
140
+ 'price' => (float)$this->wooptpm_get_order_item_price($order_item, $product),
141
+ // 'list_name' => ,
142
+ // 'currency' => '',
143
+ ];
144
+ }
145
+
146
+ protected function wooptpm_get_order_item_price($order_item, $product): float
147
+ {
148
+ if ((new Environment_Check())->is_woo_discount_rules_active()) {
149
+ $item_value = $order_item->get_meta('_advanced_woo_discount_item_total_discount');
150
+ if (is_array($item_value) && array_key_exists('discounted_price', $item_value) && $item_value['discounted_price'] != 0) {
151
+ return $item_value['discounted_price'];
152
+ } elseif (is_array($item_value) && array_key_exists('initial_price', $item_value) && $item_value['initial_price'] != 0) {
153
+ return $item_value['initial_price'];
154
+ } else {
155
+ return $product->get_price();
156
+ }
157
+ } else {
158
+ return $product->get_price();
159
+ }
160
+ }
161
  }
classes/pixels/hotjar/class-hotjar-pixel.php CHANGED
@@ -10,9 +10,9 @@ if (!defined('ABSPATH')) {
10
 
11
  class Hotjar_Pixel extends Pixel
12
  {
13
- public function __construct()
14
  {
15
- parent::__construct();
16
  }
17
 
18
  public function inject_everywhere()
10
 
11
  class Hotjar_Pixel extends Pixel
12
  {
13
+ public function __construct($options)
14
  {
15
+ parent::__construct($options);
16
  }
17
 
18
  public function inject_everywhere()
classes/pixels/trait-product.php CHANGED
@@ -8,6 +8,22 @@ if (!defined('ABSPATH')) {
8
 
9
  trait Trait_Product
10
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  protected function get_variation_or_product_id($item, $variations_output = true)
12
  {
13
  if ($item['variation_id'] <> 0 && $variations_output == true) {
@@ -56,7 +72,7 @@ trait Trait_Product
56
  return $prod_cats_output;
57
  }
58
 
59
- protected function get_compiled_product_id($product_id, $product_sku, $channel = '', $options): string
60
  {
61
  // depending on setting use product IDs or SKUs
62
  if (0 == $this->options['google']['ads']['product_identifier'] || $channel === 'ga_ua' || $channel === 'ga_4') {
@@ -86,5 +102,45 @@ trait Trait_Product
86
  return $dyn_r_ids;
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
 
 
90
  }
8
 
9
  trait Trait_Product
10
  {
11
+ protected function get_formatted_variant_text($product): string
12
+ {
13
+ $variant_text_array = [];
14
+
15
+ $attributes = $product->get_attributes();
16
+ if ($attributes) {
17
+ foreach ($attributes as $key => $value) {
18
+
19
+ $key_name = str_replace('pa_', '', $key);
20
+ $variant_text_array[] = ucfirst($key_name) . ': ' . strtolower($value);
21
+ }
22
+ }
23
+
24
+ return implode(' | ', $variant_text_array);
25
+ }
26
+
27
  protected function get_variation_or_product_id($item, $variations_output = true)
28
  {
29
  if ($item['variation_id'] <> 0 && $variations_output == true) {
72
  return $prod_cats_output;
73
  }
74
 
75
+ protected function get_compiled_product_id($product_id, $product_sku, $options, $channel = ''): string
76
  {
77
  // depending on setting use product IDs or SKUs
78
  if (0 == $this->options['google']['ads']['product_identifier'] || $channel === 'ga_ua' || $channel === 'ga_4') {
102
  return $dyn_r_ids;
103
  }
104
 
105
+ protected function get_order_item_ids($order): array
106
+ {
107
+ $order_items = $order->get_items();
108
+ $order_items_array = [];
109
+
110
+ foreach ((array)$order_items as $order_item) {
111
+
112
+ $product_id = $this->get_variation_or_product_id($order_item->get_data(), $this->options_obj->general->variations_output);
113
+
114
+ $product = wc_get_product($product_id);
115
+
116
+ // only continue if WC retrieves a valid product
117
+ if (!is_bool($product)) {
118
+
119
+ $dyn_r_ids = $this->get_dyn_r_ids($product);
120
+ $product_id_compiled = $dyn_r_ids[$this->get_dyn_r_id_type()];
121
+ // $product_id_compiled = $this->get_compiled_product_id($product_id, $product->get_sku(), $this->options, '');
122
+ array_push($order_items_array, $product_id_compiled);
123
+ }
124
+ }
125
+
126
+ return $order_items_array;
127
+ }
128
+
129
+ protected function get_dyn_r_id_type (): string
130
+ {
131
+ // $dyn_r_id_type = '';
132
+
133
+ if($this->options_obj->google->ads->product_identifier == 0) {
134
+ $this->dyn_r_id_type = 'post_id';
135
+ } elseif ($this->options_obj->google->ads->product_identifier == 1) {
136
+ $this->dyn_r_id_type = 'gpf';
137
+ } elseif ($this->options_obj->google->ads->product_identifier == 2) {
138
+ $this->dyn_r_id_type = 'sku';
139
+ }
140
+
141
+ // if you want to change the dyn_r_id type for Google programmatically
142
+ $this->dyn_r_id_type = apply_filters('wooptpm_product_id_type_for_' . $this->pixel_name, $this->dyn_r_id_type);
143
 
144
+ return $this->dyn_r_id_type;
145
+ }
146
  }
classes/pixels/trait-shop.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WGACT\Classes\Pixels;
4
+
5
+ if (!defined('ABSPATH')) {
6
+ exit; // Exit if accessed directly
7
+ }
8
+
9
+ trait Trait_Shop
10
+ {
11
+ protected function get_list_name_suffix(): string
12
+ {
13
+ $list_suffix = '';
14
+
15
+ if (is_product_category()) {
16
+
17
+ $category = get_queried_object();
18
+ $list_suffix = ' | ' . $category->name;
19
+ $list_suffix = $this->add_parent_category_name($category, $list_suffix);
20
+ } else if (is_product_tag()) {
21
+ $tag = get_queried_object();
22
+ $list_suffix = ' | ' . $tag->name;
23
+ }
24
+
25
+ return $list_suffix;
26
+ }
27
+
28
+ protected function add_parent_category_name($category, $list_suffix)
29
+ {
30
+ if ($category->parent > 0) {
31
+
32
+ $parent_category = get_term_by('id', $category->parent, 'product_cat');
33
+ $list_suffix = ' | ' . $parent_category->name . $list_suffix;
34
+ $list_suffix = $this->add_parent_category_name($parent_category, $list_suffix);
35
+ }
36
+
37
+ return $list_suffix;
38
+ }
39
+
40
+ protected function get_list_id_suffix(): string
41
+ {
42
+ $list_suffix = '';
43
+
44
+ if (is_product_category()) {
45
+
46
+ $category = get_queried_object();
47
+ $list_suffix = '.' . $category->slug;
48
+ $list_suffix = $this->add_parent_category_id($category, $list_suffix);
49
+ } else if (is_product_tag()) {
50
+ $tag = get_queried_object();
51
+ $list_suffix = '.' . $tag->slug;
52
+ }
53
+
54
+ return $list_suffix;
55
+ }
56
+
57
+ protected function add_parent_category_id($category, $list_suffix)
58
+ {
59
+ if ($category->parent > 0) {
60
+
61
+ $parent_category = get_term_by('id', $category->parent, 'product_cat');
62
+ // error_log(print_r($parent_category, true));
63
+ $list_suffix = '.' . $parent_category->slug . $list_suffix;
64
+ $list_suffix = $this->add_parent_category_id($parent_category, $list_suffix);
65
+ }
66
+
67
+ return $list_suffix;
68
+ }
69
+
70
+ }
js/admin/tabs.js CHANGED
@@ -75,7 +75,7 @@ jQuery(function () {
75
 
76
  jQuery("a[data-section-slug=" + sectionParams['section'] + "]").trigger('click');
77
 
78
- if(sectionParams['subsection'] != false){
79
  jQuery("ul[data-section-slug=" + sectionParams['section'] + "]").children("[data-subsection-slug=" + sectionParams['subsection'] + "]").trigger('click')
80
  }
81
  } else {
@@ -128,7 +128,7 @@ function toggleSections(sectionSlug, sections) {
128
  jQuery(".subnav-tabs").hide();
129
  jQuery(".subnav-tabs[data-section-slug=" + sectionSlug + "]").show();
130
 
131
- let sectionPos = sections.findIndex((arrayElement) => arrayElement['slug'] == sectionSlug);
132
 
133
  jQuery("div[data-section-slug=" + sectionSlug + "]").closest("table").prevAll("h2:first").next().nextUntil("h2, .submit").andSelf().show();
134
 
75
 
76
  jQuery("a[data-section-slug=" + sectionParams['section'] + "]").trigger('click');
77
 
78
+ if(sectionParams['subsection'] !== false){
79
  jQuery("ul[data-section-slug=" + sectionParams['section'] + "]").children("[data-subsection-slug=" + sectionParams['subsection'] + "]").trigger('click')
80
  }
81
  } else {
128
  jQuery(".subnav-tabs").hide();
129
  jQuery(".subnav-tabs[data-section-slug=" + sectionSlug + "]").show();
130
 
131
+ let sectionPos = sections.findIndex((arrayElement) => arrayElement['slug'] === sectionSlug);
132
 
133
  jQuery("div[data-section-slug=" + sectionSlug + "]").closest("table").prevAll("h2:first").next().nextUntil("h2, .submit").andSelf().show();
134
 
js/public/facebook.js CHANGED
@@ -1,15 +1,55 @@
1
- // add_to_cart event
2
- jQuery(document).on('wooptpmAddToCart', function (event, data) {
3
-
4
- // console.log('firing facebook ads AddToCart event');
5
- // alert('firing facebook ads AddToCart event');
6
- // console.log(data);
7
-
8
- fbq('track', 'AddToCart', {
9
- 'content_type': 'product',
10
- 'content_name': data.name,
11
- 'content_ids' : data.dyn_r_ids[wooptpmDataLayer.pixels.facebook.dynamic_remarketing.id_type],
12
- 'value' : data.quantity * data.price,
13
- 'currency' : data.currency,
14
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  });
1
+ jQuery(function () {
2
+
3
+ if (wooptpm.objectExists(wooptpmDataLayer.pixels.facebook)) {
4
+
5
+ // add_to_cart event
6
+ jQuery(document).on('wooptpmAddToCart', function (event, product) {
7
+
8
+ // console.log('firing facebook ads AddToCart event');
9
+ // console.log(data);
10
+
11
+ fbq('track', 'AddToCart', {
12
+ 'content_type': 'product',
13
+ 'content_name': product.name,
14
+ 'content_ids' : product.dyn_r_ids[wooptpmDataLayer.pixels.facebook.dynamic_remarketing.id_type],
15
+ 'value' : product.quantity * product.price,
16
+ 'currency' : product.currency,
17
+ });
18
+ });
19
+
20
+
21
+ }
22
+ })
23
+
24
+ jQuery(window).on('load', function () {
25
+
26
+ if (wooptpm.objectExists(wooptpmDataLayer.pixels.facebook)) {
27
+ wooptpmExists().then(function () {
28
+
29
+ try {
30
+ if (wooptpmDataLayer.shop.page_type === 'product' && wooptpm.getMainProductIdFromProductPage()) {
31
+
32
+ let product = wooptpm.getProductDataForViewItemEvent(wooptpm.getMainProductIdFromProductPage());
33
+
34
+ // console.log('fbq ViewContent');
35
+ // console.log(product);
36
+
37
+ fbq("track", "ViewContent", {
38
+ "content_type" : "product",
39
+ "content_name" : product.name,
40
+ "content_category": product.category,
41
+ "content_ids" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
42
+ "currency" : wooptpmDataLayer.shop.currency,
43
+ "value" : product.price,
44
+ });
45
+
46
+ } else if (wooptpmDataLayer.shop.page_type === 'search') {
47
+
48
+ fbq("track", "Search");
49
+ }
50
+ } catch (e) {
51
+ console.log(e);
52
+ }
53
+ })
54
+ }
55
  });
js/public/google-ads.js ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function () {
2
+
3
+ if (wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.status) {
4
+
5
+ // view_item_list event
6
+ jQuery(document).on('wooptpmViewItemList', function (event, product) {
7
+
8
+ // console.log('firing google view_item_list event');
9
+ // console.log(product);
10
+
11
+ gtag('event', 'view_item_list', {
12
+ "send_to": wooptpmDataLayer.pixels.google.ads.conversionIds,
13
+ "items" : [{
14
+ "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
15
+ "google_business_vertical": wooptpmDataLayer.pixels.google.ads.google_business_vertical,
16
+
17
+ }]
18
+ });
19
+ });
20
+
21
+ // add_to_cart event
22
+ jQuery(document).on('wooptpmAddToCart', function (event, product) {
23
+
24
+ // console.log('firing google ads add_to_cart event');
25
+ // console.log(product);
26
+ // console.log(wooptpmDataLayer.pixels.google.ads.conversionIds);
27
+ // console.log('dyn_r_id: ' + product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type]);
28
+ // console.log('dyn_r_id: ' + product.dyn_r_ids['gpf']);
29
+
30
+ gtag("event", "add_to_cart", {
31
+ "send_to": wooptpmDataLayer.pixels.google.ads.conversionIds,
32
+ "value" : product.quantity * product.price,
33
+ "items" : [{
34
+ "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
35
+ "quantity" : product.quantity,
36
+ "price" : product.price,
37
+ "google_business_vertical": wooptpmDataLayer.pixels.google.ads.google_business_vertical
38
+ }]
39
+ });
40
+ });
41
+
42
+ // select_content
43
+ // there is no select_content event that is processed by Google Ads: https://support.google.com/google-ads/answer/7305793?hl=en
44
+ // jQuery(document).on('wooptpmSelectContentGaUa', function (event, product) {
45
+ //
46
+ // // console.log('firing google ads select_content event');
47
+ // // console.log('firing google ads select_content event');
48
+ // // console.log(product);
49
+ //
50
+ // gtag("event", "select_content", {
51
+ // "send_to" : wooptpmDataLayer.pixels.google.ads.conversionIds,
52
+ // "content_type": "product",
53
+ // "items" : [{
54
+ // "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
55
+ // "quantity" : product.quantity,
56
+ // "name" : product.name,
57
+ // "price" : product.price,
58
+ // 'google_business_vertical': wooptpmDataLayer.pixels.google.ads.google_business_vertical
59
+ // }]
60
+ // });
61
+ // });
62
+
63
+ // view_item event
64
+ jQuery(document).on('wooptpmViewItem', function (event, product) {
65
+
66
+ // console.log('firing google ads view_item event');
67
+ // console.log(product);
68
+ // console.log(wooptpmDataLayer.pixels.google.ads.conversionIds);
69
+ // console.log('dyn_r_id: ' + product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type]);
70
+ // console.log('dyn_r_id: ' + product.dyn_r_ids['gpf']);
71
+
72
+ gtag("event", "view_item", {
73
+ "send_to": wooptpmDataLayer.pixels.google.ads.conversionIds,
74
+ "value" : product.quantity * product.price,
75
+ "items" : [{
76
+ "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
77
+ "quantity" : 1,
78
+ "price" : product.price,
79
+ "google_business_vertical": wooptpmDataLayer.pixels.google.ads.google_business_vertical
80
+ }]
81
+ });
82
+ });
83
+ }
84
+ })
85
+
86
+ jQuery(window).on('load', function () {
87
+
88
+ wooptpmExists().then(function () {
89
+
90
+ try {
91
+ if (wooptpmDataLayer.shop.page_type === 'product' && wooptpm.getMainProductIdFromProductPage()) {
92
+
93
+ // console.log('productId: ' + wooptpm.getMainProductIdFromProductPage());
94
+
95
+ let product = wooptpm.getProductDataForViewItemEvent(wooptpm.getMainProductIdFromProductPage());
96
+
97
+ gtag("event", "view_item", {
98
+ "send_to": wooptpmDataLayer.pixels.google.ads.conversionIds,
99
+ "value" : 1 * product.price,
100
+ "items" : [{
101
+ "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
102
+ "google_business_vertical": wooptpmDataLayer.pixels.google.ads.google_business_vertical
103
+ }]
104
+ });
105
+ } else if (wooptpmDataLayer.shop.page_type === 'search') {
106
+
107
+ let products = [];
108
+
109
+ for (const [key, product] of Object.entries(wooptpmDataLayer.products)) {
110
+ products.push({
111
+ "id" : product.dyn_r_ids[wooptpmDataLayer.pixels.google.ads.dynamic_remarketing.id_type],
112
+ "google_business_vertical": wooptpmDataLayer.pixels.google.ads.google_business_vertical
113
+ });
114
+ }
115
+
116
+ // console.log(products);
117
+
118
+ gtag("event", "view_search_results", {
119
+ "send_to": wooptpmDataLayer.pixels.google.ads.conversionIds,
120
+ // "value" : 1 * product.price,
121
+ "items": products
122
+ });
123
+ }
124
+ } catch (e) {
125
+ console.log(e);
126
+ }
127
+ })
128
+ });
js/public/wooptpm.js CHANGED
@@ -1,9 +1,21 @@
1
  (function (wooptpm, $, undefined) {
 
2
  const wgactDeduper = {
3
  keyName : '_wgact_order_ids',
4
  cookieExpiresDays: 365
5
  };
6
 
 
 
 
 
 
 
 
 
 
 
 
7
  wooptpm.writeOrderIdToStorage = function (orderId, expireDays = 365) {
8
 
9
  // save the order ID in the browser storage
@@ -64,7 +76,9 @@
64
 
65
  wooptpm.isOrderIdStored = function (orderId) {
66
 
 
67
  if (wooptpmDataLayer.orderDeduplication) {
 
68
  if (!window.Storage) {
69
 
70
  if (checkCookie()) {
@@ -82,6 +96,7 @@
82
  }
83
  }
84
  } else {
 
85
  return false;
86
  }
87
  }
@@ -92,142 +107,179 @@
92
  return regex.test(email);
93
  }
94
 
95
- wooptpm.removeProductFromCart = function (cartItemKey, quantityToRemove = null, productId = null) {
96
 
97
- if (productId == null) {
98
- productId = wooptpmDataLayer['cart_item_keys'][cartItemKey]['id'];
99
- }
100
 
101
- let quantity;
102
 
103
- if (quantityToRemove == null) {
104
- quantity = wooptpmDataLayer['cart'][productId]['quantity'];
105
- } else {
106
- quantity = quantityToRemove;
107
- }
108
 
109
- // alert ('product_id: ' + productId + ' | qty: ' + quantity);
110
 
111
- let data = {
112
- "id" : productId.toString(),
113
- "dyn_r_ids": wooptpmDataLayer['cart'][productId]['dyn_r_ids'],
114
- "name": wooptpmDataLayer['cart'][productId]['name'],
115
- // "list_name": wooptpmDataLayer['shop']['list_name'], // doesn't make sense on mini_cart
116
- "brand" : wooptpmDataLayer['cart'][productId]['brand'],
117
- "category": wooptpmDataLayer['cart'][productId]['category'],
118
- // "variant": "Black",
119
- // "list_position": wooptpmDataLayer['cart'][productId]['position'], // doesn't make sense on mini_cart
120
- "quantity": quantity,
121
- "price" : wooptpmDataLayer['cart'][productId]['price']
122
- };
123
 
124
- jQuery(document).trigger('wooptpmRemoveFromCart', data);
 
 
 
 
125
 
126
- if (quantityToRemove == null) {
127
- delete wooptpmDataLayer['cart'][productId];
128
- if (cartItemKey) {
129
- delete wooptpmDataLayer['cart_item_keys'][cartItemKey];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
- } else {
132
- wooptpmDataLayer['cart'][productId]['quantity'] = wooptpmDataLayer['cart'][productId]['quantity'] - quantity;
133
  }
134
  }
135
 
136
- wooptpm.addProductToCart = function (productId, quantity, variationId = null) {
137
 
138
- // alert('productId: ' + productId + ' | qty: ' + quantity);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- let id = '';
 
141
 
142
- if (variationId !== null) {
143
- id = variationId;
144
- } else {
145
- id = productId;
146
- }
147
 
148
- let data = {
149
- "id" : id.toString(),
150
- "dyn_r_ids": wooptpmDataLayer['visible_products'][productId]['dyn_r_ids'],
151
- "name" : wooptpmDataLayer['visible_products'][productId]['name'],
152
- "list_name": wooptpmDataLayer['shop']['list_name'], // maybe remove if in cart
153
- "brand" : wooptpmDataLayer['visible_products'][productId]['brand'],
154
- "category" : wooptpmDataLayer['visible_products'][productId]['category'],
155
- // "variant": "Black",
156
- "list_position": wooptpmDataLayer['visible_products'][productId]['position'],
157
- "quantity" : quantity,
158
- "price" : wooptpmDataLayer['visible_products'][productId]['price'],
159
- "currency" : wooptpmDataLayer.shop.currency
160
- };
161
 
162
- jQuery(document).trigger('wooptpmAddToCart', data);
163
 
164
- // add product to cart wooptpmDataLayer['cart']
165
 
166
- // if the product already exists in the object, only add the additional quantity
167
- // otherwise create that product object in the wooptpmDataLayer['cart']
168
- if (wooptpmDataLayer['cart'] !== undefined && wooptpmDataLayer['cart'][id] !== undefined) {
169
- wooptpmDataLayer['cart'][id]['quantity'] = wooptpmDataLayer['cart'][id]['quantity'] + quantity;
170
- } else {
171
 
172
- // Object.assign(wooptpmDataLayer['cart'], {
173
- // id: {
174
- // 'id' : id,
175
- // 'name' : wooptpmDataLayer['visible_products'][productId]['name'],
176
- // 'brand' : wooptpmDataLayer['visible_products'][productId]['brand'],
177
- // 'category': wooptpmDataLayer['visible_products'][productId]['category'],
178
- // 'quantity': quantity,
179
- // 'price' : wooptpmDataLayer['visible_products'][productId]['price']
180
- // }
181
- // });
182
-
183
- if (!wooptpmDataLayer.cart) {
184
-
185
- wooptpmDataLayer['cart'] = {
186
- [id]: {
187
- 'id' : id,
188
- 'dyn_r_ids': wooptpmDataLayer['visible_products'][productId]['dyn_r_ids'],
189
- 'name' : wooptpmDataLayer['visible_products'][productId]['name'],
190
- 'brand' : wooptpmDataLayer['visible_products'][productId]['brand'],
191
- 'category' : wooptpmDataLayer['visible_products'][productId]['category'],
192
- 'quantity' : quantity,
193
- 'price' : wooptpmDataLayer['visible_products'][productId]['price']
194
- }
195
  };
196
 
197
- } else {
198
 
199
- wooptpmDataLayer.cart[id] = {
200
- 'id' : id,
201
- 'dyn_r_ids': wooptpmDataLayer['visible_products'][productId]['dyn_r_ids'],
202
- 'name' : wooptpmDataLayer['visible_products'][productId]['name'],
203
- 'brand' : wooptpmDataLayer['visible_products'][productId]['brand'],
204
- 'category' : wooptpmDataLayer['visible_products'][productId]['category'],
205
- 'quantity' : quantity,
206
- 'price' : wooptpmDataLayer['visible_products'][productId]['price']
207
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
 
 
209
  }
210
  }
211
 
212
  wooptpm.getCartItemsFromBackEnd = function () {
213
  // get all cart items from the backend
214
 
215
- let data = {
216
- 'action': 'wooptpm_get_cart_items',
217
- };
 
218
 
219
- jQuery.ajax(
220
- {
221
- type : "get",
222
- dataType: "json",
223
- url : ajax_object.ajax_url,
224
- data : data,
225
- success : function (cart_items) {
226
- // save all cart items into wooptpmDataLayer
227
- wooptpmDataLayer['cart'] = cart_items['cart'];
228
- wooptpmDataLayer['cart_item_keys'] = cart_items['cart_item_keys'];
229
- }
230
- });
 
 
 
 
 
231
  }
232
 
233
  wooptpm.fireCheckoutOption = function (step, checkout_option = null, value = null) {
@@ -241,10 +293,256 @@
241
  jQuery(document).trigger('wooptpmFireCheckoutOption', data);
242
  }
243
 
 
244
 
 
 
 
 
 
 
245
 
246
  wooptpm.getPostIdFromString = function (string) {
247
- return string.match(/(post-)(\d+)/)[2];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  }
249
 
250
  // return {
@@ -261,173 +559,330 @@
261
 
262
  }(window.wooptpm = window.wooptpm || {}, jQuery));
263
 
264
-
265
  jQuery(function () {
266
  // jQuery(window).on('load', function () {
267
 
 
 
 
 
 
 
 
 
268
  // remove_from_cart event
269
- jQuery(document).on('click', '.remove_from_cart_button, .remove', function (e) {
270
 
271
- let cartItemKey;
 
272
 
273
- if (wooptpmDataLayer['shop']['page_type'] === 'cart') {
274
- let href = new URL(jQuery(this).attr('href'));
275
- let searchParams = new URLSearchParams(href.search);
276
- cartItemKey = searchParams.get('remove_item');
277
- wooptpm.removeProductFromCart(cartItemKey);
278
- } else if (wooptpmDataLayer.cart_item_keys && wooptpmDataLayer.cart_item_keys[jQuery(this).data('cart_item_key')] !== undefined) {
279
- wooptpm.removeProductFromCart(jQuery(this).data('cart_item_key'));
280
- } else {
281
- wooptpm.removeProductFromCart(null, null, jQuery(this).data('product_id'));
282
  }
283
  });
284
 
 
285
  // add_to_cart event
286
- jQuery(document).on('click', '.add_to_cart_button, .ajax_add_to_cart, .single_add_to_cart_button', function (e) {
 
 
 
287
 
288
- // console.log('test x');
289
- // alert('test');
290
- if (wooptpmDataLayer.shop.product_type !== 'grouped') {
291
 
292
- let productId = null;
 
 
 
 
 
 
 
293
 
294
- let quantity = 1;
295
 
296
- if (wooptpmDataLayer['shop']['page_type'] === 'product') {
297
- quantity = Number(jQuery('.input-text.qty').val());
298
- }
 
 
299
 
300
- if (wooptpmDataLayer['shop']['page_type'] !== 'product') {
301
- productId = jQuery(this).data('product_id');
302
- wooptpm.addProductToCart(productId, quantity);
303
- } else if (wooptpmDataLayer['shop']['product_type'] === 'variable') {
304
- productId = jQuery("[name='product_id']").val();
305
- let variationId = jQuery("[name='variation_id']").val();
306
- wooptpm.addProductToCart(productId, quantity, variationId);
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  } else {
309
- productId = jQuery(this).val();
 
 
 
 
 
310
  wooptpm.addProductToCart(productId, quantity);
311
  }
312
- } else {
313
- jQuery('.woocommerce-grouped-product-list-item').each(function () {
314
- let quantity = Number(jQuery(this).find('.input-text.qty').val());
315
- let classes = jQuery(this).attr('class');
316
- let productId = wooptpm.getPostIdFromString(classes);
317
- wooptpm.addProductToCart(productId, quantity);
318
- });
319
  }
320
  });
321
 
322
  // if someone clicks anywhere on a custom /?add-to-cart=123 link
323
  // trigger the add to cart event
324
- jQuery(document).one('click', function (e) {
325
 
326
- if (jQuery(this)[0].URL) {
 
327
 
328
- let href = new URL(jQuery(this)[0].URL);
329
- let searchParams = new URLSearchParams(href.search);
330
 
331
- if (searchParams.has('add-to-cart')) {
 
332
 
333
- let productId = searchParams.get('add-to-cart');
334
- wooptpm.addProductToCart(productId, 1);
 
335
  }
 
 
336
  }
 
337
  });
338
 
339
 
340
- // select_content event
341
- // only allow the script to be fired on the following pages
342
- let allowed_pages = ['shop', 'product_category', 'product_tag', 'search', 'product_shop', 'product'];
 
343
 
344
- if (allowed_pages.includes(wooptpmDataLayer['shop']['page_type'])) {
345
 
346
- jQuery(document).on('click', '.woocommerce-LoopProduct-link', function (e) {
 
 
 
 
 
 
347
 
348
- let name = jQuery(this).closest('.product');
349
- let classes = name.attr('class');
350
- let productId = wooptpm.getPostIdFromString(classes);
351
 
352
- let data = {
353
- 'id' : productId.toString(),
354
- 'dyn_r_ids': wooptpmDataLayer['visible_products'][productId]['dyn_r_ids'],
355
- 'name' : wooptpmDataLayer['visible_products'][productId]['name'],
356
- 'list_name': wooptpmDataLayer['shop']['list_name'],
357
- 'brand' : wooptpmDataLayer['visible_products'][productId]['brand'],
358
- 'category' : wooptpmDataLayer['visible_products'][productId]['category'],
359
- // "variant": "Black",
360
- 'list_position': wooptpmDataLayer['visible_products'][productId]['position'],
361
- 'quantity' : 1,
362
- 'price' : wooptpmDataLayer['visible_products'][productId]['price']
363
- };
364
 
365
- jQuery(document).trigger('wooptpmSelectContent', data);
366
- });
367
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
 
369
  // begin_checkout event
370
- jQuery(document).one('click', '.checkout-button, .cart-checkout-button, .button.checkout', function (e) {
 
 
371
 
372
  jQuery(document).trigger('wooptpmBeginCheckout');
373
  });
374
 
375
- // set_checkout_option event
 
 
376
  // track checkout option event: entered valid billing email
377
- jQuery(document).on('input', '#billing_email', function () {
378
 
379
  if (wooptpm.isEmail(jQuery(this).val())) {
380
- wooptpm.fireCheckoutOption(2);
 
 
381
  }
382
  });
383
 
384
  // track checkout option event: purchase click
385
- let payment_method_selected = false;
 
 
386
 
387
- jQuery(document).on('click', '.wc_payment_methods', function () {
 
 
388
 
389
  wooptpm.fireCheckoutOption(3, jQuery("input[name='payment_method']:checked").val());
390
- payment_method_selected = true;
391
  });
392
 
393
  // track checkout option event: purchase click
394
- jQuery(document).one('click', '#place_order', function () {
395
 
396
- if (payment_method_selected === false) {
 
 
397
 
 
 
398
  wooptpm.fireCheckoutOption(3, jQuery("input[name='payment_method']:checked").val());
399
  }
400
 
401
- wooptpm.fireCheckoutOption(4);
402
  });
403
 
404
  // update cart event
405
- jQuery(document).on('click', "[name='update_cart']", function (e) {
 
 
 
 
 
406
 
407
- jQuery('.cart_item').each(function () {
408
- let href = new URL(jQuery(this).find('.remove').attr('href'));
409
- let searchParams = new URLSearchParams(href.search);
410
- let cartItemKey = searchParams.get('remove_item');
411
- // alert('cart_item_key: ' + cartItemKey);
412
- let productId = wooptpmDataLayer['cart_item_keys'][cartItemKey]['id'];
413
 
414
- let quantity = jQuery(this).find('.qty').val();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
 
416
- // alert ('quantity: ' + quantity);
417
 
418
- if (quantity == 0) {
419
- wooptpm.removeProductFromCart(cartItemKey);
420
- } else if (quantity < wooptpmDataLayer['cart'][productId]['quantity']) {
421
- wooptpm.removeProductFromCart(cartItemKey, wooptpmDataLayer['cart'][productId]['quantity'] - quantity);
422
- } else if (quantity > wooptpmDataLayer['cart'][productId]['quantity']) {
423
- wooptpm.addProductToCart(productId, quantity - wooptpmDataLayer['cart'][productId]['quantity']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
  }
425
- });
 
 
426
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  });
428
 
429
 
430
  jQuery(window).on('load', function () {
431
  // populate the wooptpmDataLayer with the cart items
432
- wooptpm.getCartItemsFromBackEnd();
 
 
 
 
 
 
 
433
  });
1
  (function (wooptpm, $, undefined) {
2
+
3
  const wgactDeduper = {
4
  keyName : '_wgact_order_ids',
5
  cookieExpiresDays: 365
6
  };
7
 
8
+ wooptpm.objectExists = function (obj) {
9
+
10
+ for (let i = 1; i < arguments.length; i++) {
11
+ if (!obj.hasOwnProperty(arguments[i])) {
12
+ return false;
13
+ }
14
+ obj = obj[arguments[i]];
15
+ }
16
+ return true;
17
+ }
18
+
19
  wooptpm.writeOrderIdToStorage = function (orderId, expireDays = 365) {
20
 
21
  // save the order ID in the browser storage
76
 
77
  wooptpm.isOrderIdStored = function (orderId) {
78
 
79
+ // console.log('deduper: ' + wooptpmDataLayer.orderDeduplication);
80
  if (wooptpmDataLayer.orderDeduplication) {
81
+ // console.log('order deduplication: on');
82
  if (!window.Storage) {
83
 
84
  if (checkCookie()) {
96
  }
97
  }
98
  } else {
99
+ console.log('order deduplication: off');
100
  return false;
101
  }
102
  }
107
  return regex.test(email);
108
  }
109
 
110
+ wooptpm.removeProductFromCart = function (productId, quantityToRemove = null) {
111
 
112
+ try {
 
 
113
 
114
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
115
 
116
+ productId = getIdBasedOndVariationsOutputSetting(productId);
 
 
 
 
117
 
118
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
119
 
120
+ let quantity;
 
 
 
 
 
 
 
 
 
 
 
121
 
122
+ if (quantityToRemove == null) {
123
+ quantity = wooptpmDataLayer.cart[productId].quantity;
124
+ } else {
125
+ quantity = quantityToRemove;
126
+ }
127
 
128
+ // console.log('product_id: ' + productId + ' | qty: ' + quantity);
129
+ // console.log(productId);
130
+ // console.log(wooptpmDataLayer.cart);
131
+ // console.log(wooptpmDataLayer.cart[productId]);
132
+
133
+ if (wooptpmDataLayer.cart[productId]) {
134
+
135
+ let data = {
136
+ "id" : productId.toString(),
137
+ "dyn_r_ids": wooptpmDataLayer.cart[productId].dyn_r_ids,
138
+ "name" : wooptpmDataLayer.cart[productId].name,
139
+ // "list_name": wooptpmDataLayer.shop.list_name, // doesn't make sense on mini_cart
140
+ "brand" : wooptpmDataLayer.cart[productId].brand,
141
+ "category": wooptpmDataLayer.cart[productId].category,
142
+ "variant" : wooptpmDataLayer.cart[productId].variant,
143
+ // "list_position": wooptpmDataLayer.cart[productId].position, // doesn't make sense on mini_cart
144
+ "quantity": quantity,
145
+ "price" : wooptpmDataLayer.cart[productId].price
146
+ };
147
+
148
+ // console.log('removing');
149
+ // console.log(data);
150
+
151
+ jQuery(document).trigger('wooptpmRemoveFromCart', data);
152
+
153
+ if (quantityToRemove == null) {
154
+ delete wooptpmDataLayer.cart[productId];
155
+ } else {
156
+ wooptpmDataLayer.cart[productId].quantity = wooptpmDataLayer.cart[productId].quantity - quantity;
157
+ }
158
  }
159
+ } catch (e) {
160
+ console.log(e);
161
  }
162
  }
163
 
164
+ getIdBasedOndVariationsOutputSetting = function (productId) {
165
 
166
+ try {
167
+ if (wooptpmDataLayer.general.variationsOutput) {
168
+ // console.log('test');
169
+ return productId;
170
+ } else {
171
+ if (wooptpmDataLayer.products[productId].isVariation) {
172
+ return wooptpmDataLayer.products[productId].parentId;
173
+ } else {
174
+ return productId;
175
+ }
176
+ }
177
+ } catch (e) {
178
+ console.log(e);
179
+ }
180
+ }
181
 
182
+ // add_to_cart
183
+ wooptpm.addProductToCart = function (productId, quantity) {
184
 
185
+ try {
186
+ // console.log('productId: ' + productId + ' | qty: ' + quantity);
187
+ // console.log('productId: ' + productId + ' | variationId: ' + variationId + ' | qty: ' + quantity);
 
 
188
 
189
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
 
 
 
 
 
 
 
 
 
 
 
 
190
 
191
+ productId = getIdBasedOndVariationsOutputSetting(productId);
192
 
193
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
194
 
195
+ if (wooptpmDataLayer.products[productId]) {
 
 
 
 
196
 
197
+ let data = {
198
+ "id" : productId.toString(),
199
+ "dyn_r_ids" : wooptpmDataLayer.products[productId].dyn_r_ids,
200
+ "name" : wooptpmDataLayer.products[productId].name,
201
+ "list_name" : wooptpmDataLayer.shop.list_name, // maybe remove if in products
202
+ "brand" : wooptpmDataLayer.products[productId].brand,
203
+ "category" : wooptpmDataLayer.products[productId].category,
204
+ "variant" : wooptpmDataLayer.products[productId].variant,
205
+ "list_position": wooptpmDataLayer.products[productId].position,
206
+ "quantity" : quantity,
207
+ "price" : wooptpmDataLayer.products[productId].price,
208
+ "currency" : wooptpmDataLayer.shop.currency,
 
 
 
 
 
 
 
 
 
 
 
209
  };
210
 
211
+ // console.log(data);
212
 
213
+ jQuery(document).trigger('wooptpmAddToCart', data);
214
+
215
+ // add product to cart wooptpmDataLayer['cart']
216
+
217
+ // if the product already exists in the object, only add the additional quantity
218
+ // otherwise create that product object in the wooptpmDataLayer['cart']
219
+ if (wooptpmDataLayer.cart !== undefined && wooptpmDataLayer.cart[productId] !== undefined) {
220
+ wooptpmDataLayer.cart[productId].quantity = wooptpmDataLayer.cart[productId].quantity + quantity;
221
+ } else {
222
+
223
+ if (!wooptpmDataLayer.cart) {
224
+
225
+ wooptpmDataLayer['cart'] = {
226
+ [productId]: {
227
+ 'id' : productId,
228
+ 'dyn_r_ids': wooptpmDataLayer.products[productId].dyn_r_ids,
229
+ 'name' : wooptpmDataLayer.products[productId].name,
230
+ 'brand' : wooptpmDataLayer.products[productId].brand,
231
+ 'category' : wooptpmDataLayer.products[productId].category,
232
+ "variant" : wooptpmDataLayer.products[productId].variant,
233
+ 'quantity' : quantity,
234
+ 'price' : wooptpmDataLayer.products[productId].price
235
+ }
236
+ };
237
+
238
+ } else {
239
+
240
+ wooptpmDataLayer.cart[productId] = {
241
+ 'id' : productId,
242
+ 'dyn_r_ids': wooptpmDataLayer.products[productId].dyn_r_ids,
243
+ 'name' : wooptpmDataLayer.products[productId].name,
244
+ 'brand' : wooptpmDataLayer.products[productId].brand,
245
+ 'category' : wooptpmDataLayer.products[productId].category,
246
+ "variant" : wooptpmDataLayer.products[productId].variant,
247
+ 'quantity' : quantity,
248
+ 'price' : wooptpmDataLayer.products[productId].price
249
+ };
250
+ }
251
+ }
252
  }
253
+ } catch (e) {
254
+ console.log(e);
255
  }
256
  }
257
 
258
  wooptpm.getCartItemsFromBackEnd = function () {
259
  // get all cart items from the backend
260
 
261
+ try {
262
+ let data = {
263
+ 'action': 'wooptpm_get_cart_items',
264
+ };
265
 
266
+ jQuery.ajax(
267
+ {
268
+ type : "get",
269
+ dataType: "json",
270
+ url : ajax_object.ajax_url,
271
+ data : data,
272
+ success : function (cart_items) {
273
+ // save all cart items into wooptpmDataLayer
274
+ // console.log(cart_items['cart']);
275
+ wooptpmDataLayer.cart = cart_items['cart'];
276
+ // wooptpmDataLayer.products = {... wooptpmDataLayer.products, ...cart_items['cart']};
277
+ wooptpmDataLayer.products = Object.assign({}, wooptpmDataLayer.products, cart_items['cart']);
278
+ }
279
+ });
280
+ } catch (e) {
281
+ console.log(e);
282
+ }
283
  }
284
 
285
  wooptpm.fireCheckoutOption = function (step, checkout_option = null, value = null) {
293
  jQuery(document).trigger('wooptpmFireCheckoutOption', data);
294
  }
295
 
296
+ wooptpm.fireCheckoutProgress = function (step) {
297
 
298
+ let data = {
299
+ 'step': step,
300
+ };
301
+
302
+ jQuery(document).trigger('wooptpmFireCheckoutProgress', data);
303
+ }
304
 
305
  wooptpm.getPostIdFromString = function (string) {
306
+ // console.log(string);
307
+ try {
308
+ return string.match(/(post-)(\d+)/)[2];
309
+ } catch (e) {
310
+ console.log(e);
311
+ }
312
+ }
313
+
314
+ wooptpm.triggerViewItemList = function (productId) {
315
+
316
+ // productId = null;
317
+
318
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
319
+
320
+ productId = getIdBasedOndVariationsOutputSetting(productId);
321
+
322
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
323
+
324
+ jQuery(document).trigger('wooptpmViewItemList', wooptpm.getProductDataForViewItemEvent(productId));
325
+ }
326
+
327
+ wooptpm.getProductDataForViewItemEvent = function (productId) {
328
+
329
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
330
+
331
+ try {
332
+ if (wooptpmDataLayer.products[productId]) {
333
+ return {
334
+ "id" : productId.toString(),
335
+ "dyn_r_ids" : wooptpmDataLayer.products[productId].dyn_r_ids,
336
+ "name" : wooptpmDataLayer.products[productId].name,
337
+ "list_name" : wooptpmDataLayer.shop.list_name, // maybe remove if in cart
338
+ "brand" : wooptpmDataLayer.products[productId].brand,
339
+ "category" : wooptpmDataLayer.products[productId].category,
340
+ "variant" : wooptpmDataLayer.products[productId].variant,
341
+ "list_position": wooptpmDataLayer.products[productId].position,
342
+ "quantity" : 1,
343
+ "price" : wooptpmDataLayer.products[productId].price,
344
+ "currency" : wooptpmDataLayer.shop.currency,
345
+ };
346
+ }
347
+ } catch (e) {
348
+ console.log(e);
349
+ }
350
+ }
351
+
352
+ wooptpm.getMainProductIdFromProductPage = function () {
353
+ try {
354
+ if (wooptpmDataLayer.shop.product_type === 'simple') {
355
+ return jQuery('.single_add_to_cart_button').val();
356
+ } else if (wooptpmDataLayer.shop.product_type === 'variable') {
357
+ return jQuery('.woocommerce-variation-add-to-cart').find('[name="add-to-cart"]').val();
358
+ } else if (wooptpmDataLayer.shop.product_type === 'grouped') {
359
+ return jQuery('.grouped_form').find('[name="add-to-cart"]').val();
360
+ } else {
361
+ return false;
362
+ }
363
+ } catch (e) {
364
+ console.log(e);
365
+ }
366
+ }
367
+
368
+ wooptpm.viewItemListTriggerTestMode = function (target) {
369
+
370
+ jQuery(target).css({"position": "relative"});
371
+ jQuery(target).append('<div id="viewItemListTriggerOverlay"></div>')
372
+ jQuery(target).find('#viewItemListTriggerOverlay').css({
373
+ "z-index" : "10",
374
+ "display" : "block",
375
+ "position" : "absolute",
376
+ "height" : "100%",
377
+ "top" : "0",
378
+ "left" : "0",
379
+ "right" : "0",
380
+ "opacity" : wooptpmDataLayer.viewItemListTrigger.opacity,
381
+ "background-color": wooptpmDataLayer.viewItemListTrigger.backgroundColor,
382
+ })
383
+ }
384
+
385
+ wooptpm.getSearchTermFromUrl = function () {
386
+ try {
387
+ let urlParameters = new URLSearchParams(window.location.search)
388
+ return urlParameters.get('s');
389
+ } catch (e) {
390
+ console.log(e);
391
+ }
392
+ }
393
+
394
+ // we need this to track timeouts for intersection observers
395
+ let ioTimeouts = {};
396
+
397
+ wooptpm.observerCallback = function (entries, observer) {
398
+
399
+ entries.forEach((entry) => {
400
+
401
+ try {
402
+ let productId;
403
+
404
+ let elementId = jQuery(entry.target).data('ioid');
405
+
406
+ // Get the productId from next element, if wooptpmProductId is a sibling, like in Gutenberg blocks
407
+ // otherwise go search in children, like in regular WC loop items
408
+ if (jQuery(entry.target).next('.wooptpmProductId').length) {
409
+ // console.log('test 1');
410
+ productId = jQuery(entry.target).next('.wooptpmProductId').data('id');
411
+ } else {
412
+ productId = jQuery(entry.target).find('.wooptpmProductId').data('id');
413
+ }
414
+
415
+ // productId = null;
416
+
417
+ if (!productId) throw Error('wooptpmProductId element not found');
418
+
419
+ if (entry.isIntersecting) {
420
+
421
+ // console.log('prodid: ' + productId);
422
+ ioTimeouts[elementId] = setTimeout(() => {
423
+ // console.log('prodid: ' + productId);
424
+ wooptpm.triggerViewItemList(productId);
425
+ if (wooptpmDataLayer.viewItemListTrigger.testMode) wooptpm.viewItemListTriggerTestMode(entry.target);
426
+ if (wooptpmDataLayer.viewItemListTrigger.repeat === false) observer.unobserve(entry.target);
427
+ }, wooptpmDataLayer.viewItemListTrigger.timeout)
428
+
429
+ } else {
430
+
431
+ clearTimeout(ioTimeouts[elementId])
432
+ if (wooptpmDataLayer.viewItemListTrigger.testMode) jQuery(entry.target).find('#viewItemListTriggerOverlay').remove();
433
+ }
434
+ } catch (e) {
435
+ console.log(e);
436
+ }
437
+ });
438
+ }
439
+
440
+ // fire view_item_list only on products that have become visible
441
+ let io;
442
+ let ioid = 0;
443
+ let allIoElementsToWatch;
444
+
445
+ let getAllElementsToWatch = function () {
446
+
447
+ allIoElementsToWatch = jQuery('.wooptpmProductId')
448
+ .map(function (i, elem) {
449
+ // console.log(elem);
450
+ if (
451
+ jQuery(elem).parent().hasClass('type-product') ||
452
+ jQuery(elem).parent().hasClass('product') ||
453
+ jQuery(elem).parent().hasClass('product-item-inner')
454
+ ) {
455
+ // console.log(elem);
456
+ return jQuery(elem).parent();
457
+ } else if (
458
+ jQuery(elem).prev().hasClass('wc-block-grid__product') ||
459
+ jQuery(elem).prev().hasClass('product') ||
460
+ jQuery(elem).prev().hasClass('product-small') ||
461
+ jQuery(elem).prev().hasClass('woocommerce-LoopProduct-link')
462
+ ) {
463
+ return jQuery(this).prev();
464
+ }
465
+ });
466
+ }
467
+
468
+ wooptpm.startIntersectionObserverToWatch = function () {
469
+
470
+ try {
471
+ // enable view_item_list test mode from browser
472
+ let urlParams = new URLSearchParams(window.location.search);
473
+ if (urlParams.has('vildemomode')) wooptpmDataLayer.viewItemListTrigger.testMode = true;
474
+
475
+ // set up intersection observer
476
+ io = new IntersectionObserver(wooptpm.observerCallback, {
477
+ threshold: wooptpmDataLayer.viewItemListTrigger.threshold,
478
+ });
479
+
480
+ getAllElementsToWatch();
481
+
482
+ // console.log(allElementsToWatch);
483
+
484
+ allIoElementsToWatch.each(function (i, elem) {
485
+ // console.log(elem[0]);
486
+ // jQuery(elem[0]).attr('data-ioid', ioid++);
487
+ jQuery(elem[0]).data('ioid', ioid++);
488
+
489
+ io.observe(elem[0])
490
+ });
491
+ } catch (e) {
492
+ console.log(e);
493
+ }
494
+ }
495
+
496
+ // watch DOM for new lazy loaded products and add them to the intersection observer
497
+ wooptpm.startProductsMutationObserverToWatch = function () {
498
+
499
+ try {
500
+ // Pass in the target node, as well as the observer options
501
+
502
+ // selects the most common parent node
503
+ // https://stackoverflow.com/a/7648323/4688612
504
+ let productsNode = jQuery('.wooptpmProductId:eq(0)').parents().has(jQuery('.wooptpmProductId:eq(1)').parents()).first()
505
+
506
+ if (productsNode.length) {
507
+ productsMutationObserver.observe(productsNode[0], {
508
+ attributes : true,
509
+ childList : true,
510
+ characterData: true
511
+ });
512
+ }
513
+ } catch (e) {
514
+ console.log(e);
515
+ }
516
+ }
517
+
518
+ // Create an observer instance
519
+ let productsMutationObserver = new MutationObserver(function (mutations) {
520
+
521
+ mutations.forEach(function (mutation) {
522
+ let newNodes = mutation.addedNodes; // DOM NodeList
523
+ if (newNodes !== null) { // If there are new nodes added
524
+ let nodes = jQuery(newNodes); // jQuery set
525
+ nodes.each(function () {
526
+ if (
527
+ jQuery(this).hasClass("type-product") ||
528
+ jQuery(this).hasClass("product-small") ||
529
+ jQuery(this).hasClass('wc-block-grid__product')
530
+ ) {
531
+ // check if the node has a child or sibling wooptpmProductId
532
+ // if yes add it to the intersectionObserver
533
+ if (hasWooptpmProductIdElement(this)) {
534
+ jQuery(this).data('ioid', ioid++);
535
+ io.observe(this)
536
+ }
537
+ }
538
+ });
539
+ }
540
+ });
541
+ });
542
+
543
+ let hasWooptpmProductIdElement = function (elem) {
544
+ return !!(jQuery(elem).find('.wooptpmProductId').length ||
545
+ jQuery(elem).siblings('.wooptpmProductId').length);
546
  }
547
 
548
  // return {
559
 
560
  }(window.wooptpm = window.wooptpm || {}, jQuery));
561
 
562
+ // run when window ready
563
  jQuery(function () {
564
  // jQuery(window).on('load', function () {
565
 
566
+ // watch for products visible in viewport
567
+ wooptpm.startIntersectionObserverToWatch();
568
+
569
+ // watch for lazy loaded products
570
+ wooptpm.startProductsMutationObserverToWatch();
571
+
572
+ let body = jQuery('body');
573
+ let products = jQuery('.products, .product');
574
  // remove_from_cart event
575
+ body.on('click', '.remove_from_cart_button, .remove', function (e) {
576
 
577
+ try {
578
+ // console.log('remove_from_cart: ' + jQuery(this).data('product_id'));
579
 
580
+ wooptpm.removeProductFromCart(jQuery(this).data('product_id'));
581
+
582
+ } catch (e) {
583
+ console.log(e);
 
 
 
 
 
584
  }
585
  });
586
 
587
+
588
  // add_to_cart event
589
+ body.on('click', '.add_to_cart_button:not(.product_type_variable), .ajax_add_to_cart, .single_add_to_cart_button', function (e) {
590
+
591
+ try {
592
+ // console.log('add_to_cart');
593
 
594
+ if (wooptpmDataLayer.shop.page_type === 'product') {
 
 
595
 
596
+ // first process related and upsell products
597
+ if (typeof jQuery(this).attr('href') !== 'undefined' && jQuery(this).attr('href').includes('add-to-cart')) {
598
+ // console.log('add-to-cart on upsell and related products');
599
+ let quantity = 1;
600
+ let productId = jQuery(this).data('product_id');
601
+ // console.log('productId: ' + productId);
602
+ wooptpm.addProductToCart(productId, quantity);
603
+ } else {
604
 
605
+ if (wooptpmDataLayer.shop.product_type === 'simple') {
606
 
607
+ // console.log('test');
608
+ let quantity = Number(jQuery('.input-text.qty').val());
609
+ let productId = jQuery(this).val();
610
+ // console.log('productId: ' + productId);
611
+ wooptpm.addProductToCart(productId, quantity);
612
 
613
+ } else if (wooptpmDataLayer.shop.product_type === 'variable') {
 
 
 
 
 
 
614
 
615
+ // console.log('variable');
616
+
617
+ let quantity = Number(jQuery('.input-text.qty').val());
618
+ let productId = jQuery("[name='variation_id']").val();
619
+ wooptpm.addProductToCart(productId, quantity);
620
+
621
+ } else if (wooptpmDataLayer.shop.product_type === 'grouped') {
622
+
623
+ // console.log('grouped');
624
+
625
+ jQuery('.woocommerce-grouped-product-list-item').each(function () {
626
+ let quantity = Number(jQuery(this).find('.input-text.qty').val());
627
+ let classes = jQuery(this).attr('class');
628
+ let productId = wooptpm.getPostIdFromString(classes);
629
+ wooptpm.addProductToCart(productId, quantity);
630
+ });
631
+ }
632
+ }
633
  } else {
634
+
635
+ // console.log('non product page');
636
+
637
+ let quantity = 1;
638
+ let productId = jQuery(this).data('product_id');
639
+ // console.log('productId: ' + productId);
640
  wooptpm.addProductToCart(productId, quantity);
641
  }
642
+ } catch (e) {
643
+ console.log(e);
 
 
 
 
 
644
  }
645
  });
646
 
647
  // if someone clicks anywhere on a custom /?add-to-cart=123 link
648
  // trigger the add to cart event
649
+ body.one('click', function (e) {
650
 
651
+ try {
652
+ if (jQuery(this)[0].URL) {
653
 
654
+ let href = new URL(jQuery(this)[0].URL);
655
+ let searchParams = new URLSearchParams(href.search);
656
 
657
+ if (searchParams.has('add-to-cart')) {
658
+ // console.log('non product page, /?add-to-cart=123 link');
659
 
660
+ let productId = searchParams.get('add-to-cart');
661
+ wooptpm.addProductToCart(productId, 1);
662
+ }
663
  }
664
+ } catch (e) {
665
+ console.log(e);
666
  }
667
+
668
  });
669
 
670
 
671
+ // select_content GA UA event
672
+ // select_item GA 4 event
673
+ // jQuery(document).on('click', '.woocommerce-LoopProduct-link, .wc-block-grid__product, .product-small.box', function (e) {
674
+ body.on('click', '.woocommerce-LoopProduct-link, .wc-block-grid__product, .product, .product-small, .type-product', function (e) {
675
 
676
+ try {
677
 
678
+ // On some pages the event fires multiple times, and on product pages
679
+ // even on page load. Using e.stopPropagation helps to prevent this,
680
+ // but I dont know why. We don't even have to use this, since only a real
681
+ // product click yields a valid productId. So we filter the invalid click
682
+ // events out later down the code. I'll keep it that way because this is
683
+ // the most compatible way across shops.
684
+ // e.stopPropagation();
685
 
686
+ // console.log('select_content and select_item');
 
 
687
 
688
+ let productId = jQuery(this).nextAll('.wooptpmProductId:first').data('id');
689
+ // console.log('select_content and select_item: ' + productId);
 
 
 
 
 
 
 
 
 
 
690
 
691
+
692
+ // On product pages, for some reason, the click event is triggered on the main product on page load.
693
+ // In that case no ID is found. But we can discard it, since we only want to trigger the event on
694
+ // related products, which are found below.
695
+ if (productId) {
696
+
697
+ // console.log('select_content and select_item: ' + productId);
698
+
699
+ productId = getIdBasedOndVariationsOutputSetting(productId);
700
+
701
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
702
+
703
+ // console.log('prodid: ' + productId);
704
+
705
+ if (wooptpmDataLayer.products && wooptpmDataLayer.products[productId]) {
706
+
707
+ let data = {
708
+ "id" : productId.toString(),
709
+ "dyn_r_ids" : wooptpmDataLayer.products[productId].dyn_r_ids,
710
+ "name" : wooptpmDataLayer.products[productId].name,
711
+ "list_name" : wooptpmDataLayer.shop.list_name,
712
+ "brand" : wooptpmDataLayer.products[productId].brand,
713
+ "category" : wooptpmDataLayer.products[productId].category,
714
+ "variant" : wooptpmDataLayer.products[productId].variant,
715
+ "list_position": wooptpmDataLayer.products[productId].position,
716
+ "quantity" : 1,
717
+ "price" : wooptpmDataLayer.products[productId].price
718
+ };
719
+
720
+ jQuery(document).trigger('wooptpmSelectContentGaUa', data);
721
+ jQuery(document).trigger('wooptpmSelectItem', data);
722
+ }
723
+ }
724
+ } catch (e) {
725
+ console.log(e);
726
+ }
727
+ });
728
 
729
  // begin_checkout event
730
+ body.one('click', '.checkout-button, .cart-checkout-button, .button.checkout', function (e) {
731
+
732
+ // console.log('begin_checkout');
733
 
734
  jQuery(document).trigger('wooptpmBeginCheckout');
735
  });
736
 
737
+ let emailSelected = false;
738
+
739
+ // checkout_progress event
740
  // track checkout option event: entered valid billing email
741
+ body.on('input', '#billing_email', function () {
742
 
743
  if (wooptpm.isEmail(jQuery(this).val())) {
744
+ // wooptpm.fireCheckoutOption(2);
745
+ wooptpm.fireCheckoutProgress(2);
746
+ emailSelected = true;
747
  }
748
  });
749
 
750
  // track checkout option event: purchase click
751
+ let paymentMethodSelected = false;
752
+
753
+ body.on('click', '.wc_payment_methods', function () {
754
 
755
+ if (paymentMethodSelected === false) {
756
+ wooptpm.fireCheckoutProgress(3);
757
+ }
758
 
759
  wooptpm.fireCheckoutOption(3, jQuery("input[name='payment_method']:checked").val());
760
+ paymentMethodSelected = true;
761
  });
762
 
763
  // track checkout option event: purchase click
764
+ body.one('click', '#place_order', function () {
765
 
766
+ if (emailSelected === false) {
767
+ wooptpm.fireCheckoutProgress(2);
768
+ }
769
 
770
+ if (paymentMethodSelected === false) {
771
+ wooptpm.fireCheckoutProgress(3);
772
  wooptpm.fireCheckoutOption(3, jQuery("input[name='payment_method']:checked").val());
773
  }
774
 
775
+ wooptpm.fireCheckoutProgress(4);
776
  });
777
 
778
  // update cart event
779
+ body.on('click', "[name='update_cart']", function (e) {
780
+
781
+ try {
782
+ jQuery('.cart_item').each(function () {
783
+
784
+ let productId = jQuery(this).find('[data-product_id]').data('product_id');
785
 
786
+ let quantity = jQuery(this).find('.qty').val();
 
 
 
 
 
787
 
788
+ if (quantity === 0) {
789
+ wooptpm.removeProductFromCart(productId);
790
+ } else if (quantity < wooptpmDataLayer.cart[productId].quantity) {
791
+ wooptpm.removeProductFromCart(productId, wooptpmDataLayer.cart[productId].quantity - quantity);
792
+ } else if (quantity > wooptpmDataLayer.cart[productId].quantity) {
793
+ wooptpm.addProductToCart(productId, quantity - wooptpmDataLayer.cart[productId].quantity);
794
+ }
795
+ });
796
+ } catch (e) {
797
+ console.log(e);
798
+ }
799
+ });
800
+
801
+ // Fired when the user selects all the required dropdowns / attributes
802
+ // https://stackoverflow.com/a/27849208/4688612
803
+ jQuery(".single_variation_wrap").on("show_variation", function (event, variation) {
804
+
805
+ try {
806
+ // Fired when the user selects all the required dropdowns / attributes
807
+ // console.log('product selected');
808
+ // console.log(variation);
809
 
810
+ let productId = getIdBasedOndVariationsOutputSetting(variation.variation_id);
811
 
812
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
813
+
814
+ if (wooptpmDataLayer.products && wooptpmDataLayer.products[productId]) {
815
+
816
+ // console.log('productId: ' + productId);
817
+
818
+ let data = {
819
+ "id" : productId.toString(),
820
+ "dyn_r_ids" : wooptpmDataLayer.products[productId].dyn_r_ids,
821
+ "name" : wooptpmDataLayer.products[productId].name,
822
+ "list_name" : wooptpmDataLayer.shop.list_name,
823
+ "brand" : wooptpmDataLayer.products[productId].brand,
824
+ "category" : wooptpmDataLayer.products[productId].category,
825
+ "variant" : wooptpmDataLayer.products[productId].variant,
826
+ "list_position": wooptpmDataLayer.products[productId].position,
827
+ "quantity" : 1,
828
+ "price" : wooptpmDataLayer.products[productId].price
829
+ };
830
+
831
+ jQuery(document).trigger('wooptpmViewItem', data);
832
  }
833
+ } catch (e) {
834
+ console.log(e);
835
+ }
836
  });
837
+
838
+ // add_to_wishlist
839
+ body.on('click', '.add_to_wishlist, .wl-add-to', function () {
840
+ try {
841
+ // console.log('add_to_wishlist');
842
+ // console.log('this:' + jQuery(this).data('product-id'));
843
+
844
+ let productId;
845
+
846
+ if (jQuery(this).data('productid')) { // for the WooCommerce wishlist plugin
847
+ productId = jQuery(this).data('productid');
848
+ } else if (jQuery(this).data('product-id')) { // for the YITH wishlist plugin
849
+ productId = jQuery(this).data('product-id');
850
+ }
851
+
852
+ if (!productId) throw Error('Wasn\'t able to retrieve a productId');
853
+
854
+ let product = {
855
+ "id" : productId.toString(),
856
+ "dyn_r_ids" : wooptpmDataLayer.products[productId].dyn_r_ids,
857
+ "name" : wooptpmDataLayer.products[productId].name,
858
+ "list_name" : wooptpmDataLayer.shop.list_name,
859
+ "brand" : wooptpmDataLayer.products[productId].brand,
860
+ "category" : wooptpmDataLayer.products[productId].category,
861
+ "variant" : wooptpmDataLayer.products[productId].variant,
862
+ "list_position": wooptpmDataLayer.products[productId].position,
863
+ "quantity" : 1,
864
+ "price" : wooptpmDataLayer.products[productId].price
865
+ };
866
+
867
+ // console.log('add_to_wishlist');
868
+ // console.log(product);
869
+
870
+ jQuery(document).trigger('wooptpmAddToWishlist', product);
871
+ } catch (e) {
872
+ console.log(e);
873
+ }
874
+ })
875
  });
876
 
877
 
878
  jQuery(window).on('load', function () {
879
  // populate the wooptpmDataLayer with the cart items
880
+ // console.log('getting cart');
881
+
882
+ try {
883
+ wooptpm.getCartItemsFromBackEnd();
884
+ } catch (e) {
885
+ console.log(e);
886
+ }
887
+ // wooptpm.loadPageProductsFromBackend();
888
  });
languages/woocommerce-google-adwords-conversion-tracking-tag.pot CHANGED
@@ -2,14 +2,14 @@
2
  # This file is distributed under the same license as the WooCommerce Conversion Tracking plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WooCommerce Conversion Tracking 1.8.28\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2021-04-05T15:10:31+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: woocommerce-google-adwords-conversion-tracking-tag\n"
@@ -34,513 +34,538 @@ msgstr ""
34
  msgid "https://woopt.com"
35
  msgstr ""
36
 
37
- #: classes/admin/class-admin.php:122
38
- #: classes/admin/class-admin.php:123
39
  msgid "Google Ads Conversion Tracking"
40
  msgstr ""
41
 
42
- #: classes/admin/class-admin.php:191
43
  msgid "Google Ads Conversion ID"
44
  msgstr ""
45
 
46
- #: classes/admin/class-admin.php:203
47
  msgid "Google Ads Conversion Label"
48
  msgstr ""
49
 
50
- #: classes/admin/class-admin.php:214
51
  msgid "Google Analytics UA"
52
  msgstr ""
53
 
54
- #: classes/admin/class-admin.php:225
55
  msgid "Google Analytics 4"
56
  msgstr ""
57
 
58
- #: classes/admin/class-admin.php:236
59
  msgid "Google Optimize"
60
  msgstr ""
61
 
62
- #: classes/admin/class-admin.php:269
63
  msgid "Facebook pixel ID"
64
  msgstr ""
65
 
66
- #: classes/admin/class-admin.php:304
67
  msgid "Microsoft Advertising UET tag ID"
68
  msgstr ""
69
 
70
- #: classes/admin/class-admin.php:316
71
  msgid "Twitter pixel ID"
72
  msgstr ""
73
 
74
- #: classes/admin/class-admin.php:328
75
  msgid "Pinterest pixel ID"
76
  msgstr ""
77
 
78
- #: classes/admin/class-admin.php:341
79
  msgid "Hotjar site ID"
80
  msgstr ""
81
 
82
- #: classes/admin/class-admin.php:403
83
  msgid "Order Total Logic"
84
  msgstr ""
85
 
86
- #: classes/admin/class-admin.php:415
87
  msgid "Order deduplication"
88
  msgstr ""
89
 
90
- #: classes/admin/class-admin.php:427
91
  msgid "Maximum Compatibility Mode"
92
  msgstr ""
93
 
94
- #: classes/admin/class-admin.php:461
95
  msgid "gtag Deactivation"
96
  msgstr ""
97
 
98
- #: classes/admin/class-admin.php:475
99
  msgid "Enhanced E-Commerce"
100
  msgstr ""
101
 
102
- #: classes/admin/class-admin.php:488
 
 
 
 
103
  msgid "Enhanced Link Attribution"
104
  msgstr ""
105
 
106
- #: classes/admin/class-admin.php:501
107
  msgid "Google User ID"
108
  msgstr ""
109
 
110
- #: classes/admin/class-admin.php:515
111
  msgid "Google Ads phone conversion number"
112
  msgstr ""
113
 
114
- #: classes/admin/class-admin.php:527
115
  msgid "Google Ads phone conversion label"
116
  msgstr ""
117
 
118
- #: classes/admin/class-admin.php:561
119
  msgid "Google Consent Mode"
120
  msgstr ""
121
 
122
- #: classes/admin/class-admin.php:573
123
  msgid "Google Consent Regions"
124
  msgstr ""
125
 
126
- #: classes/admin/class-admin.php:586
127
  msgid "Borlabs support"
128
  msgstr ""
129
 
130
- #: classes/admin/class-admin.php:599
131
  msgid "Cookiebot support"
132
  msgstr ""
133
 
134
- #: classes/admin/class-admin.php:633
135
  msgid "Facebook microdata"
136
  msgstr ""
137
 
138
- #: classes/admin/class-admin.php:656
139
  msgid "Beta"
140
  msgstr ""
141
 
142
- #: classes/admin/class-admin.php:679
143
  msgid "Conversion Cart Data"
144
  msgstr ""
145
 
146
- #: classes/admin/class-admin.php:715
147
  msgid "Product Identifier"
148
  msgstr ""
149
 
150
- #: classes/admin/class-admin.php:727
151
  msgid "Dynamic Remarketing"
152
  msgstr ""
153
 
154
- #: classes/admin/class-admin.php:739
155
  msgid "Variations output"
156
  msgstr ""
157
 
158
- #: classes/admin/class-admin.php:752
159
  msgid "Google Business Vertical"
160
  msgstr ""
161
 
162
- #: classes/admin/class-admin.php:775
163
  msgid "Support"
164
  msgstr ""
165
 
166
- #: classes/admin/class-admin.php:793
167
  msgid "Author"
168
  msgstr ""
169
 
170
- #: classes/admin/class-admin.php:830
171
  msgid ""
172
  "It looks like you are using some sort of ad or script blocker which is blocking the script and CSS files of this plugin.\n"
173
  " In order for the plugin to work properly you need to disable the script blocker."
174
  msgstr ""
175
 
176
- #: classes/admin/class-admin.php:837
177
  #: classes/admin/class-notifications.php:25
178
  #: classes/admin/class-notifications.php:66
179
  msgid "Learn more"
180
  msgstr ""
181
 
182
- #: classes/admin/class-admin.php:871
183
  msgid "Profit Driven Marketing by woopt"
184
  msgstr ""
185
 
186
- #: classes/admin/class-admin.php:876
187
  msgid "Visit us here:"
188
  msgstr ""
189
 
190
- #: classes/admin/class-admin.php:946
191
  msgid "Support contacts"
192
  msgstr ""
193
 
194
- #: classes/admin/class-admin.php:948
195
  msgid "Use the following two resources for support: "
196
  msgstr ""
197
 
198
- #: classes/admin/class-admin.php:955
199
  msgid "Post a support request in the WordPress support forum here: "
200
  msgstr ""
201
 
202
- #: classes/admin/class-admin.php:959
203
  msgid "Support forum"
204
  msgstr ""
205
 
206
- #: classes/admin/class-admin.php:964
207
  msgid "(Never post the debug or other sensitive information to the support forum. Instead send us the information by email.)"
208
  msgstr ""
209
 
210
- #: classes/admin/class-admin.php:968
211
  msgid "Or send us an email to the following address: "
212
  msgstr ""
213
 
214
- #: classes/admin/class-admin.php:976
215
  msgid "Translations"
216
  msgstr ""
217
 
218
- #: classes/admin/class-admin.php:978
219
  msgid "If you want to participate improving the translations of this plugin into your language, please follow this link:"
220
  msgstr ""
221
 
222
- #: classes/admin/class-admin.php:986
223
  msgid "Debugging information"
224
  msgstr ""
225
 
226
- #: classes/admin/class-admin.php:997
227
  msgid "copy to clipboard"
228
  msgstr ""
229
 
230
- #: classes/admin/class-admin.php:1012
231
  msgid "More details about the developer of this plugin: "
232
  msgstr ""
233
 
234
- #: classes/admin/class-admin.php:1016
235
  msgid "Developer: woopt"
236
  msgstr ""
237
 
238
- #: classes/admin/class-admin.php:1020
239
  msgid "Website: "
240
  msgstr ""
241
 
242
- #: classes/admin/class-admin.php:1034
243
  msgid "The Google Analytics Universal property ID looks like this:"
244
  msgstr ""
245
 
246
- #: classes/admin/class-admin.php:1044
247
  msgid "The Google Analytics 4 measurement ID looks like this:"
248
  msgstr ""
249
 
250
- #: classes/admin/class-admin.php:1054
251
  msgid "The conversion ID looks similar to this:"
252
  msgstr ""
253
 
254
- #: classes/admin/class-admin.php:1064
255
  msgid "The conversion Label looks similar to this:"
256
  msgstr ""
257
 
258
- #: classes/admin/class-admin.php:1068
259
- #: classes/admin/class-admin.php:1559
260
  msgid "Requires an active Google Ads Conversion ID"
261
  msgstr ""
262
 
263
- #: classes/admin/class-admin.php:1079
264
  msgid "The Google Optimize container ID looks like this:"
265
  msgstr ""
266
 
267
- #: classes/admin/class-admin.php:1089
268
  msgid "The Facebook pixel ID looks similar to this:"
269
  msgstr ""
270
 
271
- #: classes/admin/class-admin.php:1100
272
  msgid "The Microsoft Advertising UET tag ID looks similar to this:"
273
  msgstr ""
274
 
275
- #: classes/admin/class-admin.php:1111
276
  msgid "The Twitter pixel ID looks similar to this:"
277
  msgstr ""
278
 
279
- #: classes/admin/class-admin.php:1122
280
  msgid "The Pinterest pixel ID looks similar to this:"
281
  msgstr ""
282
 
283
- #: classes/admin/class-admin.php:1132
284
  msgid "The Hotjar site ID looks similar to this:"
285
  msgstr ""
286
 
287
- #: classes/admin/class-admin.php:1144
288
  msgid "Use order_subtotal: Doesn't include tax and shipping (default)"
289
  msgstr ""
290
 
291
- #: classes/admin/class-admin.php:1152
292
  msgid "Use order_total: Includes tax and shipping"
293
  msgstr ""
294
 
295
- #: classes/admin/class-admin.php:1156
296
  msgid "This is the order total amount reported back to Google Ads"
297
  msgstr ""
298
 
299
- #: classes/admin/class-admin.php:1164
300
  msgid "open the documentation"
301
  msgstr ""
302
 
303
- #: classes/admin/class-admin.php:1183
304
  msgid "Disable gtag.js insertion, if another plugin is inserting it already"
305
  msgstr ""
306
 
307
- #: classes/admin/class-admin.php:1192
308
  msgid "Only do this, if the other plugin does insert the gtag above this pixel. If not, keep the gtag active."
309
  msgstr ""
310
 
311
- #: classes/admin/class-admin.php:1197
312
  msgid "This setting is deprecated. It will be removed in future versions of the plugin. Read more about it in the documentation."
313
  msgstr ""
314
 
315
- #: classes/admin/class-admin.php:1216
316
  msgid "Enable Google consent mode with standard settings"
317
  msgstr ""
318
 
319
- #: classes/admin/class-admin.php:1254
320
  msgid "If no region is set, then the restrictions are enabled for all regions. If you specify one or more regions, then the restrictions only apply for the specified regions."
321
  msgstr ""
322
 
323
- #: classes/admin/class-admin.php:1275
324
  msgid "Enable Google Analytics enhanced e-commerce"
325
  msgstr ""
326
 
327
- #: classes/admin/class-admin.php:1285
328
- #: classes/admin/class-admin.php:1313
329
- #: classes/admin/class-admin.php:1343
330
  msgid "You need to activate at least Google Analytics UA or Google Analytics 4"
331
  msgstr ""
332
 
333
- #: classes/admin/class-admin.php:1303
 
 
 
 
 
 
 
 
 
 
 
 
334
  msgid "Enable Google Analytics enhanced link attribution"
335
  msgstr ""
336
 
337
- #: classes/admin/class-admin.php:1333
338
  msgid "Enable Google user ID"
339
  msgstr ""
340
 
341
- #: classes/admin/class-admin.php:1362
342
  msgid "The Google Ads phone conversion number must be in the same format as on the website."
343
  msgstr ""
344
 
345
- #: classes/admin/class-admin.php:1384
346
  msgid "Borlabs detected. Automatic support is:"
347
  msgstr ""
348
 
349
- #: classes/admin/class-admin.php:1404
350
  msgid "Enable Cookiebot settings"
351
  msgstr ""
352
 
353
- #: classes/admin/class-admin.php:1410
354
  msgid "You need to activate the Google consent mode"
355
  msgstr ""
356
 
357
- #: classes/admin/class-admin.php:1430
358
- msgid "Enable Facebook product microdata output"
 
359
  msgstr ""
360
 
361
- #: classes/admin/class-admin.php:1437
362
- msgid "You need to activate the Facebook pixel"
363
  msgstr ""
364
 
365
- #: classes/admin/class-admin.php:1455
366
  msgid "Add the cart data to the conversion event"
367
  msgstr ""
368
 
369
- #: classes/admin/class-admin.php:1463
370
  msgid "Requires an active Google Ads Conversion ID, an active Conversion Label and an active Google Merchant Center ID (aw_merchant_id)"
371
  msgstr ""
372
 
373
- #: classes/admin/class-admin.php:1489
374
  msgid "Only disable order deduplication for testing. Remember to re-enable the setting once done."
375
  msgstr ""
376
 
377
- #: classes/admin/class-admin.php:1507
378
  msgid "Enable the maximum compatibility mode"
379
  msgstr ""
380
 
381
- #: classes/admin/class-admin.php:1519
382
  msgid "Advanced order deduplication is "
383
  msgstr ""
384
 
385
- #: classes/admin/class-admin.php:1521
386
  msgid "Basic order deduplication is "
387
  msgstr ""
388
 
389
- #: classes/admin/class-admin.php:1548
390
  msgid "Enable dynamic remarketing audience collection"
391
  msgstr ""
392
 
393
- #: classes/admin/class-admin.php:1564
394
  msgid "You need to choose the correct product identifier setting in order to match the product identifiers in the Google Merchant Center or your Google Ads business feed"
395
  msgstr ""
396
 
397
- #: classes/admin/class-admin.php:1583
398
  msgid "Enable variations output"
399
  msgstr ""
400
 
401
- #: classes/admin/class-admin.php:1591
402
  msgid "In order for this to work you need to upload your Google Merchant Center feed including product variations and the item_group_id. Disable it, if you choose only to upload the parent product for variable products."
403
  msgstr ""
404
 
405
- #: classes/admin/class-admin.php:1606
406
  msgid "Retail"
407
  msgstr ""
408
 
409
- #: classes/admin/class-admin.php:1616
410
  msgid "Education"
411
  msgstr ""
412
 
413
- #: classes/admin/class-admin.php:1626
414
  msgid "Hotels and rentals"
415
  msgstr ""
416
 
417
- #: classes/admin/class-admin.php:1636
418
  msgid "Jobs"
419
  msgstr ""
420
 
421
- #: classes/admin/class-admin.php:1646
422
  msgid "Local deals"
423
  msgstr ""
424
 
425
- #: classes/admin/class-admin.php:1656
426
  msgid "Real estate"
427
  msgstr ""
428
 
429
- #: classes/admin/class-admin.php:1666
430
  msgid "Custom"
431
  msgstr ""
432
 
433
- #: classes/admin/class-admin.php:1679
434
  msgid "ID of your Google Merchant Center account. It looks like this: 12345678"
435
  msgstr ""
436
 
437
- #: classes/admin/class-admin.php:1696
438
  msgid "Currently the plugin automatically detects the location of the visitor for this setting. In most, if not all, cases this will work fine. Please let us know if you have a use case where you need another output:"
439
  msgstr ""
440
 
441
- #: classes/admin/class-admin.php:1733
442
  msgid "The plugin will use the WordPress default language for this setting. If the shop uses translations, in theory we could also use the visitors locale. But, if that language is not set up in the Google Merchant Center we might run into issues. If you need more options here let us know:"
443
  msgstr ""
444
 
445
- #: classes/admin/class-admin.php:1753
446
  msgid "post id (default)"
447
  msgstr ""
448
 
449
- #: classes/admin/class-admin.php:1760
450
  msgid "post id with woocommerce_gpf_ prefix *"
451
  msgstr ""
452
 
453
- #: classes/admin/class-admin.php:1768
454
  msgid "SKU"
455
  msgstr ""
456
 
457
- #: classes/admin/class-admin.php:1773
458
  msgid "Choose a product identifier."
459
  msgstr ""
460
 
461
- #: classes/admin/class-admin.php:1776
462
  msgid "* This is for users of the WooCommerce Google Product Feed Plugin"
463
  msgstr ""
464
 
465
- #: classes/admin/class-admin.php:1858
466
  msgid "You have entered an invalid Google Analytics Universal property ID."
467
  msgstr ""
468
 
469
- #: classes/admin/class-admin.php:1866
470
  msgid "You have entered an invalid Google Analytics 4 measurement ID."
471
  msgstr ""
472
 
473
- #: classes/admin/class-admin.php:1874
 
 
 
 
474
  msgid "You have entered an invalid conversion ID. It only contains 8 to 10 digits."
475
  msgstr ""
476
 
477
- #: classes/admin/class-admin.php:1882
478
- #: classes/admin/class-admin.php:1890
479
  msgid "You have entered an invalid conversion label."
480
  msgstr ""
481
 
482
- #: classes/admin/class-admin.php:1898
483
  msgid "You have entered an invalid merchant ID. It only contains 7 to 10 digits."
484
  msgstr ""
485
 
486
- #: classes/admin/class-admin.php:1906
487
  msgid "You have entered an invalid Google Optimize container ID."
488
  msgstr ""
489
 
490
- #: classes/admin/class-admin.php:1914
491
  msgid "You have entered an invalid Facebook pixel ID. It only contains 14 to 16 digits."
492
  msgstr ""
493
 
494
- #: classes/admin/class-admin.php:1922
 
 
 
 
495
  msgid "You have entered an invalid Bing Ads UET tag ID. It only contains 7 to 9 digits."
496
  msgstr ""
497
 
498
- #: classes/admin/class-admin.php:1930
499
  msgid "You have entered an invalid Twitter pixel ID. It only contains 5 to 7 lowercase letters and numbers."
500
  msgstr ""
501
 
502
- #: classes/admin/class-admin.php:1938
503
  msgid "You have entered an invalid Pinterest pixel ID. It only contains 13 digits."
504
  msgstr ""
505
 
506
- #: classes/admin/class-admin.php:1946
507
  msgid "You have entered an invalid Hotjar site ID. It only contains 7 to 9 digits."
508
  msgstr ""
509
 
510
  #. translators: %d: the amount of purchase conversions that have been measured
511
- #: classes/admin/class-ask-for-rating.php:132
512
  msgid "Hey, I noticed that you tracked more than %d purchase conversions with the Google Ads Conversion Tracking plugin - that's awesome! Could you please do me a BIG favour and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation."
513
  msgstr ""
514
 
515
- #: classes/admin/class-ask-for-rating.php:146
516
  msgid "Ok, you deserve it"
517
  msgstr ""
518
 
519
- #: classes/admin/class-ask-for-rating.php:151
520
  msgid "Nope, maybe later"
521
  msgstr ""
522
 
523
- #: classes/admin/class-ask-for-rating.php:156
524
  msgid "I already did"
525
  msgstr ""
526
 
527
- #: classes/admin/class-launch-deal.php:112
528
  msgid "I am super happy and excited to announce our <a href=\"https://woopt.com/launch-deal-8a63336b/\" target=\"_blank\">special deal</a> for the launch of the <a href=\"https://woopt.com/\" target=\"_blank\">pro version</a> of the <b>woopt WooCommerce Pixel Manager Plugin</b> (formerly known as the <b>WooCommmerce Google Ads Conversion Tracking Plugin</b>)."
529
  msgstr ""
530
 
531
- #: classes/admin/class-launch-deal.php:119
532
  msgid "Because you are an existing user of this plugin you are eligible to receive a generous discount if you chose to participate in the launch deal. After all, you helped to shape the plugin into what it is today. Go ahead and have a look."
533
  msgstr ""
534
 
535
- #: classes/admin/class-launch-deal.php:132
536
  msgid "Take me to the deal!"
537
  msgstr ""
538
 
539
- #: classes/admin/class-launch-deal.php:137
540
  msgid "Maybe later"
541
  msgstr ""
542
 
543
- #: classes/admin/class-launch-deal.php:142
544
  msgid "Not interested. Close this message."
545
  msgstr ""
546
 
2
  # This file is distributed under the same license as the WooCommerce Conversion Tracking plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WooCommerce Conversion Tracking 1.9.6\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2021-04-29T09:20:47+00:00\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
  "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: woocommerce-google-adwords-conversion-tracking-tag\n"
34
  msgid "https://woopt.com"
35
  msgstr ""
36
 
37
+ #: classes/admin/class-admin.php:131
38
+ #: classes/admin/class-admin.php:132
39
  msgid "Google Ads Conversion Tracking"
40
  msgstr ""
41
 
42
+ #: classes/admin/class-admin.php:200
43
  msgid "Google Ads Conversion ID"
44
  msgstr ""
45
 
46
+ #: classes/admin/class-admin.php:212
47
  msgid "Google Ads Conversion Label"
48
  msgstr ""
49
 
50
+ #: classes/admin/class-admin.php:223
51
  msgid "Google Analytics UA"
52
  msgstr ""
53
 
54
+ #: classes/admin/class-admin.php:234
55
  msgid "Google Analytics 4"
56
  msgstr ""
57
 
58
+ #: classes/admin/class-admin.php:245
59
  msgid "Google Optimize"
60
  msgstr ""
61
 
62
+ #: classes/admin/class-admin.php:278
63
  msgid "Facebook pixel ID"
64
  msgstr ""
65
 
66
+ #: classes/admin/class-admin.php:313
67
  msgid "Microsoft Advertising UET tag ID"
68
  msgstr ""
69
 
70
+ #: classes/admin/class-admin.php:325
71
  msgid "Twitter pixel ID"
72
  msgstr ""
73
 
74
+ #: classes/admin/class-admin.php:337
75
  msgid "Pinterest pixel ID"
76
  msgstr ""
77
 
78
+ #: classes/admin/class-admin.php:350
79
  msgid "Hotjar site ID"
80
  msgstr ""
81
 
82
+ #: classes/admin/class-admin.php:412
83
  msgid "Order Total Logic"
84
  msgstr ""
85
 
86
+ #: classes/admin/class-admin.php:424
87
  msgid "Order deduplication"
88
  msgstr ""
89
 
90
+ #: classes/admin/class-admin.php:436
91
  msgid "Maximum Compatibility Mode"
92
  msgstr ""
93
 
94
+ #: classes/admin/class-admin.php:470
95
  msgid "gtag Deactivation"
96
  msgstr ""
97
 
98
+ #: classes/admin/class-admin.php:484
99
  msgid "Enhanced E-Commerce"
100
  msgstr ""
101
 
102
+ #: classes/admin/class-admin.php:496
103
+ msgid "GA 4 API secret"
104
+ msgstr ""
105
+
106
+ #: classes/admin/class-admin.php:509
107
  msgid "Enhanced Link Attribution"
108
  msgstr ""
109
 
110
+ #: classes/admin/class-admin.php:522
111
  msgid "Google User ID"
112
  msgstr ""
113
 
114
+ #: classes/admin/class-admin.php:536
115
  msgid "Google Ads phone conversion number"
116
  msgstr ""
117
 
118
+ #: classes/admin/class-admin.php:548
119
  msgid "Google Ads phone conversion label"
120
  msgstr ""
121
 
122
+ #: classes/admin/class-admin.php:582
123
  msgid "Google Consent Mode"
124
  msgstr ""
125
 
126
+ #: classes/admin/class-admin.php:594
127
  msgid "Google Consent Regions"
128
  msgstr ""
129
 
130
+ #: classes/admin/class-admin.php:607
131
  msgid "Borlabs support"
132
  msgstr ""
133
 
134
+ #: classes/admin/class-admin.php:620
135
  msgid "Cookiebot support"
136
  msgstr ""
137
 
138
+ #: classes/admin/class-admin.php:665
139
  msgid "Facebook microdata"
140
  msgstr ""
141
 
142
+ #: classes/admin/class-admin.php:688
143
  msgid "Beta"
144
  msgstr ""
145
 
146
+ #: classes/admin/class-admin.php:711
147
  msgid "Conversion Cart Data"
148
  msgstr ""
149
 
150
+ #: classes/admin/class-admin.php:747
151
  msgid "Product Identifier"
152
  msgstr ""
153
 
154
+ #: classes/admin/class-admin.php:759
155
  msgid "Dynamic Remarketing"
156
  msgstr ""
157
 
158
+ #: classes/admin/class-admin.php:771
159
  msgid "Variations output"
160
  msgstr ""
161
 
162
+ #: classes/admin/class-admin.php:784
163
  msgid "Google Business Vertical"
164
  msgstr ""
165
 
166
+ #: classes/admin/class-admin.php:807
167
  msgid "Support"
168
  msgstr ""
169
 
170
+ #: classes/admin/class-admin.php:825
171
  msgid "Author"
172
  msgstr ""
173
 
174
+ #: classes/admin/class-admin.php:862
175
  msgid ""
176
  "It looks like you are using some sort of ad or script blocker which is blocking the script and CSS files of this plugin.\n"
177
  " In order for the plugin to work properly you need to disable the script blocker."
178
  msgstr ""
179
 
180
+ #: classes/admin/class-admin.php:869
181
  #: classes/admin/class-notifications.php:25
182
  #: classes/admin/class-notifications.php:66
183
  msgid "Learn more"
184
  msgstr ""
185
 
186
+ #: classes/admin/class-admin.php:903
187
  msgid "Profit Driven Marketing by woopt"
188
  msgstr ""
189
 
190
+ #: classes/admin/class-admin.php:908
191
  msgid "Visit us here:"
192
  msgstr ""
193
 
194
+ #: classes/admin/class-admin.php:978
195
  msgid "Support contacts"
196
  msgstr ""
197
 
198
+ #: classes/admin/class-admin.php:980
199
  msgid "Use the following two resources for support: "
200
  msgstr ""
201
 
202
+ #: classes/admin/class-admin.php:987
203
  msgid "Post a support request in the WordPress support forum here: "
204
  msgstr ""
205
 
206
+ #: classes/admin/class-admin.php:991
207
  msgid "Support forum"
208
  msgstr ""
209
 
210
+ #: classes/admin/class-admin.php:996
211
  msgid "(Never post the debug or other sensitive information to the support forum. Instead send us the information by email.)"
212
  msgstr ""
213
 
214
+ #: classes/admin/class-admin.php:1000
215
  msgid "Or send us an email to the following address: "
216
  msgstr ""
217
 
218
+ #: classes/admin/class-admin.php:1008
219
  msgid "Translations"
220
  msgstr ""
221
 
222
+ #: classes/admin/class-admin.php:1010
223
  msgid "If you want to participate improving the translations of this plugin into your language, please follow this link:"
224
  msgstr ""
225
 
226
+ #: classes/admin/class-admin.php:1018
227
  msgid "Debugging information"
228
  msgstr ""
229
 
230
+ #: classes/admin/class-admin.php:1029
231
  msgid "copy to clipboard"
232
  msgstr ""
233
 
234
+ #: classes/admin/class-admin.php:1044
235
  msgid "More details about the developer of this plugin: "
236
  msgstr ""
237
 
238
+ #: classes/admin/class-admin.php:1048
239
  msgid "Developer: woopt"
240
  msgstr ""
241
 
242
+ #: classes/admin/class-admin.php:1052
243
  msgid "Website: "
244
  msgstr ""
245
 
246
+ #: classes/admin/class-admin.php:1066
247
  msgid "The Google Analytics Universal property ID looks like this:"
248
  msgstr ""
249
 
250
+ #: classes/admin/class-admin.php:1076
251
  msgid "The Google Analytics 4 measurement ID looks like this:"
252
  msgstr ""
253
 
254
+ #: classes/admin/class-admin.php:1086
255
  msgid "The conversion ID looks similar to this:"
256
  msgstr ""
257
 
258
+ #: classes/admin/class-admin.php:1096
259
  msgid "The conversion Label looks similar to this:"
260
  msgstr ""
261
 
262
+ #: classes/admin/class-admin.php:1100
263
+ #: classes/admin/class-admin.php:1641
264
  msgid "Requires an active Google Ads Conversion ID"
265
  msgstr ""
266
 
267
+ #: classes/admin/class-admin.php:1111
268
  msgid "The Google Optimize container ID looks like this:"
269
  msgstr ""
270
 
271
+ #: classes/admin/class-admin.php:1121
272
  msgid "The Facebook pixel ID looks similar to this:"
273
  msgstr ""
274
 
275
+ #: classes/admin/class-admin.php:1132
276
  msgid "The Microsoft Advertising UET tag ID looks similar to this:"
277
  msgstr ""
278
 
279
+ #: classes/admin/class-admin.php:1143
280
  msgid "The Twitter pixel ID looks similar to this:"
281
  msgstr ""
282
 
283
+ #: classes/admin/class-admin.php:1154
284
  msgid "The Pinterest pixel ID looks similar to this:"
285
  msgstr ""
286
 
287
+ #: classes/admin/class-admin.php:1164
288
  msgid "The Hotjar site ID looks similar to this:"
289
  msgstr ""
290
 
291
+ #: classes/admin/class-admin.php:1176
292
  msgid "Use order_subtotal: Doesn't include tax and shipping (default)"
293
  msgstr ""
294
 
295
+ #: classes/admin/class-admin.php:1184
296
  msgid "Use order_total: Includes tax and shipping"
297
  msgstr ""
298
 
299
+ #: classes/admin/class-admin.php:1188
300
  msgid "This is the order total amount reported back to Google Ads"
301
  msgstr ""
302
 
303
+ #: classes/admin/class-admin.php:1196
304
  msgid "open the documentation"
305
  msgstr ""
306
 
307
+ #: classes/admin/class-admin.php:1215
308
  msgid "Disable gtag.js insertion, if another plugin is inserting it already"
309
  msgstr ""
310
 
311
+ #: classes/admin/class-admin.php:1224
312
  msgid "Only do this, if the other plugin does insert the gtag above this pixel. If not, keep the gtag active."
313
  msgstr ""
314
 
315
+ #: classes/admin/class-admin.php:1229
316
  msgid "This setting is deprecated. It will be removed in future versions of the plugin. Read more about it in the documentation."
317
  msgstr ""
318
 
319
+ #: classes/admin/class-admin.php:1248
320
  msgid "Enable Google consent mode with standard settings"
321
  msgstr ""
322
 
323
+ #: classes/admin/class-admin.php:1286
324
  msgid "If no region is set, then the restrictions are enabled for all regions. If you specify one or more regions, then the restrictions only apply for the specified regions."
325
  msgstr ""
326
 
327
+ #: classes/admin/class-admin.php:1307
328
  msgid "Enable Google Analytics enhanced e-commerce"
329
  msgstr ""
330
 
331
+ #: classes/admin/class-admin.php:1317
332
+ #: classes/admin/class-admin.php:1372
333
+ #: classes/admin/class-admin.php:1402
334
  msgid "You need to activate at least Google Analytics UA or Google Analytics 4"
335
  msgstr ""
336
 
337
+ #: classes/admin/class-admin.php:1338
338
+ msgid "Google Analytics 4 activation required"
339
+ msgstr ""
340
+
341
+ #: classes/admin/class-admin.php:1343
342
+ msgid "Enhanced E-Commerce activation required"
343
+ msgstr ""
344
+
345
+ #: classes/admin/class-admin.php:1346
346
+ msgid "If enabled, purchase and refund events will be sent to Google through the measurement protocol for increased accuracy."
347
+ msgstr ""
348
+
349
+ #: classes/admin/class-admin.php:1362
350
  msgid "Enable Google Analytics enhanced link attribution"
351
  msgstr ""
352
 
353
+ #: classes/admin/class-admin.php:1392
354
  msgid "Enable Google user ID"
355
  msgstr ""
356
 
357
+ #: classes/admin/class-admin.php:1421
358
  msgid "The Google Ads phone conversion number must be in the same format as on the website."
359
  msgstr ""
360
 
361
+ #: classes/admin/class-admin.php:1443
362
  msgid "Borlabs detected. Automatic support is:"
363
  msgstr ""
364
 
365
+ #: classes/admin/class-admin.php:1463
366
  msgid "Enable Cookiebot settings"
367
  msgstr ""
368
 
369
+ #: classes/admin/class-admin.php:1469
370
  msgid "You need to activate the Google consent mode"
371
  msgstr ""
372
 
373
+ #: classes/admin/class-admin.php:1488
374
+ #: classes/admin/class-admin.php:1519
375
+ msgid "You need to activate the Facebook pixel"
376
  msgstr ""
377
 
378
+ #: classes/admin/class-admin.php:1512
379
+ msgid "Enable Facebook product microdata output"
380
  msgstr ""
381
 
382
+ #: classes/admin/class-admin.php:1537
383
  msgid "Add the cart data to the conversion event"
384
  msgstr ""
385
 
386
+ #: classes/admin/class-admin.php:1545
387
  msgid "Requires an active Google Ads Conversion ID, an active Conversion Label and an active Google Merchant Center ID (aw_merchant_id)"
388
  msgstr ""
389
 
390
+ #: classes/admin/class-admin.php:1571
391
  msgid "Only disable order deduplication for testing. Remember to re-enable the setting once done."
392
  msgstr ""
393
 
394
+ #: classes/admin/class-admin.php:1589
395
  msgid "Enable the maximum compatibility mode"
396
  msgstr ""
397
 
398
+ #: classes/admin/class-admin.php:1601
399
  msgid "Advanced order deduplication is "
400
  msgstr ""
401
 
402
+ #: classes/admin/class-admin.php:1603
403
  msgid "Basic order deduplication is "
404
  msgstr ""
405
 
406
+ #: classes/admin/class-admin.php:1630
407
  msgid "Enable dynamic remarketing audience collection"
408
  msgstr ""
409
 
410
+ #: classes/admin/class-admin.php:1646
411
  msgid "You need to choose the correct product identifier setting in order to match the product identifiers in the Google Merchant Center or your Google Ads business feed"
412
  msgstr ""
413
 
414
+ #: classes/admin/class-admin.php:1665
415
  msgid "Enable variations output"
416
  msgstr ""
417
 
418
+ #: classes/admin/class-admin.php:1673
419
  msgid "In order for this to work you need to upload your Google Merchant Center feed including product variations and the item_group_id. Disable it, if you choose only to upload the parent product for variable products."
420
  msgstr ""
421
 
422
+ #: classes/admin/class-admin.php:1688
423
  msgid "Retail"
424
  msgstr ""
425
 
426
+ #: classes/admin/class-admin.php:1698
427
  msgid "Education"
428
  msgstr ""
429
 
430
+ #: classes/admin/class-admin.php:1708
431
  msgid "Hotels and rentals"
432
  msgstr ""
433
 
434
+ #: classes/admin/class-admin.php:1718
435
  msgid "Jobs"
436
  msgstr ""
437
 
438
+ #: classes/admin/class-admin.php:1728
439
  msgid "Local deals"
440
  msgstr ""
441
 
442
+ #: classes/admin/class-admin.php:1738
443
  msgid "Real estate"
444
  msgstr ""
445
 
446
+ #: classes/admin/class-admin.php:1748
447
  msgid "Custom"
448
  msgstr ""
449
 
450
+ #: classes/admin/class-admin.php:1761
451
  msgid "ID of your Google Merchant Center account. It looks like this: 12345678"
452
  msgstr ""
453
 
454
+ #: classes/admin/class-admin.php:1778
455
  msgid "Currently the plugin automatically detects the location of the visitor for this setting. In most, if not all, cases this will work fine. Please let us know if you have a use case where you need another output:"
456
  msgstr ""
457
 
458
+ #: classes/admin/class-admin.php:1815
459
  msgid "The plugin will use the WordPress default language for this setting. If the shop uses translations, in theory we could also use the visitors locale. But, if that language is not set up in the Google Merchant Center we might run into issues. If you need more options here let us know:"
460
  msgstr ""
461
 
462
+ #: classes/admin/class-admin.php:1835
463
  msgid "post id (default)"
464
  msgstr ""
465
 
466
+ #: classes/admin/class-admin.php:1842
467
  msgid "post id with woocommerce_gpf_ prefix *"
468
  msgstr ""
469
 
470
+ #: classes/admin/class-admin.php:1850
471
  msgid "SKU"
472
  msgstr ""
473
 
474
+ #: classes/admin/class-admin.php:1855
475
  msgid "Choose a product identifier."
476
  msgstr ""
477
 
478
+ #: classes/admin/class-admin.php:1858
479
  msgid "* This is for users of the WooCommerce Google Product Feed Plugin"
480
  msgstr ""
481
 
482
+ #: classes/admin/class-admin.php:1940
483
  msgid "You have entered an invalid Google Analytics Universal property ID."
484
  msgstr ""
485
 
486
+ #: classes/admin/class-admin.php:1948
487
  msgid "You have entered an invalid Google Analytics 4 measurement ID."
488
  msgstr ""
489
 
490
+ #: classes/admin/class-admin.php:1956
491
+ msgid "You have entered an invalid Google Analytics 4 API key."
492
+ msgstr ""
493
+
494
+ #: classes/admin/class-admin.php:1964
495
  msgid "You have entered an invalid conversion ID. It only contains 8 to 10 digits."
496
  msgstr ""
497
 
498
+ #: classes/admin/class-admin.php:1972
499
+ #: classes/admin/class-admin.php:1980
500
  msgid "You have entered an invalid conversion label."
501
  msgstr ""
502
 
503
+ #: classes/admin/class-admin.php:1988
504
  msgid "You have entered an invalid merchant ID. It only contains 7 to 10 digits."
505
  msgstr ""
506
 
507
+ #: classes/admin/class-admin.php:1996
508
  msgid "You have entered an invalid Google Optimize container ID."
509
  msgstr ""
510
 
511
+ #: classes/admin/class-admin.php:2004
512
  msgid "You have entered an invalid Facebook pixel ID. It only contains 14 to 16 digits."
513
  msgstr ""
514
 
515
+ #: classes/admin/class-admin.php:2012
516
+ msgid "You have entered an invalid Facebook CAPI token."
517
+ msgstr ""
518
+
519
+ #: classes/admin/class-admin.php:2020
520
  msgid "You have entered an invalid Bing Ads UET tag ID. It only contains 7 to 9 digits."
521
  msgstr ""
522
 
523
+ #: classes/admin/class-admin.php:2028
524
  msgid "You have entered an invalid Twitter pixel ID. It only contains 5 to 7 lowercase letters and numbers."
525
  msgstr ""
526
 
527
+ #: classes/admin/class-admin.php:2036
528
  msgid "You have entered an invalid Pinterest pixel ID. It only contains 13 digits."
529
  msgstr ""
530
 
531
+ #: classes/admin/class-admin.php:2044
532
  msgid "You have entered an invalid Hotjar site ID. It only contains 7 to 9 digits."
533
  msgstr ""
534
 
535
  #. translators: %d: the amount of purchase conversions that have been measured
536
+ #: classes/admin/class-ask-for-rating.php:133
537
  msgid "Hey, I noticed that you tracked more than %d purchase conversions with the Google Ads Conversion Tracking plugin - that's awesome! Could you please do me a BIG favour and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation."
538
  msgstr ""
539
 
540
+ #: classes/admin/class-ask-for-rating.php:147
541
  msgid "Ok, you deserve it"
542
  msgstr ""
543
 
544
+ #: classes/admin/class-ask-for-rating.php:152
545
  msgid "Nope, maybe later"
546
  msgstr ""
547
 
548
+ #: classes/admin/class-ask-for-rating.php:157
549
  msgid "I already did"
550
  msgstr ""
551
 
552
+ #: classes/admin/class-launch-deal.php:106
553
  msgid "I am super happy and excited to announce our <a href=\"https://woopt.com/launch-deal-8a63336b/\" target=\"_blank\">special deal</a> for the launch of the <a href=\"https://woopt.com/\" target=\"_blank\">pro version</a> of the <b>woopt WooCommerce Pixel Manager Plugin</b> (formerly known as the <b>WooCommmerce Google Ads Conversion Tracking Plugin</b>)."
554
  msgstr ""
555
 
556
+ #: classes/admin/class-launch-deal.php:113
557
  msgid "Because you are an existing user of this plugin you are eligible to receive a generous discount if you chose to participate in the launch deal. After all, you helped to shape the plugin into what it is today. Go ahead and have a look."
558
  msgstr ""
559
 
560
+ #: classes/admin/class-launch-deal.php:126
561
  msgid "Take me to the deal!"
562
  msgstr ""
563
 
564
+ #: classes/admin/class-launch-deal.php:131
565
  msgid "Maybe later"
566
  msgstr ""
567
 
568
+ #: classes/admin/class-launch-deal.php:136
569
  msgid "Not interested. Close this message."
570
  msgstr ""
571
 
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
- === Plugin Name ===
2
  Contributors: alekv, woopt, wolfbaer
3
  Tags: woocommerce, google ads, conversion tracking, dynamic retargeting, remarketing , adwords
4
  Requires at least: 3.7
5
  Tested up to: 5.7
6
  Requires PHP: 7.2
7
- Stable tag: 1.8.28
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -103,6 +103,60 @@ You can send the link to the front page of your shop too if you think it would b
103
 
104
  == Changelog ==
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  = 1.8.28 =
107
 
108
  * New: Filter to switch Google Analytics ID output to SKU
1
+ === WooCommerce Conversion Tracking ===
2
  Contributors: alekv, woopt, wolfbaer
3
  Tags: woocommerce, google ads, conversion tracking, dynamic retargeting, remarketing , adwords
4
  Requires at least: 3.7
5
  Tested up to: 5.7
6
  Requires PHP: 7.2
7
+ Stable tag: 1.9.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
103
 
104
  == Changelog ==
105
 
106
+ = 1.9.6 =
107
+
108
+
109
+ * Tweak: Added one more tweak for LiteSpeed Cache users
110
+
111
+ * Fix: Changed reading options from database to passing options from primary instance in order to avoid options caching issues on saving.
112
+
113
+ = 1.9.5 =
114
+
115
+
116
+ * Tweak: Added dependencies to enqueued scripts
117
+ * Tweak: Improved the parent selector for the mutation observer for lazy loaded products
118
+ * Tweak: Implemented better product selector for modification observer
119
+ * Tweak: Added new selector for related products
120
+
121
+
122
+
123
+ = 1.9.4 =
124
+
125
+
126
+
127
+ * Tweak: Finalized improvement for front-end error handling
128
+ * Tweak: Added a JS modification exclusion for Autoptimize in order to prevent our script to get modified and broken
129
+ * Fix: Fixed a selector for cart items on the cart page which caused on certain custom shop templates to trigger an error
130
+
131
+ = 1.9.3 =
132
+
133
+ * Tweak: Added one more layer of safeguards if wooptpm.js can't evaluate the current productId
134
+
135
+ = 1.9.2 =
136
+
137
+ * Tweak: Added one more safeguard if wooptpm.js can't evaluate the current productId
138
+
139
+ = 1.9.1 =
140
+
141
+
142
+ * Tweak: Added some some safeguards in order to stop processing in case no productId can be evaluated
143
+ * Tweak: Removed deprecated "disable gtag insertion" feature entirely
144
+
145
+
146
+ = 1.9.0 =
147
+
148
+
149
+
150
+ * Tweak: Additional caching exclusions for SG Optimizer
151
+ * Tweak: Changed the gtag code in order to make it better testable
152
+ * Tweak: Moved some scripts to the footer
153
+ * Tweak: Improved add_to_cart trigger
154
+ * Tweak: Refactored view_item_list event entirely to be unaffected by caching mechanisms
155
+ * Tweak: Added a new view_item_list trigger with some interesting options
156
+ * Fix: Fixed front-end triggers for Google and Facebook to only fire if the pixels are enabled
157
+ * Fix: Fixed an array check if an old WP Rocket version was installed and threw a notice about a missing array index
158
+ * Fix: Output correct price if WPML Multilingual with Multi-currency is running
159
+
160
  = 1.8.28 =
161
 
162
  * New: Filter to switch Google Analytics ID output to SKU
wgact.php CHANGED
@@ -6,13 +6,13 @@
6
  * Author: woopt
7
  * Plugin URI: https://wordpress.org/plugins/woocommerce-google-adwords-conversion-tracking-tag/
8
  * Author URI: https://woopt.com
9
- * Version: 1.8.28
10
  * License: GPLv2 or later
11
  * Text Domain: woocommerce-google-adwords-conversion-tracking-tag
12
  * WC requires at least: 2.6
13
- * WC tested up to: 5.1
14
- *
15
  *
 
16
  **/
17
  // TODO export settings function
18
  // TODO add option checkbox on uninstall and ask if user wants to delete options from db
@@ -21,7 +21,9 @@
21
  use WGACT\Classes\Admin\Admin ;
22
  use WGACT\Classes\Admin\Ask_For_Rating ;
23
  use WGACT\Classes\Admin\Environment_Check ;
 
24
  use WGACT\Classes\Db_Upgrade ;
 
25
  use WGACT\Classes\Pixels\Cookie_Consent_Management ;
26
  use WGACT\Classes\Pixels\Pixel_Manager ;
27
 
@@ -130,7 +132,7 @@ if ( function_exists( 'wga_fs' ) ) {
130
  }
131
  // load the options
132
  $this->wgact_options_init();
133
- new \WGACT\Classes\Admin\Launch_Deal();
134
  if ( isset( $this->options['google']['gads']['dynamic_remarketing'] ) && $this->options['google']['gads']['dynamic_remarketing'] ) {
135
  // make sure to disable the WGDR plugin in case we use dynamic remarketing in this plugin
136
  add_filter( 'wgdr_third_party_cookie_prevention', '__return_true' );
@@ -161,7 +163,7 @@ if ( function_exists( 'wga_fs' ) ) {
161
  public function init()
162
  {
163
  // display admin views
164
- new Admin();
165
  // ask visitor for rating
166
  new Ask_For_Rating();
167
  new Environment_Check();
@@ -181,7 +183,7 @@ if ( function_exists( 'wga_fs' ) ) {
181
  $cookie_consent->setPluginPrefix( WGACT_PLUGIN_PREFIX );
182
  if ( $cookie_consent->is_cookie_prevention_active() == false ) {
183
  // inject pixels
184
- new Pixel_Manager();
185
  }
186
  }
187
 
@@ -208,7 +210,8 @@ if ( function_exists( 'wga_fs' ) ) {
208
  ];
209
  update_option( 'wooptpm_launch_deal', $wooptpm_launch_deal );
210
  // error_log('options empty, loading default');
211
- $this->options = $this->wgact_get_default_options();
 
212
  update_option( WGACT_DB_OPTIONS_NAME, $this->options );
213
  // $options = get_option(WGACT_DB_OPTIONS_NAME);
214
  // error_log(print_r($options, true));
@@ -238,100 +241,12 @@ if ( function_exists( 'wga_fs' ) ) {
238
  $this->options['facebook']['pixel_id'] = '';
239
  }
240
  // add new default options to the options db array
241
- $this->options = $this->update_with_defaults( $this->options, $this->wgact_get_default_options() );
242
  update_option( WGACT_DB_OPTIONS_NAME, $this->options );
243
  }
244
 
245
  }
246
 
247
- protected function update_with_defaults( $array_input, $array_default )
248
- {
249
- foreach ( $array_default as $key => $value ) {
250
-
251
- if ( array_key_exists( $key, $array_input ) ) {
252
- if ( is_array( $value ) ) {
253
- $array_input[$key] = $this->update_with_defaults( $array_input[$key], $value );
254
- }
255
- } else {
256
- $array_input[$key] = $value;
257
- }
258
-
259
- }
260
- return $array_input;
261
- }
262
-
263
- // get the default options
264
- private function wgact_get_default_options() : array
265
- {
266
- // default options settings
267
- return [
268
- 'google' => [
269
- 'ads' => [
270
- 'conversion_id' => '',
271
- 'conversion_label' => '',
272
- 'aw_merchant_id' => '',
273
- 'product_identifier' => 0,
274
- 'google_business_vertical' => 0,
275
- 'dynamic_remarketing' => 0,
276
- 'phone_conversion_number' => '',
277
- 'phone_conversion_label' => '',
278
- ],
279
- 'analytics' => [
280
- 'universal' => [
281
- 'property_id' => '',
282
- ],
283
- 'ga4' => [
284
- 'measurement_id' => '',
285
- ],
286
- 'eec' => 0,
287
- 'link_attribution' => 0,
288
- ],
289
- 'optimize' => [
290
- 'container_id' => '',
291
- ],
292
- 'gtag' => [
293
- 'deactivation' => 0,
294
- ],
295
- 'consent_mode' => [
296
- 'active' => 0,
297
- 'regions' => [],
298
- ],
299
- 'user_id' => 0,
300
- ],
301
- 'facebook' => [
302
- 'pixel_id' => '',
303
- 'microdata' => 0,
304
- ],
305
- 'bing' => [
306
- 'uet_tag_id' => '',
307
- ],
308
- 'twitter' => [
309
- 'pixel_id' => '',
310
- ],
311
- 'pinterest' => [
312
- 'pixel_id' => '',
313
- ],
314
- 'hotjar' => [
315
- 'site_id' => '',
316
- ],
317
- 'shop' => [
318
- 'order_total_logic' => 0,
319
- 'cookie_consent_mgmt' => [
320
- 'cookiebot' => [
321
- 'active' => 0,
322
- ],
323
- ],
324
- 'order_deduplication' => 1,
325
- ],
326
- 'general' => [
327
- 'variations_output' => 1,
328
- 'maximum_compatibility_mode' => 0,
329
- 'pro_version_demo' => 0,
330
- ],
331
- 'db_version' => WGACT_DB_VERSION,
332
- ];
333
- }
334
-
335
  // adds a link on the plugins page for the wgdr settings
336
  // ! Can't be required. Must be in the main plugin file.
337
  public function wgact_settings_link( $links )
6
  * Author: woopt
7
  * Plugin URI: https://wordpress.org/plugins/woocommerce-google-adwords-conversion-tracking-tag/
8
  * Author URI: https://woopt.com
9
+ * Version: 1.9.6
10
  * License: GPLv2 or later
11
  * Text Domain: woocommerce-google-adwords-conversion-tracking-tag
12
  * WC requires at least: 2.6
13
+ * WC tested up to: 5.2
 
14
  *
15
+ *t
16
  **/
17
  // TODO export settings function
18
  // TODO add option checkbox on uninstall and ask if user wants to delete options from db
21
  use WGACT\Classes\Admin\Admin ;
22
  use WGACT\Classes\Admin\Ask_For_Rating ;
23
  use WGACT\Classes\Admin\Environment_Check ;
24
+ use WGACT\Classes\Admin\Launch_Deal ;
25
  use WGACT\Classes\Db_Upgrade ;
26
+ use WGACT\Classes\Default_Options ;
27
  use WGACT\Classes\Pixels\Cookie_Consent_Management ;
28
  use WGACT\Classes\Pixels\Pixel_Manager ;
29
 
132
  }
133
  // load the options
134
  $this->wgact_options_init();
135
+ new Launch_Deal();
136
  if ( isset( $this->options['google']['gads']['dynamic_remarketing'] ) && $this->options['google']['gads']['dynamic_remarketing'] ) {
137
  // make sure to disable the WGDR plugin in case we use dynamic remarketing in this plugin
138
  add_filter( 'wgdr_third_party_cookie_prevention', '__return_true' );
163
  public function init()
164
  {
165
  // display admin views
166
+ new Admin( $this->options );
167
  // ask visitor for rating
168
  new Ask_For_Rating();
169
  new Environment_Check();
183
  $cookie_consent->setPluginPrefix( WGACT_PLUGIN_PREFIX );
184
  if ( $cookie_consent->is_cookie_prevention_active() == false ) {
185
  // inject pixels
186
+ new Pixel_Manager( $this->options );
187
  }
188
  }
189
 
210
  ];
211
  update_option( 'wooptpm_launch_deal', $wooptpm_launch_deal );
212
  // error_log('options empty, loading default');
213
+ // $this->options = $this->wgact_get_default_options();
214
+ $this->options = ( new Default_Options() )->get_default_options();
215
  update_option( WGACT_DB_OPTIONS_NAME, $this->options );
216
  // $options = get_option(WGACT_DB_OPTIONS_NAME);
217
  // error_log(print_r($options, true));
241
  $this->options['facebook']['pixel_id'] = '';
242
  }
243
  // add new default options to the options db array
244
+ $this->options = ( new Default_Options() )->update_with_defaults( $this->options, ( new Default_Options() )->get_default_options() );
245
  update_option( WGACT_DB_OPTIONS_NAME, $this->options );
246
  }
247
 
248
  }
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  // adds a link on the plugins page for the wgdr settings
251
  // ! Can't be required. Must be in the main plugin file.
252
  public function wgact_settings_link( $links )