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

Version Description

Download this release

Release Info

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

Code changes from version 7.1.14 to 7.2.0

dist/scripts/public.js CHANGED
@@ -680,8 +680,7 @@ if (!Array.prototype.includes) {
680
  }(options);
681
 
682
  var Facebook = function (options) {
683
- var serverEvents = ["Purchase","InitiateCheckout","CompleteRegistration","hCR","ViewContent","PageView"];
684
- var serverEventsDynamic = ["AddToCart"];
685
 
686
  var defaultEventTypes = [
687
  'PageView',
@@ -706,6 +705,16 @@ if (!Array.prototype.includes) {
706
 
707
  var initialized = false;
708
 
 
 
 
 
 
 
 
 
 
 
709
  function fireEvent(name, allData) {
710
 
711
  var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
@@ -722,14 +731,22 @@ if (!Array.prototype.includes) {
722
  options.gdpr.ginger_integration_enabled ||
723
  options.gdpr.cookie_notice_integration_enabled ||
724
  options.gdpr.cookie_law_info_integration_enabled;
 
 
 
 
 
 
725
  // send event from server if they was bloc by gdpr or need send with delay
726
- if( serverEvents.includes(name) && isApiDisabled || allData.delay > 0 || serverEventsDynamic.includes(name))
727
  {
728
  var json = {
729
  action: 'pys_api_event',
730
  pixel: 'facebook',
731
  event: name,
732
- data:data
 
 
733
  };
734
  jQuery.ajax( {
735
  type: 'POST',
@@ -746,18 +763,14 @@ if (!Array.prototype.includes) {
746
  }
747
 
748
  if (options.debug) {
749
- console.log('[Facebook] ' + name, params);
750
  }
751
  var arg = {};
752
- if(options.facebook.serverApiEnabled && params.hasOwnProperty('eventID')) {
753
- arg.eventID = params.eventID;
754
  }
755
 
756
- if(serverEvents.includes(name) || serverEventsDynamic.includes(name)) { // Deduplicate Pixel and Server-Side Events for Purchase event
757
- fbq(actionType, name, params,arg);
758
- } else {
759
- fbq(actionType, name, params);
760
- }
761
  }
762
 
763
  /**
@@ -850,9 +863,9 @@ if (!Array.prototype.includes) {
850
  onCommentEvent: function () {
851
 
852
  if (initialized && this.isEnabled() && options.facebook.commentEventEnabled) {
853
-
854
  this.fireEvent('Comment', {
855
- params: Utils.copyProperties(options.facebook.contentParams, {})
856
  });
857
 
858
  }
@@ -862,7 +875,6 @@ if (!Array.prototype.includes) {
862
  onDownloadEvent: function (params) {
863
 
864
  if (initialized && this.isEnabled() && options.facebook.downloadEnabled) {
865
-
866
  this.fireEvent('Download', {
867
  params: Utils.copyProperties(options.facebook.contentParams, params)
868
  });
@@ -1321,7 +1333,7 @@ if (!Array.prototype.includes) {
1321
  });
1322
 
1323
  // Single Product
1324
- $('.single_add_to_cart_button').click(function (e) {
1325
 
1326
  var $button = $(this);
1327
 
@@ -1635,4 +1647,15 @@ if (!Array.prototype.includes) {
1635
 
1636
  });
1637
 
1638
- }(jQuery, pysOptions);
 
 
 
 
 
 
 
 
 
 
 
680
  }(options);
681
 
682
  var Facebook = function (options) {
683
+
 
684
 
685
  var defaultEventTypes = [
686
  'PageView',
705
 
706
  var initialized = false;
707
 
708
+ var serverEventsDynamic = ["AddToCart","RemoveFromCart","ClickEvent","AdSense","WatchVideo",'Comment','Form','Download'];
709
+ // add dynamic events from options
710
+ Object.keys(options.dynamicEventsParams).forEach(function(k){
711
+ if(options.dynamicEventsParams[k].hasOwnProperty('facebook')) {
712
+ serverEventsDynamic.push(options.dynamicEventsParams[k]['facebook']['name']);
713
+ }
714
+ });
715
+ serverEventsDynamic.push(options.woo.affiliateEventName);
716
+ serverEventsDynamic.push(options.woo.paypalEventName);
717
+
718
  function fireEvent(name, allData) {
719
 
720
  var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
731
  options.gdpr.ginger_integration_enabled ||
732
  options.gdpr.cookie_notice_integration_enabled ||
733
  options.gdpr.cookie_law_info_integration_enabled;
734
+
735
+ // Update eventID
736
+ if( options.facebook.ajaxForServerEvent || serverEventsDynamic.includes(name) ) {
737
+ allData.eventID = pys_generate_token(36);
738
+ }
739
+
740
  // send event from server if they was bloc by gdpr or need send with delay
741
+ if( options.facebook.ajaxForServerEvent || isApiDisabled || allData.delay > 0 || serverEventsDynamic.includes(name))
742
  {
743
  var json = {
744
  action: 'pys_api_event',
745
  pixel: 'facebook',
746
  event: name,
747
+ data:data,
748
+ ids:options.facebook.pixelIds,
749
+ eventID:allData.eventID
750
  };
751
  jQuery.ajax( {
752
  type: 'POST',
763
  }
764
 
765
  if (options.debug) {
766
+ console.log('[Facebook] ' + name, params,"eventID",allData.eventID);
767
  }
768
  var arg = {};
769
+ if(allData.hasOwnProperty('eventID')) {
770
+ arg.eventID = allData.eventID;
771
  }
772
 
773
+ fbq(actionType, name, params,arg);
 
 
 
 
774
  }
775
 
776
  /**
863
  onCommentEvent: function () {
864
 
865
  if (initialized && this.isEnabled() && options.facebook.commentEventEnabled) {
866
+ var param = {};
867
  this.fireEvent('Comment', {
868
+ params: Utils.copyProperties(options.facebook.contentParams, param)
869
  });
870
 
871
  }
875
  onDownloadEvent: function (params) {
876
 
877
  if (initialized && this.isEnabled() && options.facebook.downloadEnabled) {
 
878
  this.fireEvent('Download', {
879
  params: Utils.copyProperties(options.facebook.contentParams, params)
880
  });
1333
  });
1334
 
1335
  // Single Product
1336
+ $('body').on('click','.single_add_to_cart_button',function (e) {
1337
 
1338
  var $button = $(this);
1339
 
1647
 
1648
  });
1649
 
1650
+ }(jQuery, pysOptions);
1651
+
1652
+ function pys_generate_token(length){
1653
+ //edit the token allowed characters
1654
+ var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
1655
+ var b = [];
1656
+ for (var i=0; i<length; i++) {
1657
+ var j = (Math.random() * (a.length-1)).toFixed(0);
1658
+ b[i] = a[j];
1659
+ }
1660
+ return b.join("");
1661
+ }
facebook-pixel-master.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: PixelYourSite
5
  * Plugin URI: http://www.pixelyoursite.com/
6
  * Description: No codding <strong>Facebook Pixel</strong> and <strong>Google Analytics</strong> install. Track key actions with our Global Events, 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.
7
- * Version: 7.1.14
8
  * Author: PixelYourSite
9
  * Author URI: http://www.pixelyoursite.com
10
  * License: GPLv3
4
  * Plugin Name: PixelYourSite
5
  * Plugin URI: http://www.pixelyoursite.com/
6
  * Description: No codding <strong>Facebook Pixel</strong> and <strong>Google Analytics</strong> install. Track key actions with our Global Events, 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.
7
+ * Version: 7.2.0
8
  * Author: PixelYourSite
9
  * Author URI: http://www.pixelyoursite.com
10
  * License: GPLv3
includes/class-event-id-generator.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace PixelYourSite;
3
+
4
+ final class EventIdGenerator {
5
+
6
+ public static function guidv4() {
7
+ $data = openssl_random_pseudo_bytes(16);
8
+
9
+ $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
10
+ $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
11
+
12
+ return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
13
+ }
14
+ }
includes/class-events-manager.php CHANGED
@@ -11,9 +11,7 @@ use FacebookAds\Object\ServerSide\Content;
11
 
12
  class EventsManager {
13
 
14
- static public $facebookServerEvents = array();
15
- private $facebookServerEventTypes = array("edd_purchase","woo_purchase","init_event","woo_view_content",
16
- "edd_view_content","edd_initiate_checkout","woo_initiate_checkout");
17
 
18
  public $doingAMP = false;
19
 
@@ -136,7 +134,7 @@ class EventsManager {
136
 
137
  public function setupEventsParams() {
138
 
139
- EventsManager::$facebookServerEvents = array();
140
 
141
  // initial event
142
  $this->addStaticEvent( 'init_event' );
@@ -164,8 +162,8 @@ class EventsManager {
164
  $this->setupEddEvents();
165
  }
166
 
167
- if(count(EventsManager::$facebookServerEvents)>0 && Facebook()->enabled()) {
168
- Facebook()->trackEventByServerApi(EventsManager::$facebookServerEvents);
169
  }
170
  }
171
 
@@ -211,20 +209,23 @@ class EventsManager {
211
  $eventName = $eventData['name'];
212
  $ids = isset( $eventData['ids'] ) ? $eventData['ids'] : array();
213
 
214
- $this->staticEvents[ $pixel->getSlug() ][ $eventName ][] = array(
215
  'params' => sanitizeParams( $eventData['data'] ),
216
  'delay' => isset( $eventData['delay'] ) ? $eventData['delay'] : 0,
217
  'ids' => $ids,
 
218
  );
219
 
220
  // fire fb server api event
221
- if($pixel->getSlug() == "facebook" && in_array($eventType,$this->facebookServerEventTypes)) {
222
  if ($eventData != null) {
223
  if ($eventData != null && (!isset($eventData['delay']) || $eventData['delay'] == 0)) {
224
- $this->addEventToFacebookServerApi($pixel, $eventType, $eventData);
225
  }
226
  }
227
  }
 
 
228
  }
229
 
230
  }
@@ -381,15 +382,6 @@ class EventsManager {
381
  }
382
  }
383
 
384
- if(!$isGdprEnabled) {
385
- // send by server api
386
- $eventData = Facebook()->getEventData( 'complete_registration',null );
387
- if($eventData != null) {
388
- $this->addEventToFacebookServerApi(Facebook(),'complete_registration',$eventData);
389
- }
390
- }
391
-
392
-
393
  } else {
394
  $this->addStaticEvent('complete_registration', null, "facebook");
395
  }
@@ -411,11 +403,11 @@ class EventsManager {
411
  isCookieLawInfoPluginActivated() && PYS()->getOption( 'gdpr_cookie_law_info_integration_enabled' );
412
  }
413
 
414
- function addEventToFacebookServerApi($pixel,$eventType,$eventData) {
415
- $isDisabled = $this->isGdprPluginEnabled();
416
 
417
 
418
- if( !$isDisabled ) {
419
  $name = $eventData['name'];
420
  $data = $eventData['data'];
421
 
@@ -424,78 +416,11 @@ class EventsManager {
424
  $data['contents']=$contents;
425
  }
426
 
427
- EventsManager::sendFbApiEvent($pixel,$name,$data);
 
428
  }
429
  }
430
 
431
- static function sendFbApiEvent($pixel,$name,$data,$async = true) {
432
-
433
- if(!$pixel->isServerApiEnabled() || !isset($data['eventID'])) return;
434
-
435
- $event = ServerEventHelper::newEvent($name,$data['eventID']);
436
- $event->setEventTime(time());
437
-
438
- if(isset($data['contents']) && is_array($data['contents'])) {
439
- $contents = array();
440
- foreach ($data['contents'] as $c) {
441
- $content = array();
442
- $content['product_id'] = $c->id;
443
- $content['quantity'] = $c->quantity;
444
- $content['item_price'] = $c->item_price;
445
- $contents[] = new Content($content);
446
- }
447
- $data['contents'] = $contents;
448
- } else {
449
- $data['contents'] = array();
450
- }
451
-
452
- $event->setCustomData(new CustomData($data));
453
-
454
- $custom_data = $event->getCustomData();
455
- if(isset($data['category_name'])) {
456
- $custom_data->setContentCategory($data['category_name']);
457
- }
458
-
459
- //$custom_data->setOrderId($data['transaction_id']);
460
- if($async) {
461
- EventsManager::$facebookServerEvents[]=$event;
462
- //$pixel->trackEventByServerApi($event);
463
- } else {
464
- Facebook::sendServerRequest(array($event));
465
- }
466
-
467
- }
468
-
469
- static function sendApiEvent() {
470
-
471
- $pixelName = $_POST['pixel'];
472
- $event = $_POST['event'];
473
- $data = $_POST['data'];
474
-
475
- if($event == "hCR") $event="CompleteRegistration"; // de mask completer registration event if it was hidden
476
-
477
- switch ($pixelName) {
478
- case 'facebook': {
479
- if(isset($data['content_ids'])) {
480
- $content_ids = json_decode(stripslashes($data['content_ids']));
481
- $data['content_ids']=$content_ids;
482
- }
483
- if(isset($data['contents'])) {
484
- if(is_array($data['contents'])) {
485
- $contents = json_decode(json_encode($data['contents']));
486
- } else {
487
- $contents = json_decode(stripslashes($data['contents']));
488
- }
489
-
490
- $data['contents']=$contents;
491
- }
492
- EventsManager::sendFbApiEvent(Facebook::instance(),$event,$data,false);
493
- break;
494
- }
495
- }
496
- /* echo "hi";
497
- wp_die();*/
498
- }
499
 
500
  public function setupWooLoopProductData()
501
  {
11
 
12
  class EventsManager {
13
 
14
+ public $facebookServerEvents = array();
 
 
15
 
16
  public $doingAMP = false;
17
 
134
 
135
  public function setupEventsParams() {
136
 
137
+ $this->facebookServerEvents = array();
138
 
139
  // initial event
140
  $this->addStaticEvent( 'init_event' );
162
  $this->setupEddEvents();
163
  }
164
 
165
+ if(count($this->facebookServerEvents)>0 && Facebook()->enabled()) {
166
+ FacebookServer()->addAsyncEvents($this->facebookServerEvents);
167
  }
168
  }
169
 
209
  $eventName = $eventData['name'];
210
  $ids = isset( $eventData['ids'] ) ? $eventData['ids'] : array();
211
 
212
+ $data = array(
213
  'params' => sanitizeParams( $eventData['data'] ),
214
  'delay' => isset( $eventData['delay'] ) ? $eventData['delay'] : 0,
215
  'ids' => $ids,
216
+ 'eventID' => isset( $eventData['eventID'] ) ? $eventData['eventID'] : "",
217
  );
218
 
219
  // fire fb server api event
220
+ if($pixel->getSlug() == "facebook" && !Facebook()->getOption( "server_event_use_ajax" ) ) {
221
  if ($eventData != null) {
222
  if ($eventData != null && (!isset($eventData['delay']) || $eventData['delay'] == 0)) {
223
+ $this->addEventToFacebookServerApi($data["eventID"], $eventType, $eventData);
224
  }
225
  }
226
  }
227
+
228
+ $this->staticEvents[ $pixel->getSlug() ][ $eventName ][] = $data;
229
  }
230
 
231
  }
382
  }
383
  }
384
 
 
 
 
 
 
 
 
 
 
385
  } else {
386
  $this->addStaticEvent('complete_registration', null, "facebook");
387
  }
403
  isCookieLawInfoPluginActivated() && PYS()->getOption( 'gdpr_cookie_law_info_integration_enabled' );
404
  }
405
 
406
+ function addEventToFacebookServerApi($eventID,$eventType,$eventData) {
407
+ $isEnabled = $this->isGdprPluginEnabled();
408
 
409
 
410
+ if( !$isEnabled ) {
411
  $name = $eventData['name'];
412
  $data = $eventData['data'];
413
 
416
  $data['contents']=$contents;
417
  }
418
 
419
+ $serverEvent = FacebookServer()->createEvent($eventID,$name,$data);
420
+ $this->facebookServerEvents[] = array("pixelIds" => Facebook()->getPixelIDs(), "event" => $serverEvent );
421
  }
422
  }
