PixelYourSite – Facebook Pixel (Events, WooCommerce & Easy Digital Downloads) - Version 8.2.7

Version Description

Download this release

Release Info

Developer PixelYourSite
Plugin Icon 128x128 PixelYourSite – Facebook Pixel (Events, WooCommerce & Easy Digital Downloads)
Version 8.2.7
Comparing to
See all releases

Code changes from version 8.2.6 to 8.2.7

composer.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "name": "pixelyoursite/pro",
3
- "description": "Track conversions and every action on your online store",
4
- "type": "project",
5
- "require": {
6
- "glenscott/url-normalizer": "1.4.0",
7
- "techcrunch/wp-async-task": "dev-master"
8
- },
9
- "autoload": {
10
- "classmap": [
11
- "vendor_prefix/"
12
- ]
13
- }
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
composer.lock DELETED
@@ -1,109 +0,0 @@
1
- {
2
- "_readme": [
3
- "This file locks the dependencies of your project to a known state",
4
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
- "This file is @generated automatically"
6
- ],
7
- "content-hash": "4b9ed8294249f3e1c6eda2f8628a891b",
8
- "packages": [
9
- {
10
- "name": "glenscott/url-normalizer",
11
- "version": "1.4.0",
12
- "source": {
13
- "type": "git",
14
- "url": "https://github.com/glenscott/url-normalizer.git",
15
- "reference": "b8e79d3360a1bd7182398c9956bd74d219ad1b3c"
16
- },
17
- "dist": {
18
- "type": "zip",
19
- "url": "https://api.github.com/repos/glenscott/url-normalizer/zipball/b8e79d3360a1bd7182398c9956bd74d219ad1b3c",
20
- "reference": "b8e79d3360a1bd7182398c9956bd74d219ad1b3c",
21
- "shasum": ""
22
- },
23
- "require": {
24
- "ext-mbstring": "*",
25
- "php": ">=5.3.0"
26
- },
27
- "type": "library",
28
- "autoload": {
29
- "psr-4": {
30
- "URL\\": "src/URL"
31
- }
32
- },
33
- "notification-url": "https://packagist.org/downloads/",
34
- "license": [
35
- "MIT"
36
- ],
37
- "authors": [
38
- {
39
- "name": "Glen Scott",
40
- "email": "glen@glenscott.co.uk"
41
- }
42
- ],
43
- "description": "Syntax based normalization of URL's",
44
- "time": "2015-06-11T16:06:02+00:00"
45
- },
46
- {
47
- "name": "techcrunch/wp-async-task",
48
- "version": "dev-master",
49
- "source": {
50
- "type": "git",
51
- "url": "https://github.com/techcrunch/wp-async-task.git",
52
- "reference": "9bdbbf9df4ff5179711bb58b9a2451296f6753dc"
53
- },
54
- "dist": {
55
- "type": "zip",
56
- "url": "https://api.github.com/repos/techcrunch/wp-async-task/zipball/9bdbbf9df4ff5179711bb58b9a2451296f6753dc",
57
- "reference": "9bdbbf9df4ff5179711bb58b9a2451296f6753dc",
58
- "shasum": ""
59
- },
60
- "require-dev": {
61
- "10up/wp_mock": "dev-master",
62
- "phpunit/phpunit": "*@stable"
63
- },
64
- "type": "wordpress-plugin",
65
- "autoload": {
66
- "classmap": [
67
- "wp-async-task.php"
68
- ]
69
- },
70
- "notification-url": "https://packagist.org/downloads/",
71
- "license": [
72
- "MIT"
73
- ],
74
- "authors": [
75
- {
76
- "name": "Alex Khadiwala",
77
- "role": "developer"
78
- },
79
- {
80
- "name": "Nicolas Vincent",
81
- "role": "developer"
82
- },
83
- {
84
- "name": "Eric Mann",
85
- "email": "eric.mann@10up.com",
86
- "role": "developer"
87
- },
88
- {
89
- "name": "John P. Bloch",
90
- "email": "john.bloch@10up.com",
91
- "role": "developer"
92
- }
93
- ],
94
- "description": "Run asynchronous tasks for long-running operations in WordPress",
95
- "time": "2016-03-10T17:37:13+00:00"
96
- }
97
- ],
98
- "packages-dev": [],
99
- "aliases": [],
100
- "minimum-stability": "stable",
101
- "stability-flags": {
102
- "techcrunch/wp-async-task": 20
103
- },
104
- "prefer-stable": false,
105
- "prefer-lowest": false,
106
- "platform": [],
107
- "platform-dev": [],
108
- "plugin-api-version": "1.1.0"
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dist/scripts/public.js CHANGED
@@ -744,32 +744,25 @@ if (!Array.prototype.includes) {
744
  */
745
  if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
746
 
747
- Cookiebot.onaccept = function () {
748
-
749
- if (Cookiebot.consent[options.gdpr.cookiebot_facebook_consent_category]) {
750
  Facebook.loadPixel();
751
- }
 
752
 
753
- if (Cookiebot.consent[options.gdpr.cookiebot_analytics_consent_category]) {
 
754
  Analytics.loadPixel();
755
  }
756
-
757
- if (Cookiebot.consent[options.gdpr.cookiebot_pinterest_consent_category]) {
758
- Pinterest.loadPixel();
 
759
  }
760
-
761
- if (Cookiebot.consent[options.gdpr.cookiebot_bing_consent_category]) {
762
- bing.loadPixel();
763
  }
764
-
765
- };
766
-
767
- Cookiebot.ondecline = function () {
768
- Facebook.disable();
769
- Analytics.disable();
770
- Pinterest.disable();
771
- Bing.disable();
772
- };
773
 
774
  }
775
 
@@ -891,6 +884,13 @@ if (!Array.prototype.includes) {
891
 
892
  var initialized = false;
893
 
 
 
 
 
 
 
 
894
 
895
  function fireEvent(name, allData) {
896
 
@@ -905,22 +905,22 @@ if (!Array.prototype.includes) {
905
  Utils.copyProperties(data, params);
906
 
907
  if(options.facebook.serverApiEnabled) {
908
- // fire server side event gdpr plugin installed
909
- var isApiDisabled = options.gdpr.all_disabled_by_api ||
910
- options.gdpr.facebook_disabled_by_api ||
911
- options.gdpr.cookiebot_integration_enabled ||
912
- options.gdpr.consent_magic_integration_enabled ||
913
- options.gdpr.cookie_notice_integration_enabled ||
914
- options.gdpr.cookie_law_info_integration_enabled;
915
-
916
- // Update eventID
917
- if( options.facebook.ajaxForServerEvent || allData.type !== "static" ) {
918
- allData.eventID = pys_generate_token(36);
919
- }
920
- arg.eventID = allData.eventID;
921
- // send event from server if they was bloc by gdpr or need send with delay
922
- if( options.facebook.ajaxForServerEvent || isApiDisabled || allData.delay > 0 || allData.type !== "static")
923
  {
 
 
 
 
 
 
 
 
 
924
  var json = {
925
  action: 'pys_api_event',
926
  pixel: 'facebook',
@@ -928,10 +928,15 @@ if (!Array.prototype.includes) {
928
  data:data,
929
  ids:options.facebook.pixelIds,
930
  eventID:allData.eventID,
931
- woo_order:allData.woo_order,
932
- edd_order:allData.edd_order,
933
  url:window.location.href,
934
  };
 
 
 
 
 
 
 
935
  if(allData.delay > 0) {
936
  jQuery.ajax( {
937
  type: 'POST',
@@ -970,6 +975,10 @@ if (!Array.prototype.includes) {
970
  console.log('[Facebook] ' + name, params,"eventID",allData.eventID);
971
  }
972
 
 
 
 
 
973
  fbq(actionType, name, params,arg);
974
  }
975
 
@@ -1239,8 +1248,30 @@ if (!Array.prototype.includes) {
1239
  onTime: function (event) {
1240
  this.fireEvent(event.name, event);
1241
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1242
 
1243
-
 
 
 
 
 
 
 
1244
  };
1245
 
1246
  }(options);
@@ -1593,14 +1624,7 @@ if (!Array.prototype.includes) {
1593
  window.pys.Analytics = Analytics;
1594
  window.pys.Utils = Utils;
1595
 
1596
- function getPixelBySlag(slug) {
1597
- switch (slug) {
1598
- case "facebook": return window.pys.Facebook;
1599
- case "ga": return window.pys.Analytics;
1600
- case "bing": return window.pys.Bing;
1601
- case "pinterest": return window.pys.Pinterest;
1602
- }
1603
- }
1604
 
1605
 
1606
  $(document).ready(function () {
@@ -1727,7 +1751,10 @@ if (!Array.prototype.includes) {
1727
  if (options.woo.enabled) {
1728
 
1729
  // WooCommerce AddToCart
1730
- if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")) {
 
 
 
1731
 
1732
  // Loop, any kind of "simple" product, except external
1733
  $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
@@ -2060,3 +2087,12 @@ function getBundlePriceOnSingleProduct(data) {
2060
  });
2061
  return items_sum;
2062
  }
 
 
 
 
 
 
 
 
 
744
  */
745
  if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
746
 
747
+ window.addEventListener("CookiebotOnConsentReady", function() {
748
+ if (Cookiebot.consent.marketing) {
 
749
  Facebook.loadPixel();
750
+ Bing.loadPixel();
751
+ Pinterest.loadPixel();
752
 
753
+ }
754
+ if (Cookiebot.consent.statistics) {
755
  Analytics.loadPixel();
756
  }
757
+ if (!Cookiebot.consent.marketing) {
758
+ Facebook.disable();
759
+ Pinterest.disable();
760
+ Bing.disable()
761
  }
762
+ if (!Cookiebot.consent.statistics) {
763
+ Analytics.disable();
 
764
  }
765
+ });
 
 
 
 
 
 
 
 
766
 
767
  }
768
 
884
 
885
  var initialized = false;
886
 
887
+ // fire server side event gdpr plugin installed
888
+ var isApiDisabled = options.gdpr.all_disabled_by_api ||
889
+ options.gdpr.facebook_disabled_by_api ||
890
+ options.gdpr.cookiebot_integration_enabled ||
891
+ options.gdpr.consent_magic_integration_enabled ||
892
+ options.gdpr.cookie_notice_integration_enabled ||
893
+ options.gdpr.cookie_law_info_integration_enabled;
894
 
895
  function fireEvent(name, allData) {
896
 
905
  Utils.copyProperties(data, params);
906
 
907
  if(options.facebook.serverApiEnabled) {
908
+
909
+ var isAddToCartFromJs = options.woo.hasOwnProperty("addToCartCatchMethod")
910
+ && options.woo.addToCartCatchMethod === "add_cart_js";
911
+ console.log(allData.e_id,"isAddToCartFromJs "+isAddToCartFromJs)
912
+ if(allData.name === "RemoveFromCart"
913
+ || (isAddToCartFromJs && allData.e_id === "woo_add_to_cart_on_button_click"))
 
 
 
 
 
 
 
 
 
914
  {
915
+ Facebook.updateEventId(allData.name);
916
+ allData.eventID = Facebook.getEventId(allData.name);
917
+ console.log('updateEventId')
918
+ } else if( options.facebook.ajaxForServerEvent
919
+ || isApiDisabled
920
+ || allData.delay > 0
921
+ || allData.type !== "static")
922
+ { // send event from server if they was bloc by gdpr or need send with delay
923
+ allData.eventID = pys_generate_token(36);
924
  var json = {
925
  action: 'pys_api_event',
926
  pixel: 'facebook',
928
  data:data,
929
  ids:options.facebook.pixelIds,
930
  eventID:allData.eventID,
 
 
931
  url:window.location.href,
932
  };
933
+ if(allData.hasOwnProperty('woo_order')) {
934
+ json['woo_order'] = allData.woo_order;
935
+ }
936
+ if(allData.hasOwnProperty('edd_order')) {
937
+ json['edd_order'] = allData.edd_order;
938
+ }
939
+
940
  if(allData.delay > 0) {
941
  jQuery.ajax( {
942
  type: 'POST',
975
  console.log('[Facebook] ' + name, params,"eventID",allData.eventID);
976
  }
977
 
978
+ if(allData.hasOwnProperty('eventID')) {
979
+ arg.eventID = allData.eventID;
980
+ }
981
+
982
  fbq(actionType, name, params,arg);
983
  }
984
 
1248
  onTime: function (event) {
1249
  this.fireEvent(event.name, event);
1250
  },
1251
+ initEventIdCookies: function () {
1252
+ var ids = {
1253
+ 'AddToCart':pys_generate_token(36)
1254
+ };
1255
+ Cookies.set('pys_fb_event_id', JSON.stringify(ids));
1256
+ },
1257
+ updateEventId:function(key) {
1258
+ var data = JSON.parse(Cookies.get("pys_fb_event_id"));
1259
+ if(data === undefined) {
1260
+ this.initEventIdCookies();
1261
+ } else {
1262
+ data[key] = pys_generate_token(36);
1263
+ Cookies.set('pys_fb_event_id', JSON.stringify(data) );
1264
+ }
1265
+ },
1266
 
1267
+ getEventId:function (key) {
1268
+ var data = Cookies.get("pys_fb_event_id");
1269
+ if(data === undefined) {
1270
+ this.initEventIdCookies();
1271
+ data = Cookies.get("pys_fb_event_id");
1272
+ }
1273
+ return JSON.parse(data)[key];
1274
+ },
1275
  };
1276
 
1277
  }(options);
1624
  window.pys.Analytics = Analytics;
1625
  window.pys.Utils = Utils;
1626
 
1627
+
 
 
 
 
 
 
 
1628
 
1629
 
1630
  $(document).ready(function () {
1751
  if (options.woo.enabled) {
1752
 
1753
  // WooCommerce AddToCart
1754
+ if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
1755
+ && options.woo.hasOwnProperty("addToCartCatchMethod")
1756
+ && options.woo.addToCartCatchMethod === "add_cart_js"
1757
+ ) {
1758
 
1759
  // Loop, any kind of "simple" product, except external
1760
  $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
2087
  });
2088
  return items_sum;
2089
  }
2090
+
2091
+ function getPixelBySlag(slug) {
2092
+ switch (slug) {
2093
+ case "facebook": return window.pys.Facebook;
2094
+ case "ga": return window.pys.Analytics;
2095
+ case "bing": return window.pys.Bing;
2096
+ case "pinterest": return window.pys.Pinterest;
2097
+ }
2098
+ }
facebook-pixel-master.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: PixelYourSite
5
  * Plugin URI: http://www.pixelyoursite.com/
6
  * Description: No coding <strong>Facebook Pixel, Facebook Converion API,</strong> and <strong>Google Analytics</strong> install. Track key actions with our Signal event, or configure your own events. WooCommerce and EDD fully supported, with Facebook Dynamic Ads Pixel set-up and Google Analytics Enhanced Ecommerce. Insert any custom script with our Head & Footer option. Add the <strong>Pinterest Tag</strong> with our free add-on. The PRO version adds support for the Google Ads tag plus a lot of extra stuff. Full support for <strong>ConsentMagic.com</strong>.
7
- * Version: 8.2.6
8
  * Author: PixelYourSite
9
  * Author URI: http://www.pixelyoursite.com
10
  * License: GPLv3
@@ -13,7 +13,7 @@
13
  * Tested up to: 5.8
14
  *
15
  * WC requires at least: 2.6.0
16
- * WC tested up to: 5.5
17
  *
18
  * Text Domain: pys
19
  */
4
  * Plugin Name: PixelYourSite
5
  * Plugin URI: http://www.pixelyoursite.com/
6
  * Description: No coding <strong>Facebook Pixel, Facebook Converion API,</strong> and <strong>Google Analytics</strong> install. Track key actions with our Signal event, or configure your own events. WooCommerce and EDD fully supported, with Facebook Dynamic Ads Pixel set-up and Google Analytics Enhanced Ecommerce. Insert any custom script with our Head & Footer option. Add the <strong>Pinterest Tag</strong> with our free add-on. The PRO version adds support for the Google Ads tag plus a lot of extra stuff. Full support for <strong>ConsentMagic.com</strong>.
7
+ * Version: 8.2.7
8
  * Author: PixelYourSite
9
  * Author URI: http://www.pixelyoursite.com
10
  * License: GPLv3
13
  * Tested up to: 5.8
14
  *
15
  * WC requires at least: 2.6.0
16
+ * WC tested up to: 5.6
17
  *
18
  * Text Domain: pys
19
  */
includes/class-events-manager-ajax_hook.php ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace PixelYourSite;
3
+
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit; // Exit if accessed directly.
6
+ }
7
+
8
+
9
+ class AjaxHookEventManager {
10
+
11
+ public static $pendingEvents = array();
12
+ public static $DIV_ID_FOR_AJAX_EVENTS = "pys_ajax_events";
13
+ private static $_instance;
14
+
15
+ public static function instance() {
16
+
17
+ if ( is_null( self::$_instance ) ) {
18
+ self::$_instance = new self();
19
+ }
20
+
21
+ return self::$_instance;
22
+
23
+ }
24
+
25
+ public function __construct() {
26
+
27
+ }
28
+
29
+ public function addHooks() {
30
+
31
+
32
+ if(EventsWoo()->isEnabled()) {
33
+
34
+ // use for fb server only because ajax request cause bugs in woo
35
+ if(Facebook()->enabled()
36
+ && Facebook()->isServerApiEnabled()
37
+ && PYS()->getOption( 'woo_remove_from_cart_enabled')
38
+ ) {
39
+ add_action( 'woocommerce_remove_cart_item', array($this, 'trackRemoveFromCartEvent'), 10, 2);
40
+ }
41
+
42
+ if ( isEventEnabled('woo_add_to_cart_enabled')
43
+ && PYS()->getOption('woo_add_to_cart_on_button_click')
44
+ )
45
+ {
46
+
47
+ if(PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_hook") {
48
+ add_action( 'wp_footer', array( __CLASS__, 'addDivForAjaxPixelEvent') );
49
+ add_action( 'woocommerce_add_to_cart',array(__CLASS__, 'trackWooAddToCartEvent'),40, 6);
50
+ } else {
51
+
52
+ if(Facebook()->enabled() && Facebook()->isServerApiEnabled()) {
53
+ add_action( 'woocommerce_add_to_cart',array(__CLASS__, 'trackWooFacebookAddToCartEvent'),40, 6);
54
+ }
55
+
56
+ }
57
+
58
+ }
59
+ }
60
+
61
+
62
+
63
+ }
64
+
65
+ /**
66
+ * @param String $cart_item_key
67
+ * @param \WC_Cart $cart
68
+ */
69
+
70
+ function trackRemoveFromCartEvent ($cart_item_key,$cart) {
71
+ $eventId = 'woo_remove_from_cart';
72
+
73
+ $url = $_SERVER['HTTP_HOST'].strtok($_SERVER["REQUEST_URI"], '?');
74
+ $postId = url_to_postid($url);
75
+ $cart_id = wc_get_page_id( 'cart' );
76
+ $item = $cart->get_cart_item($cart_item_key);
77
+ $is_ajax_request = wp_doing_ajax();
78
+ if( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'yith_wacp_add_item_cart') {
79
+ $is_ajax_request = true;
80
+ }
81
+
82
+ if(isset($item['variation_id'])) {
83
+ $product_id = $item['variation_id'];
84
+ } else {
85
+ $product_id = $item['product_id'];
86
+ }
87
+
88
+
89
+ if( $cart_id==$postId) {
90
+ PYS()->getLog()->debug('trackRemoveFromCartEvent send fb server with out browser event');
91
+ $event = new SingleEvent("woo_remove_from_cart",EventTypes::$STATIC);
92
+ $eventData = Facebook()->getEventData($eventId,$item);
93
+ $event->addParams($eventData['data']);
94
+ $event->addParams(getStandardParams());
95
+ if(isset($_COOKIE['pys_landing_page'])){
96
+ $event->addParams(['landing_page'=>$_COOKIE['pys_landing_page']]);
97
+ }
98
+
99
+ unset($eventData['data']);
100
+ $event->addPayload($eventData);
101
+
102
+ if(isset($_COOKIE["pys_fb_event_id"])) {
103
+ $eventID = json_decode(stripslashes($_COOKIE["pys_fb_event_id"]))->RemoveFromCart;
104
+ } else {
105
+ $eventID = (new EventIdGenerator())->guidv4();
106
+ }
107
+
108
+ $data = $event->getData();
109
+
110
+ $data = EventsManager::filterEventParams($data,"woo",[
111
+ 'event_id'=>$event->getId(),
112
+ 'pixel'=>Facebook()->getSlug(),
113
+ 'product_id'=>$product_id
114
+ ]);
115
+
116
+ $serverEvent = FacebookServer()->createEvent($eventID,$data['name'],$data['params']);
117
+ $ids = (array)$event->payload["pixelIds"];
118
+
119
+ if($is_ajax_request) {
120
+ FacebookServer()->sendEvent($ids,array($serverEvent));
121
+ } else {
122
+ FacebookServer()->addAsyncEvents(array(array("pixelIds" => $ids, "event" => $serverEvent )));
123
+ }
124
+ }
125
+ }
126
+
127
+ static function trackWooFacebookAddToCartEvent($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
128
+ if(isset($cart_item_data['woosb_parent_id'])) return; // fix for WPC Product Bundles for WooCommerce (Premium) product
129
+
130
+ $is_ajax_request = wp_doing_ajax();
131
+ if( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'yith_wacp_add_item_cart') {
132
+ $is_ajax_request = true;
133
+ }
134
+ PYS()->getLog()->debug('trackWooFacebookAddToCartEvent is_ajax_request '.$is_ajax_request);
135
+ if( !empty($variation_id)
136
+ && $variation_id > 0
137
+ && ( !Facebook()->getOption( 'woo_variable_as_simple' )
138
+ || !Facebook\Helpers\isDefaultWooContentIdLogic() )
139
+ ) {
140
+ $_product_id = $variation_id;
141
+ } else {
142
+ $_product_id = $product_id;
143
+ }
144
+
145
+ $event = EventsWoo()->getEvent("woo_add_to_cart_on_button_click");
146
+ if(is_array($event) && count($event) > 0) {
147
+ $event = $event[0];
148
+ }
149
+ $event->args = ['productId' => $_product_id,'quantity' => $quantity];
150
+ $isSuccess = Facebook()->addParamsToEvent( $event );
151
+ if ( !$isSuccess ) {
152
+ return; // event is disabled or not supported for the pixel
153
+ }
154
+
155
+ // prepare event data
156
+ if(isset($_COOKIE['pys_landing_page']))
157
+ $event->addParams(['landing_page'=>$_COOKIE['pys_landing_page']]);
158
+ $eventData = $event->getData();
159
+ $eventData = EventsManager::filterEventParams($eventData,"woo",[
160
+ 'event_id'=>$event->getId(),
161
+ 'pixel'=>Facebook()->getSlug(),
162
+ 'product_id'=>$product_id
163
+ ]);
164
+
165
+ if(isset($_COOKIE["pys_fb_event_id"])) {
166
+ $eventID = json_decode(stripslashes($_COOKIE["pys_fb_event_id"]))->AddToCart;
167
+ } else {
168
+ return; // not send if event id is empty
169
+ }
170
+
171
+ $ids = (array)$event->payload["pixelIds"];
172
+ $serverEvent = FacebookServer()->createEvent($eventID,$eventData['name'],$eventData['params']);
173
+
174
+ if($is_ajax_request) {
175
+ FacebookServer()->sendEvent($ids,array($serverEvent));
176
+ } else {
177
+ FacebookServer()->addAsyncEvents(array(array("pixelIds" => $ids, "event" => $serverEvent )));
178
+ }
179
+ }
180
+
181
+
182
+ static function trackWooAddToCartEvent($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
183
+
184
+ if(isset($cart_item_data['woosb_parent_id'])) return; // fix for WPC Product Bundles for WooCommerce (Premium) product
185
+
186
+ $is_ajax_request = wp_doing_ajax();
187
+ if( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'yith_wacp_add_item_cart') {
188
+ $is_ajax_request = true;
189
+ }
190
+ $standardParams = getStandardParams();
191
+
192
+ PYS()->getLog()->debug('trackWooAddToCartEvent is_ajax_request '.$is_ajax_request);
193
+
194
+ foreach ( PYS()->getRegisteredPixels() as $pixel ) {
195
+
196
+ if( !empty($variation_id)
197
+ && $variation_id > 0
198
+ && ( !$pixel->getOption( 'woo_variable_as_simple' )
199
+ || ( $pixel->getSlug() == "facebook"
200
+ && !Facebook\Helpers\isDefaultWooContentIdLogic()
201
+ )
202
+ )
203
+ ) {
204
+ $_product_id = $variation_id;
205
+ } else {
206
+ $_product_id = $product_id;
207
+ }
208
+
209
+
210
+ $event = new SingleEvent('woo_add_to_cart_on_button_click',EventTypes::$STATIC);
211
+ $event->args = ['productId' => $_product_id,'quantity' => $quantity];
212
+ $isSuccess = $pixel->addParamsToEvent( $event );
213
+ if ( !$isSuccess ) {
214
+ continue; // event is disabled or not supported for the pixel
215
+ }
216
+
217
+ if(count($event->params) == 0) {
218
+ // add product params
219
+ // use for not update bing and pinterest, need remove in next updates
220
+ $eventData = $pixel->getEventData('woo_add_to_cart_on_button_click',$product_id);
221
+ if($eventData) {
222
+ $event->addParams($eventData['params']);
223
+ unset($eventData['params']);
224
+ $event->addPayload($eventData);
225
+ }
226
+ }
227
+
228
+
229
+
230
+ // add standard params
231
+ if($pixel->getSlug() != "ga" || $pixel->isUse4Version()) {
232
+ $event->addParams($standardParams);
233
+ }
234
+
235
+ // prepare event data
236
+ $eventData = $event->getData();
237
+ $eventData = EventsManager::filterEventParams($eventData,"woo",[
238
+ 'event_id'=>$event->getId(),
239
+ 'pixel'=>$pixel->getSlug(),
240
+ 'product_id'=>$product_id
241
+ ]);
242
+
243
+ AjaxHookEventManager::$pendingEvents["woo_add_to_cart_on_button_click"][ $pixel->getSlug() ] = $eventData;
244
+
245
+ if($pixel->getSlug() == "facebook" && Facebook()->isServerApiEnabled()) {
246
+ $name = $eventData['name'];
247
+ $data = $eventData['params'];
248
+ $eventID = isset($eventData['eventID']) ? $eventData['eventID'] : false;
249
+ $ids = (array)$event->payload["pixelIds"];
250
+ $event = FacebookServer()->createEvent($eventID,$name,$data);
251
+
252
+ if($is_ajax_request) {
253
+ FacebookServer()->sendEvent($ids,array($event));
254
+ } else {
255
+ FacebookServer()->addAsyncEvents(array(array("pixelIds" => $ids, "event" => $event )));
256
+ }
257
+ }
258
+ }
259
+
260
+ if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
261
+ add_filter('wc_add_to_cart_message_html',array(__CLASS__, 'addPixelCodeToAddToCarMessage'),90,3);
262
+ } elseif ($is_ajax_request) {
263
+ add_filter('woocommerce_add_to_cart_fragments', array(__CLASS__, 'addPixelCodeToAddToCartFragment'));
264
+ } else {
265
+ add_action("wp_footer",array(__CLASS__, 'printEvent'));
266
+ // self::printEvent();
267
+ }
268
+
269
+ }
270
+
271
+ public static function printEvent() {
272
+ $pixelsEventData = self::$pendingEvents["woo_add_to_cart_on_button_click"];
273
+ if( !is_null($pixelsEventData) ) {
274
+ PYS()->getLog()->debug('trackWooAddToCartEvent printEvent is footer');
275
+ echo "<div id='pys_late_event' style='display:none' dir='".json_encode($pixelsEventData)."'></div>";
276
+ unset(self::$pendingEvents["woo_add_to_cart_on_button_click"]);
277
+ }
278
+ }
279
+
280
+ public static function addDivForAjaxPixelEvent(){
281
+
282
+ echo self::getDivForAjaxPixelEvent();
283
+ ?>
284
+ <script>
285
+ var node = document.getElementsByClassName('woocommerce-message')[0];
286
+ if(node && document.getElementById('pys_late_event')) {
287
+ var messageText = node.textContent.trim();
288
+ if(!messageText) {
289
+ node.style.display = 'none';
290
+ }
291
+ }
292
+ </script>
293
+ <?php
294
+ }
295
+
296
+ public static function getDivForAjaxPixelEvent($content = ''){
297
+ return "<div id='".self::$DIV_ID_FOR_AJAX_EVENTS."'>" . $content . "</div>";
298
+ }
299
+
300
+ public static function addPixelCodeToAddToCarMessage($message, $products, $show_qty) {
301
+ $pixelsEventData = self::$pendingEvents["woo_add_to_cart_on_button_click"];
302
+ if( !is_null($pixelsEventData) ){
303
+ $message .= "<div id='pys_late_event' dir='".json_encode($pixelsEventData)."'></div>";
304
+ unset(self::$pendingEvents["woo_add_to_cart_on_button_click"]);
305
+ }
306
+ return $message;
307
+ }
308
+
309
+ public static function addPixelCodeToAddToCartFragment($fragments) {
310
+
311
+
312
+ $pixelsEventData = self::$pendingEvents["woo_add_to_cart_on_button_click"];
313
+ if( !is_null($pixelsEventData) ){
314
+ PYS()->getLog()->debug('addPixelCodeToAddToCartFragment send data with fragment');
315
+ $pixel_code = self::generatePixelCode($pixelsEventData);
316
+ $fragments['#'.self::$DIV_ID_FOR_AJAX_EVENTS] =
317
+ self::getDivForAjaxPixelEvent($pixel_code);
318
+ unset(self::$pendingEvents["woo_add_to_cart_on_button_click"]);
319
+ }
320
+
321
+ return $fragments;
322
+ }
323
+
324
+ public static function generatePixelCode($pixelsEventData){
325
+
326
+ ob_start();
327
+ //$cartHashKey = apply_filters( 'woocommerce_cart_hash_key', 'wc_cart_hash_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) . get_template() ) );
328
+ ?>
329
+ <script>
330
+ function pys_getCookie(name) {
331
+ var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
332
+ return v ? v[2] : null;
333
+ }
334
+ function pys_setCookie(name, value, days) {
335
+ var d = new Date;
336
+ d.setTime(d.getTime() + 24*60*60*1000*days);
337
+ document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
338
+ }
339
+ var name = 'pysAddToCartFragmentId';
340
+ var cartHash = "<?=WC()->cart->get_cart_hash()?>";
341
+
342
+ if(pys_getCookie(name) != cartHash) { // prevent re send event if user update page
343
+ <?php foreach ($pixelsEventData as $slug => $eventData) : ?>
344
+
345
+ var pixel = getPixelBySlag('<?=$slug?>');
346
+ var event = <?=json_encode($eventData)?>;
347
+ pixel.fireEvent(event.name, event);
348
+
349
+ <?php endforeach; ?>
350
+ pys_setCookie(name,cartHash,90)
351
+ }
352
+ </script>
353
+ <?php
354
+
355
+ $code = ob_get_clean();
356
+ return $code;
357
+ }
358
+
359
+
360
+
361
+
362
+ }
includes/class-events-manager.php CHANGED
@@ -179,7 +179,10 @@ class EventsManager {
179
 
180
  if(EventsWoo()->isEnabled()){
181
  // AddToCart on button and Affiliate
182
- if ( isEventEnabled( 'woo_add_to_cart_enabled') && PYS()->getOption( 'woo_add_to_cart_on_button_click' )) {
 
 
 
183
  add_action( 'woocommerce_after_shop_loop_item', array( $this, 'setupWooLoopProductData' ) );
184
  add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'setupWooSingleProductData' ) );
185
  add_filter( 'woocommerce_blocks_product_grid_item_html', array( $this, 'setupWooBlocksProductData' ), 10, 3 );
@@ -275,7 +278,7 @@ class EventsManager {
275
  $eventId = $event->getId();
276
  }
277
  $this->triggerEvents[ $eventId ][ $pixel->getSlug() ] = $eventData;
278
- $this->triggerEventTypes[ $eventData['trigger_type'] ][ $eventId ][] = $eventData['trigger_value'];
279
  }
280
 
281
  /**
@@ -341,7 +344,7 @@ class EventsManager {
341
 
342
  }
343
 
344
- function filterEventParams($data,$slug)
345
  {
346
 
347
  if(!PYS()->getOption('enable_content_name_param')) {
@@ -433,19 +436,27 @@ class EventsManager {
433
 
434
  foreach ( PYS()->getRegisteredPixels() as $pixel ) {
435
  /** @var Pixel|Settings $pixel */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
 
437
- $eventData = $pixel->getEventData( 'woo_add_to_cart_on_button_click', $product_id );
438
-
439
- if ( false === $eventData ) {
440
- continue; // event is disabled or not supported for the pixel
441
- }
442
 
443
- if(isset($eventData['params']))
444
- $eventData['params'] = sanitizeParams($eventData['params']);
445
- else $eventData['params'] = sanitizeParams($eventData['data']);
446
  $params[$pixel->getSlug()] = $eventData;
447
-
448
-
449
  }
450
 
451
  if ( empty( $params ) ) {
@@ -501,20 +512,30 @@ class EventsManager {
501
  }
502
 
503
  $params = array();
504
-
505
  foreach ( $product_ids as $product_id ) {
506
  foreach ( PYS()->getRegisteredPixels() as $pixel ) {
507
  /** @var Pixel|Settings $pixel */
508
 
509
- $eventData = $pixel->getEventData( 'woo_add_to_cart_on_button_click', $product_id );
510
-
511
- if ( false === $eventData ) {
512
- continue; // event is disabled or not supported for the pixel
513
- }
 
 
 
 
 
 
 
 
 
 
514
 
515
- if(isset($eventData['params']))
516
- $eventData['params'] = sanitizeParams($eventData['params']);
517
- else $eventData['params'] = sanitizeParams($eventData['data']);
518
 
519
  $params[ $product_id ][ $pixel->getSlug() ] = $eventData;
520
 
179
 
180
  if(EventsWoo()->isEnabled()){
181
  // AddToCart on button and Affiliate
182
+ if ( PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_js"
183
+ && isEventEnabled( 'woo_add_to_cart_enabled')
184
+ && PYS()->getOption( 'woo_add_to_cart_on_button_click' )
185
+ ) {
186
  add_action( 'woocommerce_after_shop_loop_item', array( $this, 'setupWooLoopProductData' ) );
187
  add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'setupWooSingleProductData' ) );
188
  add_filter( 'woocommerce_blocks_product_grid_item_html', array( $this, 'setupWooBlocksProductData' ), 10, 3 );
278
  $eventId = $event->getId();
279
  }
280
  $this->triggerEvents[ $eventId ][ $pixel->getSlug() ] = $eventData;
281
+ $this->triggerEventTypes[ $eventData['trigger_type'] ][ $eventId ] = $eventData['trigger_value'];
282
  }
283
 
284
  /**
344
 
345
  }
346
 
347
+ static function filterEventParams($data,$slug)
348
  {
349
 
350
  if(!PYS()->getOption('enable_content_name_param')) {
436
 
437
  foreach ( PYS()->getRegisteredPixels() as $pixel ) {
438
  /** @var Pixel|Settings $pixel */
439
+ $event = new SingleEvent('woo_add_to_cart_on_button_click',EventTypes::$STATIC);
440
+ $event->args = ['productId' => $product_id,'quantity' => 1];
441
+ $isSuccess = $pixel->addParamsToEvent( $event );
442
+ if ( !$isSuccess ) {
443
+ continue; // event is disabled or not supported for the pixel
444
+ }
445
+ if(count($event->params) == 0) {
446
+ // add product params
447
+ // use for not update bing and pinterest, need remove in next updates
448
+ $eventData = $pixel->getEventData( 'woo_add_to_cart_on_button_click', $product_id );
449
+ if ( false === $eventData ) {
450
+ continue; // event is disabled or not supported for the pixel
451
+ }
452
+ $event->addParams($eventData['params']);
453
+ }
454
 
455
+ // prepare event data
456
+ $eventData = $event->getData();
457
+ $eventData = EventsManager::filterEventParams($eventData,"woo");
 
 
458
 
 
 
 
459
  $params[$pixel->getSlug()] = $eventData;
 
 
460
  }
461
 
462
  if ( empty( $params ) ) {
512
  }
513
 
514
  $params = array();
515
+ $eventType = 'woo_add_to_cart_on_button_click';
516
  foreach ( $product_ids as $product_id ) {
517
  foreach ( PYS()->getRegisteredPixels() as $pixel ) {
518
  /** @var Pixel|Settings $pixel */
519
 
520
+ $event = new SingleEvent($eventType,EventTypes::$STATIC);
521
+ $event->args = ['productId' => $product_id,'quantity' => 1];
522
+ $isSuccess = $pixel->addParamsToEvent( $event );
523
+ if ( !$isSuccess ) {
524
+ continue; // event is disabled or not supported for the pixel
525
+ }
526
+ if(count($event->params) == 0) {
527
+ // add product params
528
+ // use for not update bing and pinterest, need remove in next updates
529
+ $eventData = $pixel->getEventData( $eventType, $product_id );
530
+ if ( false === $eventData ) {
531
+ continue; // event is disabled or not supported for the pixel
532
+ }
533
+ $event->addParams($eventData['params']);
534
+ }
535
 
536
+ // prepare event data
537
+ $eventData = $event->getData();
538
+ $eventData = EventsManager::filterEventParams($eventData,"woo");
539
 
540
  $params[ $product_id ][ $pixel->getSlug() ] = $eventData;
541
 
includes/class-fixed-notices.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace PixelYourSite;
3
+
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit; // Exit if accessed directly.
6
+ }
7
+
8
+
9
+ class NoticesFixed {
10
+
11
+ private static $_instance;
12
+ private $dismissedKey = "pys_free_fixed_dismissed_notices";
13
+
14
+ public static function instance() {
15
+
16
+ if ( is_null( self::$_instance ) ) {
17
+ self::$_instance = new self();
18
+ }
19
+
20
+ return self::$_instance;
21
+
22
+ }
23
+
24
+ public function __construct() {
25
+ add_action( 'init', [$this,'init'] );
26
+ }
27
+
28
+ function init() {
29
+ if ( ! current_user_can( 'manage_pys' ) ) {
30
+ return;
31
+ }
32
+
33
+ add_action( 'admin_notices', [$this,'showNotices'] );
34
+ add_action( 'wp_ajax_pys_fixed_notice_dismiss', [$this,'catchOnCloseNotice'] );
35
+
36
+ }
37
+
38
+ function showNotices() {
39
+
40
+ require_once PYS_FREE_PATH . '/notices/fixed.php';
41
+ $user_id = get_current_user_id();
42
+
43
+ $this->isNeedToShow(adminGetFixedNotices(),(array)get_user_meta( $user_id, $this->dismissedKey,true ));
44
+ }
45
+
46
+
47
+ function catchOnCloseNotice() {
48
+
49
+ if ( empty( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'pys_fixed_notice_dismiss' ) ) {
50
+ return;
51
+ }
52
+
53
+ if ( empty( $_REQUEST['user_id'] ) || empty( $_REQUEST['addon_slug'] ) || empty( $_REQUEST['meta_key'] ) ) {
54
+ return;
55
+ }
56
+ $userId = sanitize_text_field( $_REQUEST['user_id'] );
57
+ $dismissedSlugs = (array)get_user_meta( $userId, $this->dismissedKey,true);
58
+ $dismissedSlugs[] = sanitize_text_field( $_REQUEST['meta_key'] );
59
+
60
+ // save dismissed notice
61
+ update_user_meta($userId, $this->dismissedKey, $dismissedSlugs );
62
+ }
63
+
64
+ private function renderNotice($notice) {
65
+
66
+ if ( ! current_user_can( 'manage_pys' ) ) {
67
+ return;
68
+ }
69
+
70
+ if ( ! $notice ) {
71
+ return;
72
+ }
73
+
74
+ $user_id = get_current_user_id();
75
+
76
+ ?>
77
+ <div class="notice notice-info is-dismissible pys-fixed-notice" data-slug="<?=$notice['slug']?>">
78
+ <p><?php echo $notice['message']; ?></p>
79
+ </div>
80
+ <script type='application/javascript'>
81
+ jQuery(document).on('click', '.pys-fixed-notice .notice-dismiss', function () {
82
+ jQuery.ajax({
83
+ url: ajaxurl,
84
+ data: {
85
+ action: 'pys_fixed_notice_dismiss',
86
+ nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_fixed_notice_dismiss' ) ); ?>',
87
+ user_id: '<?php esc_attr_e( $user_id ); ?>',
88
+ addon_slug: 'free',
89
+ meta_key: jQuery(this).parents('.pys-fixed-notice').data('slug')
90
+ }
91
+ });
92
+ });
93
+ </script>
94
+ <?php
95
+ }
96
+
97
+ private function isNeedToShow($notices,$showedNoticesSlug) {
98
+ $activePlugins = [];
99
+
100
+ if(isWooCommerceActive()) {
101
+ $activePlugins[]='woo';
102
+ }
103
+ if(isWcfActive()) {
104
+ $activePlugins[]='wcf';
105
+ }
106
+ if(isEddActive()) {
107
+ $activePlugins[]='edd';
108
+ }
109
+ foreach ($notices as $notice) {
110
+ // check is notice has some plugin dependencies
111
+ if( count($notice['plugins']) == 0
112
+ || (count(array_intersect($notice['plugins'], $activePlugins)) == count($activePlugins)
113
+ && count($notice['plugins']) == count($activePlugins))
114
+ ) {
115
+
116
+ // check is this notice was showed
117
+ if(!in_array($notice['slug'],$showedNoticesSlug)) {
118
+ $this->renderNotice($notice);
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ }
125
+
126
+ /**
127
+ * @return NoticesFixed
128
+ */
129
+ function NoticesFixed() {
130
+ return NoticesFixed::instance();
131
+ }
132
+
133
+ NoticesFixed();
includes/class-pys.php CHANGED
@@ -23,6 +23,11 @@ final class PYS extends Settings implements Plugin {
23
  private $registeredPlugins = array();
24
 
25
  private $adminPagesSlugs = array();
 
 
 
 
 
26
 
27
  public static function instance() {
28
 
@@ -84,6 +89,9 @@ final class PYS extends Settings implements Plugin {
84
  * Restore settings after COG plugin
85
  * */
86
  add_action( 'deactivate_pixel-cost-of-goods/pixel-cost-of-goods.php',array($this,"restoreSettingsAfterCog"));
 
 
 
87
  }
88
 
89
  public function init() {
@@ -121,6 +129,8 @@ final class PYS extends Settings implements Plugin {
121
  add_filter( 'facebook_for_woocommerce_integration_pixel_enabled', '__return_false' );
122
  }
123
 
 
 
124
  }
125
 
126
  /**
@@ -618,6 +628,10 @@ final class PYS extends Settings implements Plugin {
618
 
619
  $this->updateOptions($params);
620
  }
 
 
 
 
621
  }
622
 
623
  /**
23
  private $registeredPlugins = array();
24
 
25
  private $adminPagesSlugs = array();
26
+
27
+ /**
28
+ * @var PYS_Logger
29
+ */
30
+ private $logger;
31
 
32
  public static function instance() {
33
 
89
  * Restore settings after COG plugin
90
  * */
91
  add_action( 'deactivate_pixel-cost-of-goods/pixel-cost-of-goods.php',array($this,"restoreSettingsAfterCog"));
92
+
93
+ $this->logger = new PYS_Logger();
94
+
95
  }
96
 
97
  public function init() {
129
  add_filter( 'facebook_for_woocommerce_integration_pixel_enabled', '__return_false' );
130
  }
131
 
132
+ $this->logger->init();
133
+ AjaxHookEventManager::instance()->addHooks();
134
  }
135
 
136
  /**
628
 
629
  $this->updateOptions($params);
630
  }
631
+
632
+ public function getLog() {
633
+ return $this->logger;
634
+ }
635
  }
636
 
637
  /**
includes/events/class-event-single.php CHANGED
@@ -44,6 +44,7 @@ class SingleEvent extends PYSEvent{
44
  function getData() {
45
  $data = $this->payload;
46
  $data['params'] = sanitizeParams($this->params);
 
47
 
48
  $data['delay'] = isset( $this->payload['delay'] ) ? $this->payload['delay'] : 0;
49
  $data['ids'] = isset( $this->payload['ids'] ) ? $this->payload['ids'] : array();
44
  function getData() {
45
  $data = $this->payload;
46
  $data['params'] = sanitizeParams($this->params);
47
+ $data['e_id'] = $this->getId();
48
 
49
  $data['delay'] = isset( $this->payload['delay'] ) ? $this->payload['delay'] : 0;
50
  $data['ids'] = isset( $this->payload['ids'] ) ? $this->payload['ids'] : array();
includes/events/class-events-woo.php CHANGED
@@ -94,7 +94,8 @@ class EventsWoo extends EventsFactory {
94
  'singleProductId' => isWooCommerceActive() && is_singular( 'product' ) ? $post->ID : null,
95
  'removeFromCartSelector' => isWooCommerceVersionGte( '3.0.0' )
96
  ? 'form.woocommerce-cart-form .remove'
97
- : '.cart .product-remove .remove'
 
98
  );
99
 
100
  return $data;
@@ -110,7 +111,9 @@ class EventsWoo extends EventsFactory {
110
  {
111
  switch ($event) {
112
  case 'woo_add_to_cart_on_button_click': {
113
- return PYS()->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' );
 
 
114
  }
115
 
116
 
94
  'singleProductId' => isWooCommerceActive() && is_singular( 'product' ) ? $post->ID : null,
95
  'removeFromCartSelector' => isWooCommerceVersionGte( '3.0.0' )
96
  ? 'form.woocommerce-cart-form .remove'
97
+ : '.cart .product-remove .remove',
98
+ 'addToCartCatchMethod' => PYS()->getOption('woo_add_to_cart_catch_method')
99
  );
100
 
101
  return $data;
111
  {
112
  switch ($event) {
113
  case 'woo_add_to_cart_on_button_click': {
114
+ return PYS()->getOption( 'woo_add_to_cart_enabled' )
115
+ && PYS()->getOption( 'woo_add_to_cart_on_button_click' )
116
+ && PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_js"; // or use in hook
117
  }
118
 
119
 
includes/functions-woo.php CHANGED
@@ -39,6 +39,14 @@ function getWooProductPriceToDisplay( $product_id, $qty = 1 ) {
39
  return 0;
40
  }
41
 
 
 
 
 
 
 
 
 
42
  if ( isWooCommerceVersionGte( '2.7' ) ) {
43
 
44
  return (float) wc_get_price_to_display( $product, array( 'qty' => $qty ) );
39
  return 0;
40
  }
41
 
42
+ // for Woo Discount Rules
43
+ if(method_exists('\Wdr\App\Controllers\ManageDiscount','calculateInitialAndDiscountedPrice')) {
44
+ $salePrice = \Wdr\App\Controllers\ManageDiscount::calculateInitialAndDiscountedPrice($product,$qty);
45
+ if(is_array($salePrice) && isset($salePrice['discounted_price'])) {
46
+ return $salePrice['discounted_price'];
47
+ }
48
+ }
49
+
50
  if ( isWooCommerceVersionGte( '2.7' ) ) {
51
 
52
  return (float) wc_get_price_to_display( $product, array( 'qty' => $qty ) );
includes/logger/class-pys-logger.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PixelYourSite;
4
+ defined('ABSPATH') || exit;
5
+
6
+ /**
7
+ * PYS_Logger class.
8
+ *
9
+ */
10
+ class PYS_Logger
11
+ {
12
+
13
+ protected $isEnabled = false;
14
+ /**
15
+ * Stores open file handles.
16
+ */
17
+ protected $handle = null;
18
+
19
+ public function __construct( ) {
20
+
21
+ }
22
+
23
+ public function init() {
24
+ $this->isEnabled = PYS()->getOption('logs_enable');
25
+ }
26
+
27
+ /**
28
+ * Destructor.
29
+ *
30
+ * Cleans up open file handles.
31
+ */
32
+ public function __destruct() {
33
+ if ( is_resource( $this->handle ) ) {
34
+ fclose( $this->handle ); // @codingStandardsIgnoreLine.
35
+ }
36
+ }
37
+
38
+ public function debug($message,$args = null) {
39
+ $this->log('debug',$message,$args);
40
+ }
41
+
42
+ public function error($message,$args = null) {
43
+ $this->log('error',$message,$args);
44
+ }
45
+
46
+ private function log($level,$message,$args = null) {
47
+ if(!$this->isEnabled) return;
48
+ if($args) {
49
+ $message .= " \nArgs: ".print_r($args,true);
50
+ }
51
+ $this->handle(time(),$level,$message,[]);
52
+ }
53
+
54
+ /**
55
+ * Handle a log entry.
56
+ *
57
+ * @param int $timestamp Log timestamp.
58
+ * @param string $level emergency|alert|critical|error|warning|notice|info|debug.
59
+ * @param string $message Log message.
60
+ * @param array $context {
61
+ * Additional information for log handlers.
62
+ * }
63
+ *
64
+ * @return bool False if value was not handled and true if value was handled.
65
+ */
66
+ private function handle( $timestamp, $level, $message, $context ) {
67
+
68
+ $time_string = date( 'c', $timestamp );
69
+ $entry = "{$time_string} {$level} {$message}";
70
+
71
+ return $this->add( $entry );
72
+ }
73
+
74
+ /**
75
+ * Open log file for writing.
76
+ *
77
+ * @param string $mode Optional. File mode. Default 'a'.
78
+ * @return bool Success.
79
+ */
80
+ protected function open( $mode = 'a' ) {
81
+ if ( $this->is_open() ) {
82
+ return true;
83
+ }
84
+
85
+ $file = self::get_log_file_path( );
86
+
87
+ if ( $file ) {
88
+ if ( ! file_exists( $file ) ) {
89
+ $temphandle = @fopen( $file, 'w+' ); // @codingStandardsIgnoreLine.
90
+ if ( is_resource( $temphandle ) ) {
91
+ @fclose( $temphandle ); // @codingStandardsIgnoreLine.
92
+
93
+ @chmod( $file, FS_CHMOD_FILE ); // @codingStandardsIgnoreLine.
94
+ }
95
+ }
96
+
97
+ $resource = @fopen( $file, $mode ); // @codingStandardsIgnoreLine.
98
+
99
+ if ( $resource ) {
100
+ $this->handle = $resource;
101
+ return true;
102
+ }
103
+ }
104
+
105
+ return false;
106
+ }
107
+
108
+ /**
109
+ * Get a log file path.
110
+ *
111
+ * @return string The log file path or false if path cannot be determined.
112
+ */
113
+ public static function get_log_file_path( ) {
114
+ return trailingslashit( PYS_FREE_PATH ).'logs/' . self::get_log_file_name( );
115
+ }
116
+ public static function get_log_file_url( ) {
117
+
118
+ return trailingslashit( PYS_FREE_URL ) .'logs/'. self::get_log_file_name( );
119
+ }
120
+
121
+
122
+
123
+ /**
124
+ * Get a log file name.
125
+ *
126
+ * File names consist of the handle, followed by the date, followed by a hash, .log.
127
+ *
128
+ * @return string The log file name or false if cannot be determined.
129
+ */
130
+ public static function get_log_file_name( ) {
131
+ return 'pys_debug.log';
132
+ }
133
+
134
+ /**
135
+ * Check if a handle is open.
136
+ *
137
+ * @return bool True if $handle is open.
138
+ */
139
+ protected function is_open( ) {
140
+ return is_resource( $this->handle );
141
+ }
142
+
143
+ /**
144
+ * Close a handle.
145
+ *
146
+ * @return bool success
147
+ */
148
+ protected function close() {
149
+ $result = false;
150
+
151
+ if ( $this->is_open() ) {
152
+ $result = fclose( $this->handle ); // @codingStandardsIgnoreLine.
153
+ $this->handle = null;
154
+ }
155
+
156
+ return $result;
157
+ }
158
+
159
+ /**
160
+ * Add a log entry to chosen file.
161
+ *
162
+ * @param string $entry Log entry text.
163
+ *
164
+ * @return bool True if write was successful.
165
+ */
166
+ protected function add( $entry ) {
167
+ $result = false;
168
+
169
+ if ( $this->open() && is_resource( $this->handle ) ) {
170
+ $result = fwrite( $this->handle, $entry . PHP_EOL ); // @codingStandardsIgnoreLine.
171
+ }
172
+
173
+ return false !== $result;
174
+ }
175
+
176
+ public function getLogs( ) {
177
+ if(is_file( self::get_log_file_path() ))
178
+ return file_get_contents(self::get_log_file_path());
179
+ return "";
180
+ }
181
+
182
+ /**
183
+ * Remove/delete the chosen file.
184
+ *
185
+ * @return bool
186
+ */
187
+ public function remove( )
188
+ {
189
+ $removed = false;
190
+ $file = realpath($this::get_log_file_path());
191
+ if (is_file($file) && is_writable($file)) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
192
+ $this->close(); // Close first to be certain no processes keep it alive after it is unlinked.
193
+ $removed = unlink($file); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink
194
+ }
195
+
196
+ return $removed;
197
+ }
198
+ }
includes/options_defaults.json CHANGED
@@ -119,5 +119,7 @@
119
  "enable_edd_category_name_param": true,
120
  "enable_edd_num_items_param": true,
121
  "enable_edd_product_price_param": true,
122
- "enable_remove_download_url_param": true
 
 
123
  }
119
  "enable_edd_category_name_param": true,
120
  "enable_edd_num_items_param": true,
121
  "enable_edd_product_price_param": true,
122
+ "enable_remove_download_url_param": true,
123
+ "logs_enable": true,
124
+ "woo_add_to_cart_catch_method": "add_cart_js"
125
  }
includes/options_fields.json CHANGED
@@ -107,5 +107,7 @@
107
  "enable_edd_category_name_param": "checkbox",
108
  "enable_edd_num_items_param": "checkbox",
109
  "enable_edd_product_price_param": "checkbox",
110
- "enable_remove_download_url_param": "checkbox"
 
 
111
  }
107
  "enable_edd_category_name_param": "checkbox",
108
  "enable_edd_num_items_param": "checkbox",
109
  "enable_edd_product_price_param": "checkbox",
110
+ "enable_remove_download_url_param": "checkbox",
111
+ "logs_enable": "checkbox",
112
+ "woo_add_to_cart_catch_method": "select"
113
  }
includes/views/html-logs.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PixelYourSite;
4
+
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ exit; // Exit if accessed directly.
7
+ }
8
+
9
+ if(isset($_GET['clear_logs'])) {
10
+ PYS()->getLog()->remove();
11
+ $actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
12
+ wp_redirect(remove_query_arg( 'clear_logs',$actual_link ));
13
+ exit;
14
+ }
15
+
16
+ ?>
17
+
18
+ <div class="card card-static">
19
+ <div class="card-header ">
20
+ <?php PYS()->render_switcher_input('logs_enable');?> Plugin Logs
21
+ <div style="float: right;margin-top: 10px;">
22
+ <a style="margin-right: 30px" href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite', 'logs' ) ); ?>&clear_logs=true">Clear Logs</a>
23
+ <a href="<?= PYS_Logger::get_log_file_url() ?>" target="_blank" download>Download Logs</a>
24
+ </div>
25
+ </div>
26
+ <div class="card-body">
27
+ <textarea style="white-space: nowrap;width: 100%;height: 500px;"><?php
28
+ echo PYS()->getLog()->getLogs();
29
+ ?></textarea>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="row justify-content-center">
34
+ <div class="col-4">
35
+ <button class="btn btn-block btn-sm btn-save">Save Settings</button>
36
+ </div>
37
+ </div>
includes/views/html-main-general.php CHANGED
@@ -249,16 +249,6 @@ if ( ! defined( 'ABSPATH' ) ) {
249
  </div>
250
  <?php endif; ?>
251
 
252
-
253
- <?php if ( Pinterest()->enabled() ) : ?>
254
- <div class="row">
255
- <div class="col">
256
- <?php Pinterest()->render_switcher_input( 'signal_events_enabled' ); ?>
257
- <h4 class="switcher-label">Enable on Pinterest</h4>
258
- </div>
259
- </div>
260
- <?php endif; ?>
261
-
262
  <?php if ( Bing()->enabled() ) : ?>
263
  <div class="row">
264
  <div class="col">
249
  </div>
250
  <?php endif; ?>
251
 
 
 
 
 
 
 
 
 
 
 
252
  <?php if ( Bing()->enabled() ) : ?>
253
  <div class="row">
254
  <div class="col">
includes/views/html-main-wcf.php CHANGED
@@ -18,6 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  <div class="row">
19
  <div class="col">
20
  <p>From here you can control the events and parameters fired by PixelYourSite Professional on CartFlos pages and actions.</p>
 
21
  <?php PYS()->render_switcher_input( "",false,true ); ?>
22
  <h4 class="switcher-label">Enable CartFlows set-up</h4>
23
  <?php renderProBadge(); ?>
18
  <div class="row">
19
  <div class="col">
20
  <p>From here you can control the events and parameters fired by PixelYourSite Professional on CartFlos pages and actions.</p>
21
+ <p>To learn more <a href="https://www.pixelyoursite.com/cartflows-and-pixelyoursite" target="_blank">go to this dedicated page and watch the video</a></p>
22
  <?php PYS()->render_switcher_input( "",false,true ); ?>
23
  <h4 class="switcher-label">Enable CartFlows set-up</h4>
24
  <?php renderProBadge(); ?>
includes/views/html-main-woo.php CHANGED
@@ -78,6 +78,13 @@ use PixelYourSite\Facebook\Helpers;
78
  </div>
79
  </div>
80
  </div>
 
 
 
 
 
 
 
81
  </div>
82
  </div>
83
 
78
  </div>
79
  </div>
80
  </div>
81
+ <div class="row">
82
+ <div class="col form-inline">
83
+ <label>Change this if the AddToCart event doesn't fire</label>
84
+ <?php PYS()->render_select_input( 'woo_add_to_cart_catch_method',
85
+ array('add_cart_hook'=>"WooCommerce hooks",'add_cart_js'=>"Button's classes",) ); ?>
86
+ </div>
87
+ </div>
88
  </div>
89
  </div>
90
 
includes/views/html-wrapper-main.php CHANGED
@@ -110,7 +110,9 @@ include "html-popovers.php";
110
  case 'reset_settings':
111
  include "html-reset.php";
112
  break;
113
-
 
 
114
  default:
115
  do_action( 'pys_admin_' . getCurrentAdminTab() );
116
  }
@@ -164,6 +166,9 @@ include "html-popovers.php";
164
  <a class="nav-item nav-link" href="https://www.pixelyoursite.com/video?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-right-menu"
165
  target="_blank" style="font-weight: bold;">VIDEO TIPS</a>
166
 
 
 
 
167
  </nav>
168
 
169
  <div class="card card-static card-primary">
110
  case 'reset_settings':
111
  include "html-reset.php";
112
  break;
113
+ case 'logs':
114
+ include "html-logs.php";
115
+ break;
116
  default:
117
  do_action( 'pys_admin_' . getCurrentAdminTab() );
118
  }
166
  <a class="nav-item nav-link" href="https://www.pixelyoursite.com/video?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-right-menu"
167
  target="_blank" style="font-weight: bold;">VIDEO TIPS</a>
168
 
169
+ <a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite', 'logs' ) ); ?>"
170
+ class="nav-item nav-link">Logs</a>
171
+
172
  </nav>
173
 
174
  <div class="card card-static card-primary">
modules/facebook/facebook-server.php CHANGED
@@ -13,6 +13,7 @@ require_once PYS_FREE_PATH . '/modules/facebook/facebook-server-async-task.php';
13
  require_once PYS_FREE_PATH . '/modules/facebook/PYSServerEventHelper.php';
14
 
15
  use PYS_PRO_GLOBAL\FacebookAds\Api;
 
16
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\EventRequest;
17
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\Event;
18
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\CustomData;
@@ -202,9 +203,15 @@ class FacebookServer {
202
  $request->setTestEventCode($this->testCode[$pixel_Id]);
203
 
204
  try{
 
205
  $response = $request->execute();
 
206
  } catch (\Exception $e) {
207
- // error_log("error send Fb API request ".$e->getMessage());
 
 
 
 
208
  }
209
 
210
  }
13
  require_once PYS_FREE_PATH . '/modules/facebook/PYSServerEventHelper.php';
14
 
15
  use PYS_PRO_GLOBAL\FacebookAds\Api;
16
+ use PYS_PRO_GLOBAL\FacebookAds\Http\Exception\RequestException;
17
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\EventRequest;
18
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\Event;
19
  use PYS_PRO_GLOBAL\FacebookAds\Object\ServerSide\CustomData;
203
  $request->setTestEventCode($this->testCode[$pixel_Id]);
204
 
205
  try{
206
+ PYS()->getLog()->debug('Send FB server event',$request);
207
  $response = $request->execute();
208
+ PYS()->getLog()->debug('Response from FB server',$response);
209
  } catch (\Exception $e) {
210
+ if($e instanceof RequestException) {
211
+ PYS()->getLog()->error('Error send FB server event '.$e->getErrorUserMessage(),$e->getResponse());
212
+ } else {
213
+ PYS()->getLog()->error('Error send FB server event',$e);
214
+ }
215
  }
216
 
217
  }
modules/facebook/facebook.php CHANGED
@@ -46,41 +46,10 @@ class Facebook extends Settings implements Pixel {
46
  $core->registerPixel( $this );
47
  } );
48
  add_action( 'wp_head', array( $this, 'output_meta_tag' ) );
49
- // add_action( 'woocommerce_add_to_cart', array($this,'server_woo_add_to_cart') , 20, 6 );
50
- // add_action( 'woocommerce_ajax_added_to_cart', array($this,'server_woo_add_to_cart_ajax') );
51
- }
52
-
53
- function server_woo_add_to_cart_ajax($product_id,$quantity = 1) {
54
-
55
- if(EventsWoo()->isEnabled() && EventsWoo()->isReadyForFire("woo_add_to_cart_on_button_click")) {
56
-
57
- $event = EventsWoo()->getEvent("woo_add_to_cart_on_button_click");
58
- $isSuccess = Facebook()->addParamsToEvent( $event );
59
- if ( !$isSuccess ) {
60
- return;
61
- }
62
- $eventData = Facebook()->getEventData( 'woo_add_to_cart_on_button_click', $product_id );
63
- if(!$eventData) return;
64
- $data = $eventData['data'];
65
-
66
- if(isset($data['contents']) ) {
67
- $data['contents'][0]['quantity'] = $quantity;
68
- }
69
 
70
- $event->addParams($data);
71
- $event->addParams(getStandardParams());
72
- $serverEvent = FacebookServer()->createEvent($event->payload["eventID"],$event->payload["name"],$event->getData()['params']);
73
-
74
- FacebookServer()->addAsyncEvents(array(
75
- array("pixelIds" => Facebook()->getPixelIDs(), "event" => $serverEvent )
76
- ));
77
- }
78
  }
79
 
80
- function server_woo_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
81
 
82
- $this->server_woo_add_to_cart_ajax($product_id,$quantity);
83
- }
84
 
85
  public function enabled() {
86
  return $this->getOption( 'enabled' );
@@ -213,7 +182,7 @@ class Facebook extends Settings implements Pixel {
213
  $payload = array(
214
  'name' => "AddToCart",
215
  'trigger_type' => $trigger_type,
216
- 'trigger_value' => $trigger_value
217
  );
218
  $event->addParams($params);
219
  $event->addPayload($payload);
@@ -357,8 +326,13 @@ class Facebook extends Settings implements Pixel {
357
  case 'woo_add_to_cart_on_button_click':{
358
  if ( $this->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
359
  $isActive = true;
 
 
 
 
360
  $event->addPayload(array(
361
- 'name'=>"AddToCart"
 
362
  ));
363
  }
364
  }break;
@@ -668,13 +642,15 @@ class Facebook extends Settings implements Pixel {
668
 
669
  }
670
 
671
- private function getWooAddToCartOnButtonClickEventParams( $product_id ) {
672
 
673
  if ( ! $this->getOption( 'woo_add_to_cart_enabled' ) || ! PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
674
  return false;
675
  }
 
 
676
 
677
- $params = Helpers\getWooSingleAddToCartParams( $product_id, 1 );
678
  $data = array(
679
  'params' => $params,
680
  );
46
  $core->registerPixel( $this );
47
  } );
48
  add_action( 'wp_head', array( $this, 'output_meta_tag' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
 
 
 
 
 
 
 
 
50
  }
51
 
 
52
 
 
 
53
 
54
  public function enabled() {
55
  return $this->getOption( 'enabled' );
182
  $payload = array(
183
  'name' => "AddToCart",
184
  'trigger_type' => $trigger_type,
185
+ 'trigger_value' => [$trigger_value]
186
  );
187
  $event->addParams($params);
188
  $event->addPayload($payload);
326
  case 'woo_add_to_cart_on_button_click':{
327
  if ( $this->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
328
  $isActive = true;
329
+ if(isset($event->args['productId'])) {
330
+ $eventData = $this->getWooAddToCartOnButtonClickEventParams( $event->args );
331
+ $event->addParams($eventData["params"]);
332
+ }
333
  $event->addPayload(array(
334
+ 'name'=>"AddToCart",
335
+ 'pixelIds' => isset($eventData["pixelIds"]) ? $eventData["pixelIds"] : null,
336
  ));
337
  }
338
  }break;
642
 
643
  }
644
 
645
+ private function getWooAddToCartOnButtonClickEventParams( $args ) {
646
 
647
  if ( ! $this->getOption( 'woo_add_to_cart_enabled' ) || ! PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
648
  return false;
649
  }
650
+ $product_id = $args['productId'];
651
+ $quantity = $args['quantity'];
652
 
653
+ $params = Helpers\getWooSingleAddToCartParams( $product_id, $quantity );
654
  $data = array(
655
  'params' => $params,
656
  );
modules/facebook/function-helpers.php CHANGED
@@ -324,7 +324,7 @@ function getWooSingleAddToCartParams( $_product_id, $qty = 1 ) {
324
  // Facebook for WooCommerce plugin does not support new Dynamic Ads parameters
325
  $params['contents'][] = array(
326
  'id' => (string) reset( $content_id ),
327
- 'quantity' => 1,
328
  //'item_price' => PixelYourSite\getWooProductPriceToDisplay( $product_id ),// remove because price need send only with currency
329
  );
330
  }
324
  // Facebook for WooCommerce plugin does not support new Dynamic Ads parameters
325
  $params['contents'][] = array(
326
  'id' => (string) reset( $content_id ),
327
+ 'quantity' => $qty,
328
  //'item_price' => PixelYourSite\getWooProductPriceToDisplay( $product_id ),// remove because price need send only with currency
329
  );
330
  }
modules/google_analytics/ga.php CHANGED
@@ -264,6 +264,15 @@ class GA extends Settings implements Pixel {
264
  case 'woo_add_to_cart_on_button_click': {
265
  if ( $this->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
266
  $isActive = true;
 
 
 
 
 
 
 
 
 
267
  $event->addPayload(array(
268
  'name'=>"add_to_cart"
269
  ));
@@ -560,11 +569,14 @@ class GA extends Settings implements Pixel {
560
 
561
  }
562
 
563
- private function getWooAddToCartOnButtonClickEventParams( $product_id ) {
564
 
565
  if ( ! $this->getOption( 'woo_add_to_cart_enabled' ) || ! PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
566
  return false;
567
  }
 
 
 
568
  $product = wc_get_product( $product_id );
569
  if(!$product) return false;
570
 
@@ -584,7 +596,7 @@ class GA extends Settings implements Pixel {
584
  continue;
585
  }
586
  $content_id = GA\Helpers\getWooProductContentId($child_id);
587
- $price = getWooProductPriceToDisplay( $child_id, 1 );
588
  $name = $childProduct->get_title();
589
 
590
  if ( $childProduct->get_type() == 'variation' ) {
@@ -598,7 +610,7 @@ class GA extends Settings implements Pixel {
598
  'id' => $content_id,
599
  'name' => $name,
600
  'category' => $categories,
601
- 'quantity' => 1,
602
  'price' => $price,
603
  'variant' => $variation_name,
604
  );
264
  case 'woo_add_to_cart_on_button_click': {
265
  if ( $this->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
266
  $isActive = true;
267
+ if(isset($event->args['productId'])) {
268
+ $eventData = $this->getWooAddToCartOnButtonClickEventParams( $event );
269
+
270
+ if($eventData) {
271
+ $event->addParams($eventData["params"]);
272
+ unset($eventData["params"]);
273
+ $event->addPayload($eventData);
274
+ }
275
+ }
276
  $event->addPayload(array(
277
  'name'=>"add_to_cart"
278
  ));
569
 
570
  }
571
 
572
+ private function getWooAddToCartOnButtonClickEventParams( $args ) {
573
 
574
  if ( ! $this->getOption( 'woo_add_to_cart_enabled' ) || ! PYS()->getOption( 'woo_add_to_cart_on_button_click' ) ) {
575
  return false;
576
  }
577
+ $product_id = $args->args['productId'];
578
+ $quantity = $args->args['quantity'];
579
+
580
  $product = wc_get_product( $product_id );
581
  if(!$product) return false;
582
 
596
  continue;
597
  }
598
  $content_id = GA\Helpers\getWooProductContentId($child_id);
599
+ $price = getWooProductPriceToDisplay( $child_id, $quantity );
600
  $name = $childProduct->get_title();
601
 
602
  if ( $childProduct->get_type() == 'variation' ) {
610
  'id' => $content_id,
611
  'name' => $name,
612
  'category' => $categories,
613
+ 'quantity' => $quantity,
614
  'price' => $price,
615
  'variant' => $variation_name,
616
  );
notices/fixed.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PixelYourSite;
4
+
5
+ if ( ! defined( 'ABSPATH' ) ) {
6
+ exit; // Exit if accessed directly.
7
+ }
8
+
9
+ /*
10
+ * Notice structure
11
+ [
12
+ 'plugins' =>[], // can be "woo","wcf","edd" or empty array
13
+ 'slug' => '',// unique id
14
+ 'message' => '' // message with html tags
15
+ ]
16
+ * */
17
+
18
+ function adminGetFixedNotices() {
19
+ return [
20
+ [
21
+ 'plugins' =>["woo","wcf"],
22
+ 'slug' => 'wcf_and_woo_promo',
23
+ 'message' => 'HOT: Improve CartFlows tracking with PixelYourSite Professional: <a target="_blank" href="https://www.pixelyoursite.com/cartflows-and-pixelyoursite">CLICK TO LEARN MORE</a>'
24
+ ]
25
+ ];
26
+ }
pixelyoursite.php CHANGED
@@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
- define( 'PYS_FREE_VERSION', '8.2.6' );
8
  define( 'PYS_FREE_PINTEREST_MIN_VERSION', '3.0.0' );
9
  define( 'PYS_FREE_BING_MIN_VERSION', '2.0.0' );
10
  define( 'PYS_FREE_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
@@ -18,6 +18,7 @@ if ( isPysProActive()) {
18
  return; // exit early when PYS PRO is active
19
  }
20
  require_once PYS_FREE_PATH.'/vendor/autoload.php';
 
21
  require_once PYS_FREE_PATH.'/includes/class-event-id-generator.php';
22
  require_once PYS_FREE_PATH.'/includes/functions-common.php';
23
  require_once PYS_FREE_PATH.'/includes/functions-admin.php';
@@ -41,10 +42,12 @@ require_once PYS_FREE_PATH.'/includes/functions-gdpr.php';
41
  require_once PYS_FREE_PATH.'/includes/functions-migrate.php';
42
  require_once PYS_FREE_PATH.'/includes/functions-optin.php';
43
  require_once PYS_FREE_PATH.'/includes/functions-promo-notices.php';
 
44
  require_once PYS_FREE_PATH.'/includes/class-pixel.php';
45
  require_once PYS_FREE_PATH.'/includes/class-settings.php';
46
  require_once PYS_FREE_PATH.'/includes/class-plugin.php';
47
 
 
48
  require_once PYS_FREE_PATH.'/includes/class-pys.php';
49
  require_once PYS_FREE_PATH.'/includes/class-events-manager.php';
50
  require_once PYS_FREE_PATH.'/includes/class-custom-event.php';
@@ -54,5 +57,6 @@ require_once PYS_FREE_PATH.'/modules/facebook/facebook-server.php';
54
  require_once PYS_FREE_PATH.'/modules/google_analytics/ga.php';
55
  require_once PYS_FREE_PATH.'/modules/head_footer/head_footer.php';
56
 
 
57
  // here we go...
58
  PixelYourSite\PYS();
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
+ define( 'PYS_FREE_VERSION', '8.2.7' );
8
  define( 'PYS_FREE_PINTEREST_MIN_VERSION', '3.0.0' );
9
  define( 'PYS_FREE_BING_MIN_VERSION', '2.0.0' );
10
  define( 'PYS_FREE_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
18
  return; // exit early when PYS PRO is active
19
  }
20
  require_once PYS_FREE_PATH.'/vendor/autoload.php';
21
+ require_once PYS_FREE_PATH.'/includes/logger/class-pys-logger.php';
22
  require_once PYS_FREE_PATH.'/includes/class-event-id-generator.php';
23
  require_once PYS_FREE_PATH.'/includes/functions-common.php';
24
  require_once PYS_FREE_PATH.'/includes/functions-admin.php';
42
  require_once PYS_FREE_PATH.'/includes/functions-migrate.php';
43
  require_once PYS_FREE_PATH.'/includes/functions-optin.php';
44
  require_once PYS_FREE_PATH.'/includes/functions-promo-notices.php';
45
+ require_once PYS_FREE_PATH.'/includes/class-fixed-notices.php';
46
  require_once PYS_FREE_PATH.'/includes/class-pixel.php';
47
  require_once PYS_FREE_PATH.'/includes/class-settings.php';
48
  require_once PYS_FREE_PATH.'/includes/class-plugin.php';
49
 
50
+ require_once PYS_FREE_PATH.'/includes/class-events-manager-ajax_hook.php';
51
  require_once PYS_FREE_PATH.'/includes/class-pys.php';
52
  require_once PYS_FREE_PATH.'/includes/class-events-manager.php';
53
  require_once PYS_FREE_PATH.'/includes/class-custom-event.php';
57
  require_once PYS_FREE_PATH.'/modules/google_analytics/ga.php';
58
  require_once PYS_FREE_PATH.'/modules/head_footer/head_footer.php';
59
 
60
+
61
  // here we go...
62
  PixelYourSite\PYS();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: Facebook Pixel, Facebook Conversion API, CAPI, Facebook Pixel Events, Face
4
  Requires at least: 3.0.1
5
  Requires PHP: 5.4
6
  Tested up to: 5.8
7
- Stable tag: 8.2.6
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -460,6 +460,21 @@ NO, absolutely not! We don't track any type of data about your website. We simpl
460
  == Changelog ==
461
 
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  = PixelYourSite 8.2.6 =
464
 
465
  * UI update to reflect the [new integration with CartFlows available in PixelYourSite Professional](https://www.pixelyoursite.com/cartflows-and-pixelyoursite)
4
  Requires at least: 3.0.1
5
  Requires PHP: 5.4
6
  Tested up to: 5.8
7
+ Stable tag: 8.2.7
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
460
  == Changelog ==
461
 
462
 
463
+ = PixelYourSite 8.2.7 =
464
+
465
+ * Improvements regarding how WooCommerce related events are fired.
466
+
467
+ * Signal event removed for Pinterest tag. This change affects only users of our free Pinterest Tag add-on. The Signal event is no longer fired for Pinterest, because it was not easy to use it for audiences or conversions. If the default events fired by the plugin are not enough, consider adding your own Pinterest events on the plugin's Events page.
468
+
469
+ * WooCommerce 5.6 compatibility.
470
+
471
+ * Small UI change: Notification about CartFlows integration.
472
+
473
+ * New option to store logs for Facebook CAPI events.
474
+
475
+ * Other code changes.
476
+
477
+
478
  = PixelYourSite 8.2.6 =
479
 
480
  * UI update to reflect the [new integration with CartFlows available in PixelYourSite Professional](https://www.pixelyoursite.com/cartflows-and-pixelyoursite)