423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
 
425
  public function setupWooLoopProductData()
426
  {
includes/class-pys.php CHANGED
@@ -77,9 +77,6 @@ final class PYS extends Settings implements Plugin {
77
 
78
  } );
79
 
80
- add_action( 'wp_ajax_pys_api_event','PixelYourSite\EventsManager::sendApiEvent');
81
- add_action( 'wp_ajax_nopriv_pys_api_event', 'PixelYourSite\EventsManager::sendApiEvent');
82
-
83
  add_action( 'wp_ajax_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
84
  add_action( 'wp_ajax_nopriv_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
85
 
77
 
78
  } );
79
 
 
 
 
80
  add_action( 'wp_ajax_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
81
  add_action( 'wp_ajax_nopriv_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
82
 
includes/options_defaults.json CHANGED
@@ -29,14 +29,14 @@
29
  "woo_add_to_cart_on_checkout_page": false,
30
  "woo_purchase_value_option": "price",
31
  "woo_purchase_value_global": 0,
32
- "woo_initiate_checkout_value_enabled": false,
33
  "woo_initiate_checkout_value_option": "price",
34
  "woo_initiate_checkout_value_global": 0,
35
  "woo_add_to_cart_value_enabled": true,
36
  "woo_add_to_cart_value_option": "price",
37
  "woo_add_to_cart_value_global": 0,
38
  "woo_view_content_delay": 0,
39
- "woo_view_content_value_enabled": false,
40
  "woo_view_content_value_option": "price",
41
  "woo_view_content_value_global": 0,
42
 
@@ -45,14 +45,14 @@
45
  "edd_add_to_cart_on_checkout_page": false,
46
  "edd_purchase_value_option": "price",
47
  "edd_purchase_value_global": 0,
48
- "edd_initiate_checkout_value_enabled": false,
49
  "edd_initiate_checkout_value_option": "price",
50
  "edd_initiate_checkout_value_global": 0,
51
  "edd_add_to_cart_value_enabled": true,
52
  "edd_add_to_cart_value_option": "price",
53
  "edd_add_to_cart_value_global": 0,
54
  "edd_view_content_delay": 0,
55
- "edd_view_content_value_enabled": false,
56
  "edd_view_content_value_option": "price",
57
  "edd_view_content_value_global": 0,
58
 
29
  "woo_add_to_cart_on_checkout_page": false,
30
  "woo_purchase_value_option": "price",
31
  "woo_purchase_value_global": 0,
32
+ "woo_initiate_checkout_value_enabled": true,
33
  "woo_initiate_checkout_value_option": "price",
34
  "woo_initiate_checkout_value_global": 0,
35
  "woo_add_to_cart_value_enabled": true,
36
  "woo_add_to_cart_value_option": "price",
37
  "woo_add_to_cart_value_global": 0,
38
  "woo_view_content_delay": 0,
39
+ "woo_view_content_value_enabled": true,
40
  "woo_view_content_value_option": "price",
41
  "woo_view_content_value_global": 0,
42
 
45
  "edd_add_to_cart_on_checkout_page": false,
46
  "edd_purchase_value_option": "price",
47
  "edd_purchase_value_global": 0,
48
+ "edd_initiate_checkout_value_enabled": true,
49
  "edd_initiate_checkout_value_option": "price",
50
  "edd_initiate_checkout_value_global": 0,
51
  "edd_add_to_cart_value_enabled": true,
52
  "edd_add_to_cart_value_option": "price",
53
  "edd_add_to_cart_value_global": 0,
54
  "edd_view_content_delay": 0,
55
+ "edd_view_content_value_enabled": true,
56
  "edd_view_content_value_option": "price",
57
  "edd_view_content_value_global": 0,
58
 
includes/views/html-main-general.php CHANGED
@@ -43,6 +43,7 @@ if ( ! defined( 'ABSPATH' ) ) {
43
  "use_server_api",
44
  "Send events directly from your web server to Facebook through the Conversion API. This can help you capture more events. An access token is required to use the server-side API. <a href='https://www.pixelyoursite.com/documentation/configure-server-side-events' target='_blank'>Generate Access Token</a>"
45
  ); ?>
 
46
  <?php Facebook()->render_text_area_array_item("server_access_api_token","Api token") ?>
47
  <small class="form-text">
48
  This is an experimental feature and works only for the automatilly fired standard events. We plan to expand it to all events soon.
43
  "use_server_api",
44
  "Send events directly from your web server to Facebook through the Conversion API. This can help you capture more events. An access token is required to use the server-side API. <a href='https://www.pixelyoursite.com/documentation/configure-server-side-events' target='_blank'>Generate Access Token</a>"
45
  ); ?>
46
+ <?php Facebook()->render_checkbox_input("server_event_use_ajax","Use Ajax when conversion API is enabled. Keep this option active if you use a cache");?>
47
  <?php Facebook()->render_text_area_array_item("server_access_api_token","Api token") ?>
48
  <small class="form-text">
49
  This is an experimental feature and works only for the automatilly fired standard events. We plan to expand it to all events soon.
modules/facebook/{PYSServerEventAsyncTask.php → facebook-server-async-task.php} RENAMED
@@ -5,7 +5,7 @@ namespace PixelYourSite;
5
  defined('ABSPATH') or die('Direct access not allowed');
6
 
7
 
8
- class PYSServerEventAsyncTask extends \WP_Async_Task {
9
  protected $action = 'pys_send_server_event';
10
 
11
  protected function prepare_data($data) {
@@ -23,13 +23,14 @@ class PYSServerEventAsyncTask extends \WP_Async_Task {
23
  protected function run_action() {
24
  try {
25
  $data = unserialize(base64_decode($_POST['data']));
 
26
  $events = is_array($data[0]) ? $data[0] : $data ;
27
  if (empty($events)) {
28
  return;
29
  }
30
 
31
  foreach ($events as $event) {
32
- Facebook::sendServerRequest([$event]);
33
  }
34
 
35
  }
5
  defined('ABSPATH') or die('Direct access not allowed');
6
 
7
 
8
+ class FacebookAsyncTask extends \WP_Async_Task {
9
  protected $action = 'pys_send_server_event';
10
 
11
  protected function prepare_data($data) {
23
  protected function run_action() {
24
  try {
25
  $data = unserialize(base64_decode($_POST['data']));
26
+
27
  $events = is_array($data[0]) ? $data[0] : $data ;
28
  if (empty($events)) {
29
  return;
30
  }
31
 
32
  foreach ($events as $event) {
33
+ FacebookServer()->sendEvent($event["pixelIds"],[$event["event"]]);
34
  }
35
 
36
  }
modules/facebook/facebook-server.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace PixelYourSite;
3
+
4
+ if ( ! defined( 'ABSPATH' ) ) {
5
+ exit; // Exit if accessed directly.
6
+ }
7
+ /*
8
+ * @see https://github.com/facebook/facebook-php-business-sdk
9
+ * This class use for sending facebook server events
10
+ */
11
+
12
+ 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 FacebookAds\Api;
16
+ use FacebookAds\Object\ServerSide\EventRequest;
17
+ use FacebookAds\Object\ServerSide\Event;
18
+ use FacebookAds\Object\ServerSide\CustomData;
19
+ use FacebookAds\Object\ServerSide\Content;
20
+
21
+ class FacebookServer {
22
+
23
+ private static $_instance;
24
+ private $isEnabled;
25
+ private $hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
26
+ '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
27
+ '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
28
+ ];
29
+ private $access_token;
30
+ private $testCode;
31
+ private $isDebug;
32
+
33
+ public static function instance() {
34
+
35
+ if ( is_null( self::$_instance ) ) {
36
+ self::$_instance = new self();
37
+ }
38
+
39
+ return self::$_instance;
40
+
41
+ }
42
+
43
+
44
+ public function __construct() {
45
+
46
+ $this->isEnabled = Facebook()->enabled() && Facebook()->isServerApiEnabled();
47
+ $this->isDebug = PYS()->getOption( 'debug_enabled' );
48
+
49
+ if($this->isEnabled) {
50
+ add_action( 'wp_ajax_pys_api_event',array($this,"catchAjaxEvent"));
51
+ add_action( 'wp_ajax_nopriv_pys_api_event', array($this,"catchAjaxEvent"));
52
+
53
+ // initialize the s2s event async task
54
+ new FacebookAsyncTask();
55
+ }
56
+ }
57
+
58
+
59
+
60
+ /**
61
+ * Send this events by FacebookAsyncTask
62
+ * @param array $event List of raw event data
63
+ */
64
+ public function addAsyncEvents($events) {
65
+ do_action('pys_send_server_event', $events);
66
+ }
67
+
68
+ /*
69
+ * If server message is blocked by gprg or it dynamic
70
+ * we send data by ajax request from js and send the same data like browser event
71
+ */
72
+ function catchAjaxEvent() {
73
+
74
+ $event = $_POST['event'];
75
+ $data = isset($_POST['data']) ? $_POST['data'] : array();
76
+ $ids = $_POST['ids'];
77
+ $eventID = $_POST['eventID'];
78
+
79
+ if($event == "hCR") $event="CompleteRegistration"; // de mask completer registration event if it was hidden
80
+
81
+ if(isset($data['content_ids'])) {
82
+ $content_ids = json_decode(stripslashes($data['content_ids']));
83
+ $data['content_ids']=$content_ids;
84
+ }
85
+
86
+ if(isset($data['contents'])) {
87
+ if(is_array($data['contents'])) {
88
+ $contents = json_decode(json_encode($data['contents']));
89
+ } else {
90
+ $contents = json_decode(stripslashes($data['contents']));
91
+ }
92
+
93
+ $data['contents']=$contents;
94
+ }
95
+
96
+ $event = $this->createEvent($eventID,$event,$data);
97
+ if($event) {
98
+ $this->sendEvent($ids,array($event));
99
+ }
100
+ wp_die();
101
+ }
102
+
103
+
104
+ /**
105
+ * We prepare data from event for browser and create Facebook server event object
106
+ * @param String $name Event name
107
+ * @param $data Data for event
108
+ * @return bool|\FacebookAds\Object\ServerSide\Event
109
+ */
110
+ function createEvent($eventID,$name, $data) {
111
+
112
+ if(!$eventID) return false;
113
+
114
+ // create Server event
115
+ $event = ServerEventHelper::newEvent($name,$eventID);
116
+
117
+ $event->setEventTime(time());
118
+
119
+ // prepare data
120
+ if(isset($data['contents']) && is_array($data['contents'])) {
121
+ $contents = array();
122
+ foreach ($data['contents'] as $c) {
123
+ $content = array();
124
+ $content['product_id'] = $c->id;
125
+ $content['quantity'] = $c->quantity;
126
+ $content['item_price'] = $c->item_price;
127
+ $contents[] = new Content($content);
128
+ }
129
+ $data['contents'] = $contents;
130
+ } else {
131
+ $data['contents'] = array();
132
+ }
133
+
134
+ // prepare custom data
135
+ $customData = new CustomData($data);
136
+ $customProperties = getCommonEventParams();
137
+ $customProperties['event_day'] = date("l");
138
+ $customProperties['event_month'] = date("F");
139
+ $customProperties['event_hour'] = $this->hours[date("G")];
140
+ if(PYS()->getOption( 'track_traffic_source' ))
141
+ $customProperties['traffic_source'] = $this->getTrafficSource();
142
+
143
+
144
+ if(PYS()->getOption( 'track_utms' )) {
145
+ $customProperties = array_merge($customProperties,$this->getUtms());
146
+ }
147
+
148
+ if( isset($data['tags']) ) {
149
+ $customProperties['tags'] = $data['tags'];
150
+ }
151
+ $customData->setCustomProperties($customProperties);
152
+ if(isset($data['category_name'])) {
153
+ $customData->setContentCategory($data['category_name']);
154
+ }
155
+
156
+ $event->setCustomData($customData);
157
+
158
+ return $event;
159
+ }
160
+ function getUtms () {
161
+ $utm = array();
162
+
163
+ $utmTerms = ['utm_source', 'utm_media', 'utm_campaign', 'utm_term', 'utm_content'];
164
+ foreach ($utmTerms as $utmTerm) {
165
+ if(isset($_GET[$utmTerm])) {
166
+ $utm[$utmTerm] = filterEmails($_GET[$utmTerm]);
167
+ } elseif (isset($_COOKIE["pys_".$utmTerm])) {
168
+ $utm[$utmTerm] =filterEmails( $_COOKIE["pys_".$utmTerm]);
169
+ } else {
170
+ $utm[$utmTerm] = "undefined";
171
+ }
172
+ }
173
+
174
+ return $utm;
175
+ }
176
+
177
+ /**
178
+ * Send event for each pixel id
179
+ * @param array $pixel_Ids array of facebook ids
180
+ * @param array $events One Facebook event object
181
+ */
182
+ function sendEvent($pixel_Ids, $events) {
183
+
184
+ if (empty($events)) {
185
+ return;
186
+ }
187
+
188
+ if(!$this->access_token) {
189
+ $this->access_token = Facebook()->getApiToken();
190
+ $this->testCode = Facebook()->getApiTestCode();
191
+ }
192
+
193
+ foreach($pixel_Ids as $pixel_Id) {
194
+
195
+ if(empty($this->access_token[$pixel_Id])) continue;
196
+
197
+ $api = Api::init(null, null, $this->access_token[$pixel_Id]);
198
+
199
+ $request = (new EventRequest($pixel_Id))->setEvents($events);
200
+ $request->setPartnerAgent("dvpixelyoursite");
201
+ if(!empty($this->testCode[$pixel_Id]))
202
+ $request->setTestEventCode($this->testCode[$pixel_Id]);
203
+
204
+ if($this->isDebug)
205
+ error_log("send fb api request ".print_r($request,true));
206
+
207
+ try{
208
+ $response = $request->execute();
209
+ } catch (\Exception $e) {
210
+ error_log("error send Fb API request ".$e->getMessage());
211
+ }
212
+
213
+ if($this->isDebug && isset($response)) error_log("fb api response ".print_r($response,true));
214
+ }
215
+ }
216
+
217
+ function getTrafficSource () {
218
+ $referrer = "";
219
+ $source = "";
220
+ try {
221
+ if (isset($_SERVER['HTTP_REFERER'])) {
222
+ $referrer = $_SERVER['HTTP_REFERER'];
223
+ }
224
+
225
+ $direct = empty($referrer);
226
+ $internal = $direct ? false : strpos(site_url(), $referrer) == 0;
227
+ $external = !$direct && !$internal;
228
+ $cookie = !isset($_COOKIE['pysTrafficSource']) ? false : $_COOKIE['pysTrafficSource'];
229
+
230
+ if (!$external) {
231
+ $source = $cookie ? $cookie : 'direct';
232
+ } else {
233
+ $source = $cookie && $cookie === $referrer ? $cookie : $referrer;
234
+ }
235
+
236
+ if ($source !== 'direct') {
237
+ $parse = parse_url($source);
238
+
239
+ // leave only domain (Issue #70)
240
+ return $parse['host'];
241
+
242
+ } else {
243
+ return $source;
244
+ }
245
+ } catch (\Exception $e) {
246
+ return "direct";
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * @return FacebookServer
253
+ */
254
+ function FacebookServer() {
255
+ return FacebookServer::instance();
256
+ }
257
+
258
+ FacebookServer();
259
+
260
+
261
+
262
+
263
+
modules/facebook/facebook.php CHANGED
@@ -9,8 +9,8 @@ if ( ! defined( 'ABSPATH' ) ) {
9
  /** @noinspection PhpIncludeInspection */
10
  require_once PYS_FREE_PATH . '/modules/facebook/function-helpers.php';
11
  require_once PYS_FREE_PATH . '/modules/facebook/FDPEvent.php';
12
- require_once PYS_FREE_PATH . '/modules/facebook/PYSServerEventAsyncTask.php';
13
- require_once PYS_FREE_PATH . '/modules/facebook/PYSServerEventHelper.php';
14
 
15
  use PixelYourSite\Facebook\Helpers;
16
  use FacebookAds\Api;
@@ -45,10 +45,6 @@ class Facebook extends Settings implements Pixel {
45
  /** @var PYS $core */
46
  $core->registerPixel( $this );
47
  } );
48
-
49
- // initialize the s2s event async task
50
- new PYSServerEventAsyncTask();
51
-
52
  }
53
 
54
  public function enabled() {
@@ -89,6 +85,7 @@ class Facebook extends Settings implements Pixel {
89
  'wooVariableAsSimple' => $this->getOption( 'woo_variable_as_simple' ),
90
  'downloadEnabled' => $this->getOption( 'download_event_enabled' ),
91
  'formEventEnabled' => $this->getOption( 'form_event_enabled' ),
 
92
  'serverApiEnabled' => $this->isServerApiEnabled() && count($this->getApiToken()) > 0,
93
  'wooCRSendFromServer' => $this->getOption("woo_complete_registration_send_from_server") && $this->getOption("woo_complete_registration_fire_every_time")
94
  );
@@ -100,74 +97,83 @@ class Facebook extends Settings implements Pixel {
100
  if ( ! $this->configured() ) {
101
  return false;
102
  }
 
103
 
104
  switch ( $eventType ) {
105
  case 'init_event':
106
- return $this->getPageViewEventParams();
107
 
108
  case 'general_event':
109
- return $this->getGeneralEventParams();
110
 
111
  case 'search_event':
112
- return $this->getSearchEventParams();
113
 
114
  case 'custom_event':
115
- return $this->getCustomEventParams( $args );
116
 
117
  case 'fdp_event':
118
- return $this->getFDPEventParams( $args );
119
 
120
  case 'woo_view_content':
121
- return $this->getWooViewContentEventParams();
122
 
123
  case 'woo_add_to_cart_on_button_click':
124
- return $this->getWooAddToCartOnButtonClickEventParams( $args );
125
 
126
  case 'woo_add_to_cart_on_cart_page':
127
  case 'woo_add_to_cart_on_checkout_page':
128
- return $this->getWooAddToCartOnCartEventParams();
129
 
130
  case 'woo_remove_from_cart':
131
- return $this->getWooRemoveFromCartParams( $args );
132
 
133
  case 'woo_view_category':
134
- return $this->getWooViewCategoryEventParams();
135
 
136
  case 'woo_initiate_checkout':
137
- return $this->getWooInitiateCheckoutEventParams();
138
 
139
  case 'woo_purchase':
140
- return $this->getWooPurchaseEventParams();
141
 
142
  case 'edd_view_content':
143
- return $this->getEddViewContentEventParams();
144
 
145
  case 'edd_add_to_cart_on_button_click':
146
- return $this->getEddAddToCartOnButtonClickEventParams( $args );
147
 
148
  case 'edd_add_to_cart_on_checkout_page':
149
- return $this->getEddCartEventParams( 'AddToCart' );
150
 
151
  case 'edd_remove_from_cart':
152
- return $this->getEddRemoveFromCartParams( $args );
153
 
154
  case 'edd_view_category':
155
- return $this->getEddViewCategoryEventParams();
156
 
157
  case 'edd_initiate_checkout':
158
- return $this->getEddCartEventParams( 'InitiateCheckout' );
159
 
160
  case 'edd_purchase':
161
- return $this->getEddCartEventParams( 'Purchase' );
 
162
  case 'hCR':
163
- return $this->getCompleteRegistrationEventParams('hCR');
 
164
  case 'complete_registration':
165
- return $this->getCompleteRegistrationEventParams();
166
 
167
- default:
168
- return false; // event does not supported
169
  }
170
-
 
 
 
 
 
 
 
171
  }
172
 
173
  public function outputNoScriptEvents() {
@@ -207,9 +213,6 @@ class Facebook extends Settings implements Pixel {
207
 
208
  private function getPageViewEventParams() {
209
  $data = array();
210
- if($this->isServerApiEnabled()) {
211
- $data['eventID'] = "pv_".time();
212
- }
213
  return array(
214
  'name' => 'PageView',
215
  'data' => $data,
@@ -402,10 +405,10 @@ class Facebook extends Settings implements Pixel {
402
 
403
 
404
  $params['value'] = getWooEventValue( $value_option, $global_value,100, $post->ID ,1);
405
-
406
 
407
  }
408
- $params['currency'] = get_woocommerce_currency();
409
  // contents
410
  if ( Helpers\isDefaultWooContentIdLogic() ) {
411
 
@@ -414,14 +417,12 @@ class Facebook extends Settings implements Pixel {
414
  array(
415
  'id' => (string) reset( $content_id ),
416
  'quantity' => 1,
417
- 'item_price' => getWooProductPriceToDisplay( $post->ID ),
418
  )
419
  ) );
420
 
421
  }
422
- if($this->isServerApiEnabled()) {
423
- $params['eventID'] = $post->ID."_".time();
424
- }
425
 
426
  $params['product_price'] = getWooProductPriceToDisplay( $post->ID );
427
 
@@ -454,9 +455,6 @@ class Facebook extends Settings implements Pixel {
454
  }
455
 
456
  $params = Helpers\getWooCartParams();
457
- if($this->isServerApiEnabled()) {
458
- $params['eventID'] = "add_cart_".time();
459
- }
460
 
461
  return array(
462
  'name' => 'AddToCart',
@@ -488,7 +486,7 @@ class Facebook extends Settings implements Pixel {
488
  array(
489
  'id' => (string) reset( $content_id ),
490
  'quantity' => $cart_item['quantity'],
491
- 'item_price' => getWooProductPriceToDisplay( $product_id ),
492
  )
493
  ) );
494
 
@@ -550,9 +548,7 @@ class Facebook extends Settings implements Pixel {
550
  }
551
 
552
  $params = Helpers\getWooCartParams( 'InitiateCheckout' );
553
- if($this->isServerApiEnabled()) {
554
- $params['eventID'] = "init_check_".time();
555
- }
556
 
557
  return array(
558
  'name' => 'InitiateCheckout',
@@ -635,9 +631,6 @@ class Facebook extends Settings implements Pixel {
635
  $params['currency'] = get_woocommerce_currency();
636
  //$params['transaction_id'] = $order_id;
637
 
638
- if($this->isServerApiEnabled()) {
639
- $params['eventID'] = $order_id;
640
- }
641
  return array(
642
  'name' => 'Purchase',
643
  'data' => $params,
@@ -677,7 +670,7 @@ class Facebook extends Settings implements Pixel {
677
  }
678
 
679
  }
680
-
681
  return array(
682
  'name' => $customEvent->getFacebookEventType(),
683
  'data' => $params,
@@ -710,20 +703,17 @@ class Facebook extends Settings implements Pixel {
710
  $global_value = PYS()->getOption( 'edd_view_content_value_global', 0 );
711
 
712
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
713
-
714
 
715
  }
716
- $params['currency'] = edd_get_currency();
717
- if($this->isServerApiEnabled()) {
718
- $params['eventID'] = $post->ID."_".time();
719
- }
720
 
721
  // contents
722
  $params['contents'] = json_encode( array(
723
  array(
724
  'id' => (string) $post->ID,
725
  'quantity' => 1,
726
- 'item_price' => getEddDownloadPriceToDisplay( $post->ID ),
727
  )
728
  ) );
729
 
@@ -766,21 +756,18 @@ class Facebook extends Settings implements Pixel {
766
  $global_value = PYS()->getOption( 'edd_add_to_cart_value_global', 0 );
767
 
768
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
769
-
770
 
771
  }
772
- $params['currency'] = edd_get_currency();
773
  // contents
774
  $params['contents'] = json_encode( array(
775
  array(
776
  'id' => (string) $download_id,
777
  'quantity' => 1,
778
- 'item_price' => getEddDownloadPriceToDisplay( $download_id ),
779
  )
780
  ) );
781
- if($this->isServerApiEnabled()) {
782
- $params['eventID'] = $download_id."_".time();
783
- }
784
 
785
  return array(
786
  'data' => $params,
@@ -873,7 +860,7 @@ class Facebook extends Settings implements Pixel {
873
  $contents[] = array(
874
  'id' => (string) $download_id,
875
  'quantity' => $cart_item['quantity'],
876
- 'item_price' => getEddDownloadPriceToDisplay( $download_id, $price_index ),
877
  );
878
 
879
  }
@@ -890,39 +877,19 @@ class Facebook extends Settings implements Pixel {
890
 
891
  // currency, value
892
  if ( $value_enabled ) {
893
-
894
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
895
- $params['currency'] = edd_get_currency();
896
-
897
  }
898
 
899
- if($context == 'AddToCart') {
900
- if($this->isServerApiEnabled()) {
901
- $params['eventID'] = "edd_add_cart_".time();
902
- }
903
-
904
- }
905
- if($context == 'InitiateCheckout') {
906
- if($this->isServerApiEnabled()) {
907
- $params['eventID'] = "init_check_".time();
908
- }
909
- }
910
 
911
 
912
  if ( $context == 'Purchase' ) {
913
-
914
  $payment_key = getEddPaymentKey();
915
  $payment_id = (int) edd_get_purchase_id_by_key( $payment_key );
916
-
917
-
918
  $params['value'] = edd_get_payment_amount( $payment_id );
919
- if($this->isServerApiEnabled()) {
920
- $params['eventID'] = $payment_id."_".time();
921
- }
922
-
923
-
924
  }
925
- $params['currency'] = edd_get_currency();
926
  return array(
927
  'name' => $context,
928
  'data' => $params,
@@ -949,12 +916,11 @@ class Facebook extends Settings implements Pixel {
949
  $params = array_merge( $params, Helpers\getEddCustomAudiencesOptimizationParams( $download_id ) );
950
 
951
  $params['num_items'] = $cart_item['quantity'];
952
-
953
  $params['contents'] = json_encode( array(
954
  array(
955
  'id' => (string) $download_id,
956
  'quantity' => $cart_item['quantity'],
957
- 'item_price' => getEddDownloadPriceToDisplay( $download_id, $price_index ),
958
  )
959
  ) );
960
 
@@ -1005,24 +971,40 @@ class Facebook extends Settings implements Pixel {
1005
  * @return array
1006
  */
1007
  public function getApiToken() {
1008
- $ids = (array) $this->getOption( 'server_access_api_token' );
 
 
 
 
 
1009
  if ( isSuperPackActive() && SuperPack()->getOption( 'enabled' ) && SuperPack()->getOption( 'additional_ids_enabled' ) ) {
1010
- return $ids;
 
 
 
1011
  } else {
1012
- return (array) reset( $ids ); // return first id only
1013
  }
 
 
1014
  }
1015
 
1016
  /**
1017
  * @return array
1018
  */
1019
  public function getApiTestCode() {
1020
- $ids = (array) $this->getOption( 'test_api_event_code' );
 
 
1021
  if ( isSuperPackActive() && SuperPack()->getOption( 'enabled' ) && SuperPack()->getOption( 'additional_ids_enabled' ) ) {
1022
- return $ids;
 
 
 
1023
  } else {
1024
- return (array) reset( $ids ); // return first id only
1025
  }
 
1026
  }
1027
 
1028
  /**
@@ -1032,42 +1014,7 @@ class Facebook extends Settings implements Pixel {
1032
  return $this->getOption("use_server_api");
1033
  }
1034
 
1035
- public function trackEventByServerApi($event) {
1036
- do_action('pys_send_server_event', $event);
1037
- }
1038
-
1039
- public static function sendServerRequest($events) {
1040
- if (empty($events)) {
1041
- return;
1042
- }
1043
- $access_token = Facebook::instance()->getApiToken();
1044
- $testCode = Facebook::instance()->getApiTestCode();
1045
- $isDebug = PYS()->getOption( 'debug_enabled' );
1046
- $pixel_Ids = Facebook::instance()->getPixelIDs();
1047
-
1048
- $count = count($pixel_Ids);
1049
- for($i=0; $i<$count; $i++) {
1050
-
1051
- if(empty($access_token[$i])) continue;
1052
-
1053
- $api = Api::init(null, null, $access_token[$i]);
1054
 
1055
- $request = (new EventRequest($pixel_Ids[$i]))->setEvents($events);
1056
- $request->setPartnerAgent("dvpixelyoursite");
1057
- if(!empty($testCode[$i])) $request->setTestEventCode($testCode[$i]);
1058
-
1059
- if($isDebug) error_log("send fb api request ".print_r($request,true));
1060
-
1061
- try{
1062
- $response = $request->execute();
1063
- } catch (\Exception $e) {
1064
- error_log("error send Fb API request ".$e->getMessage());
1065
-
1066
- }
1067
-
1068
- if($isDebug && isset($response)) error_log("fb api response ".print_r($response,true));
1069
- }
1070
- }
1071
 
1072
  private function getCompleteRegistrationEventParams($args=null) {
1073
 
@@ -1080,9 +1027,10 @@ class Facebook extends Settings implements Pixel {
1080
  isset( $_REQUEST['key'] ) ) {
1081
  $params = Helpers\getCompleteRegistrationOrderParams();
1082
  }
 
1083
 
1084
  return $params = array(
1085
- 'name' => isset($args) && $args == "hCR" ? "hCR" : 'CompleteRegistration',
1086
  'data' => $params,
1087
  );
1088
 
9
  /** @noinspection PhpIncludeInspection */
10
  require_once PYS_FREE_PATH . '/modules/facebook/function-helpers.php';
11
  require_once PYS_FREE_PATH . '/modules/facebook/FDPEvent.php';
12
+
13
+
14
 
15
  use PixelYourSite\Facebook\Helpers;
16
  use FacebookAds\Api;
45
  /** @var PYS $core */
46
  $core->registerPixel( $this );
47
  } );
 
 
 
 
48
  }
49
 
50
  public function enabled() {
85
  'wooVariableAsSimple' => $this->getOption( 'woo_variable_as_simple' ),
86
  'downloadEnabled' => $this->getOption( 'download_event_enabled' ),
87
  'formEventEnabled' => $this->getOption( 'form_event_enabled' ),
88
+ "ajaxForServerEvent" => $this->getOption( "server_event_use_ajax" ),
89
  'serverApiEnabled' => $this->isServerApiEnabled() && count($this->getApiToken()) > 0,
90
  'wooCRSendFromServer' => $this->getOption("woo_complete_registration_send_from_server") && $this->getOption("woo_complete_registration_fire_every_time")
91
  );
97
  if ( ! $this->configured() ) {
98
  return false;
99
  }
100
+ $eventData = false;
101
 
102
  switch ( $eventType ) {
103
  case 'init_event':
104
+ $eventData = $this->getPageViewEventParams(); break;
105
 
106
  case 'general_event':
107
+ $eventData = $this->getGeneralEventParams(); break;
108
 
109
  case 'search_event':
110
+ $eventData = $this->getSearchEventParams(); break;
111
 
112
  case 'custom_event':
113
+ $eventData = $this->getCustomEventParams( $args ); break;
114
 
115
  case 'fdp_event':
116
+ $eventData = $this->getFDPEventParams( $args ); break;
117
 
118
  case 'woo_view_content':
119
+ $eventData = $this->getWooViewContentEventParams(); break;
120
 
121
  case 'woo_add_to_cart_on_button_click':
122
+ $eventData = $this->getWooAddToCartOnButtonClickEventParams( $args ); break;
123
 
124
  case 'woo_add_to_cart_on_cart_page':
125
  case 'woo_add_to_cart_on_checkout_page':
126
+ $eventData = $this->getWooAddToCartOnCartEventParams(); break;
127
 
128
  case 'woo_remove_from_cart':
129
+ $eventData = $this->getWooRemoveFromCartParams( $args ); break;
130
 
131
  case 'woo_view_category':
132
+ $eventData = $this->getWooViewCategoryEventParams(); break;
133
 
134
  case 'woo_initiate_checkout':
135
+ $eventData = $this->getWooInitiateCheckoutEventParams(); break;
136
 
137
  case 'woo_purchase':
138
+ $eventData = $this->getWooPurchaseEventParams(); break;
139
 
140
  case 'edd_view_content':
141
+ $eventData = $this->getEddViewContentEventParams(); break;
142
 
143
  case 'edd_add_to_cart_on_button_click':
144
+ $eventData = $this->getEddAddToCartOnButtonClickEventParams( $args ); break;
145
 
146
  case 'edd_add_to_cart_on_checkout_page':
147
+ $eventData = $this->getEddCartEventParams( 'AddToCart' ); break;
148
 
149
  case 'edd_remove_from_cart':
150
+ $eventData = $this->getEddRemoveFromCartParams( $args ); break;
151
 
152
  case 'edd_view_category':
153
+ $eventData = $this->getEddViewCategoryEventParams(); break;
154
 
155
  case 'edd_initiate_checkout':
156
+ $eventData = $this->getEddCartEventParams( 'InitiateCheckout' ); break;
157
 
158
  case 'edd_purchase':
159
+ $eventData = $this->getEddCartEventParams( 'Purchase' ); break;
160
+
161
  case 'hCR':
162
+ $eventData = $this->getCompleteRegistrationEventParams('hCR'); break;
163
+
164
  case 'complete_registration':
165
+ $eventData = $this->getCompleteRegistrationEventParams(); break;
166
 
167
+ default: return false; // event does not supported
 
168
  }
169
+
170
+ if($eventData) {
171
+ if($this->isServerApiEnabled()) {
172
+ $eventData['eventID'] = EventIdGenerator::guidv4();
173
+ }
174
+ }
175
+
176
+ return $eventData;
177
  }
178
 
179
  public function outputNoScriptEvents() {
213
 
214
  private function getPageViewEventParams() {
215
  $data = array();
 
 
 
216
  return array(
217
  'name' => 'PageView',
218
  'data' => $data,
405
 
406
 
407
  $params['value'] = getWooEventValue( $value_option, $global_value,100, $post->ID ,1);
408
+ $params['currency'] = get_woocommerce_currency();
409
 
410
  }
411
+
412
  // contents
413
  if ( Helpers\isDefaultWooContentIdLogic() ) {
414
 
417
  array(
418
  'id' => (string) reset( $content_id ),
419
  'quantity' => 1,
420
+ //'item_price' => getWooProductPriceToDisplay( $post->ID ),
421
  )
422
  ) );
423
 
424
  }
425
+
 
 
426
 
427
  $params['product_price'] = getWooProductPriceToDisplay( $post->ID );
428
 
455
  }
456
 
457
  $params = Helpers\getWooCartParams();
 
 
 
458
 
459
  return array(
460
  'name' => 'AddToCart',
486
  array(
487
  'id' => (string) reset( $content_id ),
488
  'quantity' => $cart_item['quantity'],
489
+ //'item_price' => getWooProductPriceToDisplay( $product_id ),
490
  )
491
  ) );
492
 
548
  }
549
 
550
  $params = Helpers\getWooCartParams( 'InitiateCheckout' );
551
+
 
 
552
 
553
  return array(
554
  'name' => 'InitiateCheckout',
631
  $params['currency'] = get_woocommerce_currency();
632
  //$params['transaction_id'] = $order_id;
633
 
 
 
 
634
  return array(
635
  'name' => 'Purchase',
636
  'data' => $params,
670
  }
671
 
672
  }
673
+
674
  return array(
675
  'name' => $customEvent->getFacebookEventType(),
676
  'data' => $params,
703
  $global_value = PYS()->getOption( 'edd_view_content_value_global', 0 );
704
 
705
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
706
+ $params['currency'] = edd_get_currency();
707
 
708
  }
709
+
 
 
 
710
 
711
  // contents
712
  $params['contents'] = json_encode( array(
713
  array(
714
  'id' => (string) $post->ID,
715
  'quantity' => 1,
716
+ //'item_price' => getEddDownloadPriceToDisplay( $post->ID ),
717
  )
718
  ) );
719
 
756
  $global_value = PYS()->getOption( 'edd_add_to_cart_value_global', 0 );
757
 
758
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
759
+ $params['currency'] = edd_get_currency();
760
 
761
  }
762
+
763
  // contents
764
  $params['contents'] = json_encode( array(
765
  array(
766
  'id' => (string) $download_id,
767
  'quantity' => 1,
768
+ //'item_price' => getEddDownloadPriceToDisplay( $download_id ),
769
  )
770
  ) );
 
 
 
771
 
772
  return array(
773
  'data' => $params,
860
  $contents[] = array(
861
  'id' => (string) $download_id,
862
  'quantity' => $cart_item['quantity'],
863
+ //'item_price' => getEddDownloadPriceToDisplay( $download_id, $price_index ),
864
  );
865
 
866
  }
877
 
878
  // currency, value
879
  if ( $value_enabled ) {
880
+ $params['currency'] = edd_get_currency();
881
  $params['value'] = getEddEventValue( $value_option, $amount, $global_value );
 
 
882
  }
883
 
 
 
 
 
 
 
 
 
 
 
 
884
 
885
 
886
  if ( $context == 'Purchase' ) {
 
887
  $payment_key = getEddPaymentKey();
888
  $payment_id = (int) edd_get_purchase_id_by_key( $payment_key );
 
 
889
  $params['value'] = edd_get_payment_amount( $payment_id );
890
+ $params['currency'] = edd_get_currency();
 
 
 
 
891
  }
892
+
893
  return array(
894
  'name' => $context,
895
  'data' => $params,
916
  $params = array_merge( $params, Helpers\getEddCustomAudiencesOptimizationParams( $download_id ) );
917
 
918
  $params['num_items'] = $cart_item['quantity'];
 
919
  $params['contents'] = json_encode( array(
920
  array(
921
  'id' => (string) $download_id,
922
  'quantity' => $cart_item['quantity'],
923
+ //'item_price' => getEddDownloadPriceToDisplay( $download_id, $price_index ),
924
  )
925
  ) );
926
 
971
  * @return array
972
  */
973
  public function getApiToken() {
974
+ $tokens = array();
975
+ $pixelids = (array) $this->getOption( 'pixel_id' );
976
+ $serverids = (array) $this->getOption( 'server_access_api_token' );
977
+
978
+ if(count($pixelids) == 0) return array();
979
+
980
  if ( isSuperPackActive() && SuperPack()->getOption( 'enabled' ) && SuperPack()->getOption( 'additional_ids_enabled' ) ) {
981
+ foreach ($pixelids as $key => $val) {
982
+ if(isset($serverids[$key]))
983
+ $tokens[$val] = $serverids[$key];
984
+ }
985
  } else {
986
+ $tokens[$pixelids[0]] = reset( $serverids ); // return first id only
987
  }
988
+
989
+ return $tokens;
990
  }
991
 
992
  /**
993
  * @return array
994
  */
995
  public function getApiTestCode() {
996
+ $testCode = array();
997
+ $pixelids = (array) $this->getOption( 'pixel_id' );
998
+ $serverTestCode = (array) $this->getOption( 'test_api_event_code' );
999
  if ( isSuperPackActive() && SuperPack()->getOption( 'enabled' ) && SuperPack()->getOption( 'additional_ids_enabled' ) ) {
1000
+ foreach ($pixelids as $key => $val) {
1001
+ if(isset($serverTestCode[$key]))
1002
+ $testCode[$val] = $serverTestCode[$key];
1003
+ }
1004
  } else {
1005
+ $testCode[$pixelids[0]] = reset( $serverTestCode ); // return first id only
1006
  }
1007
+ return $testCode;
1008
  }
1009
 
1010
  /**
1014
  return $this->getOption("use_server_api");
1015
  }
1016
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1018
 
1019
  private function getCompleteRegistrationEventParams($args=null) {
1020
 
1027
  isset( $_REQUEST['key'] ) ) {
1028
  $params = Helpers\getCompleteRegistrationOrderParams();
1029
  }
1030
+ $name = isset($args) && $args == "hCR" ? "hCR" : 'CompleteRegistration';
1031
 
1032
  return $params = array(
1033
+ 'name' => $name,
1034
  'data' => $params,
1035
  );
1036
 
modules/facebook/function-helpers.php CHANGED
@@ -296,13 +296,10 @@ function getWooSingleAddToCartParams( $product_id, $qty = 1 ) {
296
  $global_value = PixelYourSite\PYS()->getOption( 'woo_add_to_cart_value_global', 0 );
297
 
298
  $params['value'] = PixelYourSite\getWooEventValue( $value_option, $global_value,100, $product_id,$qty );
299
-
300
 
301
  }
302
- $params['currency'] = get_woocommerce_currency();
303
- if(PixelYourSite\Facebook()->isServerApiEnabled()) {
304
- $params['eventID'] = (string) $product_id."_".time();
305
- }
306
 
307
  // contents
308
  if ( isDefaultWooContentIdLogic() ) {
@@ -312,7 +309,7 @@ function getWooSingleAddToCartParams( $product_id, $qty = 1 ) {
312
  array(
313
  'id' => (string) reset( $content_id ),
314
  'quantity' => 1,
315
- 'item_price' => PixelYourSite\getWooProductPriceToDisplay( $product_id ),
316
  )
317
  );
318
 
@@ -355,7 +352,7 @@ function getWooCartParams( $context = 'cart' ) {
355
  $contents[] = array(
356
  'id' => (string) reset( $content_id ),
357
  'quantity' => $cart_item['quantity'],
358
- 'item_price' => PixelYourSite\getWooProductPriceToDisplay( $_product_id ),
359
  );
360
 
361
  }
@@ -400,10 +397,10 @@ function getWooCartParams( $context = 'cart' ) {
400
  $global_value = PixelYourSite\PYS()->getOption( $value_global_option, 0 );
401
 
402
  $params['value'] = PixelYourSite\getWooEventValueCart( $value_option, $global_value );
403
-
404
 
405
  }
406
- $params['currency'] = get_woocommerce_currency();
407
  return $params;
408
 
409
  }
@@ -563,15 +560,10 @@ function getCompleteRegistrationOrderParams() {
563
  $order_id = (int) wc_get_order_id_by_order_key( $order_key );
564
  $order = new \WC_Order( $order_id );
565
 
566
-
567
  $value_option = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_custom_value' );
568
  $global_value = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_global_value', 0 );
569
  $percents_value = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_percent_value', 100 );
570
 
571
- if(PixelYourSite\Facebook()->isServerApiEnabled()) {
572
- $params['eventID'] = $order_id."_".time();
573
- }
574
-
575
  $params['value'] = PixelYourSite\getWooEventValueOrder( $value_option, $order, $global_value, $percents_value );
576
  $params['currency'] = get_woocommerce_currency();
577
  return $params;
296
  $global_value = PixelYourSite\PYS()->getOption( 'woo_add_to_cart_value_global', 0 );
297
 
298
  $params['value'] = PixelYourSite\getWooEventValue( $value_option, $global_value,100, $product_id,$qty );
299
+ $params['currency'] = get_woocommerce_currency();
300
 
301
  }
302
+
 
 
 
303
 
304
  // contents
305
  if ( isDefaultWooContentIdLogic() ) {
309
  array(
310
  'id' => (string) reset( $content_id ),
311
  'quantity' => 1,
312
+ //'item_price' => PixelYourSite\getWooProductPriceToDisplay( $product_id ),
313
  )
314
  );
315
 
352
  $contents[] = array(
353
  'id' => (string) reset( $content_id ),
354
  'quantity' => $cart_item['quantity'],
355
+ //'item_price' => PixelYourSite\getWooProductPriceToDisplay( $_product_id ),
356
  );
357
 
358
  }
397
  $global_value = PixelYourSite\PYS()->getOption( $value_global_option, 0 );
398
 
399
  $params['value'] = PixelYourSite\getWooEventValueCart( $value_option, $global_value );
400
+ $params['currency'] = get_woocommerce_currency();
401
 
402
  }
403
+
404
  return $params;
405
 
406
  }
560
  $order_id = (int) wc_get_order_id_by_order_key( $order_key );
561
  $order = new \WC_Order( $order_id );
562
 
 
563
  $value_option = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_custom_value' );
564
  $global_value = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_global_value', 0 );
565
  $percents_value = PixelYourSite\Facebook()->getOption( 'woo_complete_registration_percent_value', 100 );
566
 
 
 
 
 
567
  $params['value'] = PixelYourSite\getWooEventValueOrder( $value_option, $order, $global_value, $percents_value );
568
  $params['currency'] = get_woocommerce_currency();
569
  return $params;
modules/facebook/options_defaults.json CHANGED
@@ -50,6 +50,7 @@
50
  "fdp_purchase_value" : "0",
51
 
52
  "use_server_api": false,
 
53
  "server_access_api_token": "",
54
  "test_api_event_code": "",
55
 
50
  "fdp_purchase_value" : "0",
51
 
52
  "use_server_api": false,
53
+ "server_event_use_ajax": true,
54
  "server_access_api_token": "",
55
  "test_api_event_code": "",
56
 
modules/facebook/options_fields.json CHANGED
@@ -49,6 +49,7 @@
49
  "fdp_purchase_value" : "text",
50
 
51
  "use_server_api": "checkbox",
 
52
  "server_access_api_token": "array",
53
  "test_api_event_code": "array",
54
 
49
  "fdp_purchase_value" : "text",
50
 
51
  "use_server_api": "checkbox",
52
+ "server_event_use_ajax": "checkbox",
53
  "server_access_api_token": "array",
54
  "test_api_event_code": "array",
55
 
pixelyoursite.php CHANGED
@@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
- define( 'PYS_FREE_VERSION', '7.1.14' );
8
  define( 'PYS_FREE_PINTEREST_MIN_VERSION', '2.0.6' );
9
  define( 'PYS_FREE_BING_MIN_VERSION', '1.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/functions-common.php';
22
  require_once PYS_FREE_PATH.'/includes/functions-admin.php';
23
  require_once PYS_FREE_PATH.'/includes/functions-custom-event.php';
@@ -39,6 +40,7 @@ require_once PYS_FREE_PATH.'/includes/class-events-manager.php';
39
  require_once PYS_FREE_PATH.'/includes/class-custom-event.php';
40
  require_once PYS_FREE_PATH.'/includes/class-custom-event-factory.php';
41
  require_once PYS_FREE_PATH.'/modules/facebook/facebook.php';
 
42
  require_once PYS_FREE_PATH.'/modules/google_analytics/ga.php';
43
  require_once PYS_FREE_PATH.'/modules/head_footer/head_footer.php';
44
 
4
  exit; // Exit if accessed directly.
5
  }
6
 
7
+ define( 'PYS_FREE_VERSION', '7.2.0' );
8
  define( 'PYS_FREE_PINTEREST_MIN_VERSION', '2.0.6' );
9
  define( 'PYS_FREE_BING_MIN_VERSION', '1.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/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';
24
  require_once PYS_FREE_PATH.'/includes/functions-custom-event.php';
40
  require_once PYS_FREE_PATH.'/includes/class-custom-event.php';
41
  require_once PYS_FREE_PATH.'/includes/class-custom-event-factory.php';
42
  require_once PYS_FREE_PATH.'/modules/facebook/facebook.php';
43
+ require_once PYS_FREE_PATH.'/modules/facebook/facebook-server.php';
44
  require_once PYS_FREE_PATH.'/modules/google_analytics/ga.php';
45
  require_once PYS_FREE_PATH.'/modules/head_footer/head_footer.php';
46
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: Facebook Pixel, New Facebook Pixel, Facebook Conversion Pixel, Facebook Pi
4
  Requires at least: 3.0.1
5
  Requires PHP: 5.4
6
  Tested up to: 5.5
7
- Stable tag: 7.1.14
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -391,6 +391,18 @@ NO, absolutely not! We don't track any type of data about your website. We simpl
391
  == Changelog ==
392
 
393
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  = PixelYourSite 7.1.14 =
395
 
396
  * We removed the EventID parameter when Facebook Conversion API is not configured.
4
  Requires at least: 3.0.1
5
  Requires PHP: 5.4
6
  Tested up to: 5.5
7
+ Stable tag: 7.2.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
391
  == Changelog ==
392
 
393
 
394
+ = PixelYourSite 7.2.0 =
395
+
396
+
397
+ * NEW: Facebook Conversion API works for all the pixel events.
398
+
399
+ * Ajax option for the Facebook Pixel when Conversion API is enabled. This helps to avoid problems with caches. You can learn more about these problems from [this video](https://www.youtube.com/watch?v=YH6ve7qj1hw)
400
+
401
+ * ViewContent, AddToCart, InitiateCheckout events related to WooCommerce have value turned ON by default. The reasons are explained in [this video](https://www.youtube.com/watch?v=neH2Hc6xXUU)
402
+
403
+ * Samll change to the contents parameter for some Facebook Pixel events that had the potential to trigger a warning related to currency or value.
404
+
405
+
406
  = PixelYourSite 7.1.14 =
407
 
408
  * We removed the EventID parameter when Facebook Conversion API is not configured.