Official Facebook Pixel - Version 3.0.0

Version Description

Download this release

Release Info

Developer Facebook
Plugin Icon Official Facebook Pixel
Version 3.0.0
Comparing to
See all releases

Code changes from version 2.2.2 to 3.0.0

Files changed (45) hide show
  1. changelog.txt +4 -0
  2. core/AAMFieldsExtractor.php +84 -0
  3. core/AAMSettingsFields.php +46 -0
  4. core/FacebookPluginConfig.php +21 -8
  5. core/FacebookServerSideEvent.php +19 -13
  6. core/FacebookWordpressOptions.php +168 -50
  7. core/FacebookWordpressPixelInjection.php +8 -10
  8. core/FacebookWordpressSettingsPage.php +125 -256
  9. core/FacebookWordpressSettingsRecorder.php +60 -0
  10. core/ServerEventAsyncTask.php +99 -8
  11. core/ServerEventFactory.php +130 -46
  12. facebook-for-wordpress.php +4 -2
  13. integration/FacebookWordpressEasyDigitalDownloads.php +1 -2
  14. js/fbe_allinone.js +21734 -0
  15. languages/official-facebook-pixel-ar_AR.po +3 -3
  16. languages/official-facebook-pixel-cs_CZ.po +3 -3
  17. languages/official-facebook-pixel-da_DK.po +3 -3
  18. languages/official-facebook-pixel-de_DE.po +3 -3
  19. languages/official-facebook-pixel-en_GB.po +3 -3
  20. languages/official-facebook-pixel-es_ES.po +3 -3
  21. languages/official-facebook-pixel-es_LA.po +3 -3
  22. languages/official-facebook-pixel-fi_FI.po +3 -3
  23. languages/official-facebook-pixel-fr_CA.po +3 -3
  24. languages/official-facebook-pixel-fr_FR.po +3 -3
  25. languages/official-facebook-pixel-he_IL.po +3 -3
  26. languages/official-facebook-pixel-it_IT.po +3 -3
  27. languages/official-facebook-pixel-ja_JP.po +3 -3
  28. languages/official-facebook-pixel-ko_KR.po +3 -3
  29. languages/official-facebook-pixel-nb_NO.po +3 -3
  30. languages/official-facebook-pixel-nl_NL.po +3 -3
  31. languages/official-facebook-pixel-pl_PL.po +3 -3
  32. languages/official-facebook-pixel-pt_BR.po +3 -3
  33. languages/official-facebook-pixel-pt_PT.po +3 -3
  34. languages/official-facebook-pixel-ru_RU.po +3 -3
  35. languages/official-facebook-pixel-sv_SE.po +3 -3
  36. languages/official-facebook-pixel-th_TH.po +3 -3
  37. languages/official-facebook-pixel-tr_TR.po +3 -3
  38. languages/official-facebook-pixel-vi_VN.po +3 -3
  39. languages/official-facebook-pixel-zh_CN.po +3 -3
  40. languages/official-facebook-pixel-zh_TW.po +3 -3
  41. languages/official-facebook-pixel.pot +4 -4
  42. readme.txt +15 -7
  43. vendor/autoload.php +1 -1
  44. vendor/composer/autoload_real.php +7 -7
  45. vendor/composer/autoload_static.php +4 -4
changelog.txt CHANGED
@@ -1,4 +1,8 @@
1
  *** Facebook for WordPress Changelog ***
 
 
 
 
2
  2020-12-08 version 2.2.2
3
  * Update Business SDK to v9.0.1
4
 
1
  *** Facebook for WordPress Changelog ***
2
+ 2021-01-06 version 3.0.0
3
+ * Adding Facebook Business Extension based configuration
4
+ * Renaming to Facebook for WordPress
5
+
6
  2020-12-08 version 2.2.2
7
  * Update Business SDK to v9.0.1
8
 
core/AAMFieldsExtractor.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (C) 2015-present, Facebook, Inc.
4
+ *
5
+ * This program is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; version 2 of the License.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ */
15
+
16
+ namespace FacebookPixelPlugin\Core;
17
+
18
+ use FacebookAds\Object\ServerSide\Normalizer;
19
+
20
+ final class AAMFieldsExtractor {
21
+ /**
22
+ * Filters the passed user data using the AAM settings of the pixel
23
+ * @param string[] $user_data_array
24
+ * @return string[]
25
+ */
26
+ public static function getNormalizedUserData($user_data_array) {
27
+ $aam_setttings = FacebookWordpressOptions::getAAMSettings();
28
+ if(!$user_data_array || !$aam_setttings ||
29
+ !$aam_setttings->getEnableAutomaticMatching()){
30
+ return array();
31
+ }
32
+
33
+ //Removing fields not enabled in AAM settings
34
+ foreach ($user_data_array as $key => $value) {
35
+ if(!in_array($key, $aam_setttings->getEnabledAutomaticMatchingFields())){
36
+ unset($user_data_array[$key]);
37
+ }
38
+ }
39
+
40
+ // Normalizing gender and date of birth
41
+ // According to https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
42
+ if(
43
+ array_key_exists(AAMSettingsFields::GENDER, $user_data_array)
44
+ && !empty($user_data_array[AAMSettingsFields::GENDER])
45
+ ){
46
+ $user_data_array[AAMSettingsFields::GENDER] =
47
+ $user_data_array[AAMSettingsFields::GENDER][0];
48
+ }
49
+ if(
50
+ array_key_exists(AAMSettingsFields::DATE_OF_BIRTH, $user_data_array)
51
+ ){
52
+ // strtotime() and date() return false for invalid parameters
53
+ $unix_timestamp =
54
+ strtotime($user_data_array[AAMSettingsFields::DATE_OF_BIRTH]);
55
+ if(!$unix_timestamp){
56
+ unset($user_data_array[AAMSettingsFields::DATE_OF_BIRTH]);
57
+ } else {
58
+ $formatted_date = date("Ymd", $unix_timestamp);
59
+ if(!$formatted_date){
60
+ unset($user_data_array[AAMSettingsFields::DATE_OF_BIRTH]);
61
+ } else {
62
+ $user_data_array[AAMSettingsFields::DATE_OF_BIRTH] = $formatted_date;
63
+ }
64
+ }
65
+ }
66
+ // Given that the format of advanced matching fields is the same in
67
+ // the Pixel and the Conversions API,
68
+ // we can use the business sdk for normalization
69
+ // Compare the documentation:
70
+ // https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
71
+ // https://developers.facebook.com/docs/facebook-pixel/advanced/advanced-matching
72
+ foreach($user_data_array as $field => $data){
73
+ try{
74
+ $normalized_value = Normalizer::normalize($field, $data);
75
+ $user_data_array[$field] = $normalized_value;
76
+ }
77
+ catch(\Exception $e){
78
+ unset($user_data_array[$field]);
79
+ }
80
+ }
81
+
82
+ return $user_data_array;
83
+ }
84
+ }
core/AAMSettingsFields.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright (C) 2017-present, Facebook, Inc.
4
+ *
5
+ * This program is free software; you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation; version 2 of the License.
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU General Public License for more details.
12
+ */
13
+
14
+ namespace FacebookPixelPlugin\Core;
15
+
16
+ /**
17
+ * Class that contains the keys used to identify each field in AAMSettings
18
+ */
19
+ abstract class AAMSettingsFields{
20
+ const EMAIL = "em";
21
+ const FIRST_NAME = "fn";
22
+ const LAST_NAME = "ln";
23
+ const GENDER = "ge";
24
+ const PHONE = "ph";
25
+ const CITY = "ct";
26
+ const STATE = "st";
27
+ const ZIP_CODE = "zp";
28
+ const DATE_OF_BIRTH = "db";
29
+ const COUNTRY = "country";
30
+ const EXTERNAL_ID = "external_id";
31
+ public static function getAllFields(){
32
+ return array(
33
+ self::EMAIL,
34
+ self::FIRST_NAME,
35
+ self::LAST_NAME,
36
+ self::GENDER,
37
+ self::PHONE,
38
+ self::CITY,
39
+ self::STATE,
40
+ self::ZIP_CODE,
41
+ self::DATE_OF_BIRTH,
42
+ self::COUNTRY,
43
+ self::EXTERNAL_ID,
44
+ );
45
+ }
46
+ }
core/FacebookPluginConfig.php CHANGED
@@ -20,15 +20,20 @@ namespace FacebookPixelPlugin\Core;
20
  defined('ABSPATH') or die('Direct access not allowed');
21
 
22
  class FacebookPluginConfig {
23
- const PLUGIN_VERSION = '2.2.2';
24
  const SOURCE = 'wordpress';
25
  const TEXT_DOMAIN = 'official-facebook-pixel';
 
26
 
27
  const ADMIN_CAPABILITY = 'manage_options';
28
  const ADMIN_DISMISS_PIXEL_ID_NOTICE = 'dismiss_pixel_id_notice';
29
  const ADMIN_IGNORE_PIXEL_ID_NOTICE = 'ignore_pixel_id_notice';
30
  const ADMIN_DISMISS_SSAPI_NOTICE = 'dismiss_ssapi__notice';
31
  const ADMIN_IGNORE_SSAPI_NOTICE = 'ignore_ssapi_notice';
 
 
 
 
32
  const ADMIN_MENU_SLUG = 'facebook_pixel_options';
33
  const ADMIN_MENU_TITLE = 'Facebook Pixel';
34
  const ADMIN_OPTION_GROUP = 'facebook_option_group';
@@ -37,15 +42,23 @@ class FacebookPluginConfig {
37
  const ADMIN_S2S_URL = 'https://developers.facebook.com/docs/marketing-api/conversions-api';
38
  const ADMIN_SECTION_ID = 'facebook_settings_section';
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  const DEFAULT_PIXEL_ID = null;
41
- const PIXEL_ID_KEY = 'pixel_id';
42
- const SETTINGS_KEY = 'facebook_config';
43
- const USE_PII_KEY = 'use_pii';
44
- const USE_ADVANCED_MATCHING_DEFAULT = null;
45
- const USE_S2S_KEY = 'use_s2s';
46
  const DEFAULT_ACCESS_TOKEN = null;
47
- const ACCESS_TOKEN_KEY = 'access_token';
48
- const USE_S2S_DEFAULT = null;
49
 
50
  const IS_PIXEL_RENDERED = 'is_pixel_rendered';
51
  const IS_NOSCRIPT_RENDERED = 'is_noscript_rendered';
20
  defined('ABSPATH') or die('Direct access not allowed');
21
 
22
  class FacebookPluginConfig {
23
+ const PLUGIN_VERSION = '3.0.0';
24
  const SOURCE = 'wordpress';
25
  const TEXT_DOMAIN = 'official-facebook-pixel';
26
+ const PLUGIN_NAME = 'Facebook for WordPress';
27
 
28
  const ADMIN_CAPABILITY = 'manage_options';
29
  const ADMIN_DISMISS_PIXEL_ID_NOTICE = 'dismiss_pixel_id_notice';
30
  const ADMIN_IGNORE_PIXEL_ID_NOTICE = 'ignore_pixel_id_notice';
31
  const ADMIN_DISMISS_SSAPI_NOTICE = 'dismiss_ssapi__notice';
32
  const ADMIN_IGNORE_SSAPI_NOTICE = 'ignore_ssapi_notice';
33
+ const ADMIN_DISMISS_FBE_NOT_INSTALLED_NOTICE =
34
+ 'dismiss_fbe_not_installed_notice';
35
+ const ADMIN_IGNORE_FBE_NOT_INSTALLED_NOTICE =
36
+ 'ignore_fbe_not_installed_notice';
37
  const ADMIN_MENU_SLUG = 'facebook_pixel_options';
38
  const ADMIN_MENU_TITLE = 'Facebook Pixel';
39
  const ADMIN_OPTION_GROUP = 'facebook_option_group';
42
  const ADMIN_S2S_URL = 'https://developers.facebook.com/docs/marketing-api/conversions-api';
43
  const ADMIN_SECTION_ID = 'facebook_settings_section';
44
 
45
+ const SETTINGS_KEY = 'facebook_business_extension_config';
46
+ const PIXEL_ID_KEY = 'facebook_pixel_id';
47
+ const ACCESS_TOKEN_KEY = 'facebook_access_token';
48
+ const EXTERNAL_BUSINESS_ID_KEY = 'facebook_external_business_id';
49
+ const IS_FBE_INSTALLED_KEY = 'facebook_is_fbe_installed';
50
+ const AAM_SETTINGS_KEY = 'facebook_pixel_aam_settings';
51
+
52
+ // Keys used in the old settings
53
+ const OLD_SETTINGS_KEY = 'facebook_config';
54
+ const OLD_PIXEL_ID_KEY = 'pixel_id';
55
+ const OLD_ACCESS_TOKEN_KEY = 'access_token';
56
+ const OLD_USE_PII = 'use_pii';
57
+
58
  const DEFAULT_PIXEL_ID = null;
 
 
 
 
 
59
  const DEFAULT_ACCESS_TOKEN = null;
60
+ const DEFAULT_EXTERNAL_BUSINESS_ID_PREFIX = 'fbe_wordpress_';
61
+ const DEFAULT_IS_FBE_INSTALLED = '0';
62
 
63
  const IS_PIXEL_RENDERED = 'is_pixel_rendered';
64
  const IS_NOSCRIPT_RENDERED = 'is_noscript_rendered';
core/FacebookServerSideEvent.php CHANGED
@@ -21,6 +21,7 @@ use FacebookAds\Api;
21
  use FacebookAds\Object\ServerSide\Event;
22
  use FacebookAds\Object\ServerSide\EventRequest;
23
  use FacebookAds\Object\ServerSide\UserData;
 
24
 
25
  defined('ABSPATH') or die('Direct access not allowed');
26
 
@@ -43,16 +44,14 @@ class FacebookServerSideEvent {
43
 
44
  public function track($event, $sendNow = true) {
45
  $this->trackedEvents[] = $event;
46
- if( FacebookWordpressOptions::getUseS2S() ){
47
- if( $sendNow ){
48
- do_action( 'send_server_events',
49
- array($event),
50
- 1
51
- );
52
- }
53
- else{
54
- $this->pendingEvents[] = $event;
55
- }
56
  }
57
  }
58
 
@@ -89,12 +88,19 @@ class FacebookServerSideEvent {
89
  $access_token = FacebookWordpressOptions::getAccessToken();
90
  $agent = FacebookWordpressOptions::getAgentString();
91
 
92
- $api = Api::init(null, null, $access_token);
 
 
 
 
93
 
94
- $request = (new EventRequest($pixel_id))
95
  ->setEvents($events)
96
  ->setPartnerAgent($agent);
97
 
98
- $response = $request->execute();
 
 
 
99
  }
100
  }
21
  use FacebookAds\Object\ServerSide\Event;
22
  use FacebookAds\Object\ServerSide\EventRequest;
23
  use FacebookAds\Object\ServerSide\UserData;
24
+ use FacebookAds\Exception\Exception;
25
 
26
  defined('ABSPATH') or die('Direct access not allowed');
27
 
44
 
45
  public function track($event, $sendNow = true) {
46
  $this->trackedEvents[] = $event;
47
+ if( $sendNow ){
48
+ do_action( 'send_server_events',
49
+ array($event),
50
+ 1
51
+ );
52
+ }
53
+ else{
54
+ $this->pendingEvents[] = $event;
 
 
55
  }
56
  }
57
 
88
  $access_token = FacebookWordpressOptions::getAccessToken();
89
  $agent = FacebookWordpressOptions::getAgentString();
90
 
91
+ if(empty($pixel_id) || empty($access_token)){
92
+ return;
93
+ }
94
+ try{
95
+ $api = Api::init(null, null, $access_token);
96
 
97
+ $request = (new EventRequest($pixel_id))
98
  ->setEvents($events)
99
  ->setPartnerAgent($agent);
100
 
101
+ $response = $request->execute();
102
+ } catch (Exception $e) {
103
+ error_log(json_encode($e));
104
+ }
105
  }
106
  }
core/FacebookWordpressOptions.php CHANGED
@@ -17,17 +17,22 @@
17
 
18
  namespace FacebookPixelPlugin\Core;
19
 
 
 
20
  defined('ABSPATH') or die('Direct access not allowed');
21
 
22
  class FacebookWordpressOptions {
23
  private static $options = array();
24
  private static $userInfo = array();
25
  private static $versionInfo = array();
 
 
26
 
27
  public static function initialize() {
28
- self::setOptions();
29
- self::setUserInfo();
30
  self::setVersionInfo();
 
 
31
  }
32
 
33
  public static function getOptions() {
@@ -44,38 +49,72 @@ class FacebookWordpressOptions {
44
  ? '' : FacebookPluginConfig::DEFAULT_ACCESS_TOKEN;
45
  }
46
 
47
- // Default is on for unset config
48
- public static function getDefaultUsePIIKey() {
49
- return (!is_null(FacebookPluginConfig::USE_ADVANCED_MATCHING_DEFAULT)
50
- && !FacebookPluginConfig::USE_ADVANCED_MATCHING_DEFAULT) ? '0' : '1';
51
  }
52
 
53
- // We default not to send events through S2S, if the config is unset.
54
- public static function getDefaultUseS2SKey() {
55
- return (is_null(FacebookPluginConfig::USE_S2S_DEFAULT)
56
- || !FacebookPluginConfig::USE_S2S_DEFAULT) ? '0' : '1';
57
  }
58
 
59
- private static function setOptions() {
60
- self::$options = \get_option(
61
- FacebookPluginConfig::SETTINGS_KEY,
62
- array(
63
- FacebookPluginConfig::PIXEL_ID_KEY => self::getDefaultPixelID(),
64
- FacebookPluginConfig::USE_PII_KEY => self::getDefaultUsePIIKey(),
65
- FacebookPluginConfig::USE_S2S_KEY => self::getDefaultUseS2SKey(),
66
- FacebookPluginConfig::ACCESS_TOKEN_KEY => self::getDefaultAccessToken(),
67
- ));
68
-
69
- // we need esc_js because the id is set through the form
70
- if (array_key_exists(FacebookPluginConfig::PIXEL_ID_KEY, self::$options)) {
71
- self::$options[FacebookPluginConfig::PIXEL_ID_KEY] =
72
- esc_js(self::$options[FacebookPluginConfig::PIXEL_ID_KEY]);
73
  }
74
-
75
- if (array_key_exists(
76
- FacebookPluginConfig::ACCESS_TOKEN_KEY, self::$options)) {
77
- self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY] =
78
- esc_js(self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
  }
81
 
@@ -87,30 +126,35 @@ class FacebookWordpressOptions {
87
  return self::getDefaultPixelID();
88
  }
89
 
90
- public static function getAccessToken() {
91
- if (array_key_exists(
92
- FacebookPluginConfig::ACCESS_TOKEN_KEY, self::$options)) {
93
- return self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY];
 
 
94
  }
95
 
96
- return self::getDefaultAccessToken();
97
  }
98
 
99
- public static function getUsePii() {
100
- if (array_key_exists(
101
- FacebookPluginConfig::USE_PII_KEY, self::$options)) {
102
- return self::$options[FacebookPluginConfig::USE_PII_KEY];
 
 
103
  }
104
 
105
- return self::getDefaultUsePIIKey();
106
  }
107
 
108
- public static function getUseS2S() {
109
- if (array_key_exists(FacebookPluginConfig::USE_S2S_KEY, self::$options)) {
110
- return self::$options[FacebookPluginConfig::USE_S2S_KEY];
 
111
  }
112
 
113
- return self::getDefaultUseS2SKey();
114
  }
115
 
116
  public static function getUserInfo() {
@@ -129,20 +173,20 @@ class FacebookWordpressOptions {
129
 
130
  public static function registerUserInfo() {
131
  $current_user = wp_get_current_user();
132
- $use_pii = self::getUsePii();
133
- if (0 === $current_user->ID || $use_pii !== '1') {
134
- // User not logged in or admin chose not to send PII.
135
  self::$userInfo = array();
136
  } else {
137
- self::$userInfo = array_filter(
138
  array(
139
  // Keys documented in
140
  // https://developers.facebook.com/docs/facebook-pixel/pixel-with-ads/conversion-tracking#advanced_match
141
- 'em' => $current_user->user_email,
142
- 'fn' => $current_user->user_firstname,
143
- 'ln' => $current_user->user_lastname
144
  ),
145
  function ($value) { return $value !== null && $value !== ''; });
 
146
  }
147
  }
148
 
@@ -167,4 +211,78 @@ class FacebookWordpressOptions {
167
  self::$versionInfo['version'],
168
  self::$versionInfo['pluginVersion']);
169
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  }
17
 
18
  namespace FacebookPixelPlugin\Core;
19
 
20
+ use FacebookAds\Object\ServerSide\AdsPixelSettings;
21
+
22
  defined('ABSPATH') or die('Direct access not allowed');
23
 
24
  class FacebookWordpressOptions {
25
  private static $options = array();
26
  private static $userInfo = array();
27
  private static $versionInfo = array();
28
+ private static $aamSettings = null;
29
+ const AAM_SETTINGS_REFRESH_IN_MINUTES = 20;
30
 
31
  public static function initialize() {
32
+ self::initOptions();
 
33
  self::setVersionInfo();
34
+ self::setAAMSettings();
35
+ self::setUserInfo();
36
  }
37
 
38
  public static function getOptions() {
49
  ? '' : FacebookPluginConfig::DEFAULT_ACCESS_TOKEN;
50
  }
51
 
52
+ public static function getDefaultExternalBusinessId(){
53
+ return uniqid(
54
+ FacebookPluginConfig::DEFAULT_EXTERNAL_BUSINESS_ID_PREFIX.time().'_'
55
+ );
56
  }
57
 
58
+ public static function getDefaultIsFbeInstalled(){
59
+ return FacebookPluginConfig::DEFAULT_IS_FBE_INSTALLED;
 
 
60
  }
61
 
62
+ private static function initOptions() {
63
+ $old_options = \get_option(FacebookPluginConfig::OLD_SETTINGS_KEY);
64
+ $new_options = \get_option(FacebookPluginConfig::SETTINGS_KEY);
65
+ // If the new options are saved in WP database, they are used
66
+ if($new_options){
67
+ self::$options = $new_options;
 
 
 
 
 
 
 
 
68
  }
69
+ // Otherwise, the old options can be used
70
+ else{
71
+ // The pixel id and access token will be exported
72
+ if($old_options){
73
+ self::$options = array(
74
+ FacebookPluginConfig::EXTERNAL_BUSINESS_ID_KEY =>
75
+ self::getDefaultExternalBusinessId(),
76
+ FacebookPluginConfig::IS_FBE_INSTALLED_KEY =>
77
+ self::getDefaultIsFbeInstalled(),
78
+ );
79
+ if(
80
+ array_key_exists(FacebookPluginConfig::OLD_ACCESS_TOKEN_KEY,$old_options)
81
+ && !empty($old_options[FacebookPluginConfig::OLD_ACCESS_TOKEN_KEY])
82
+ ){
83
+ self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY] =
84
+ $old_options[FacebookPluginConfig::OLD_ACCESS_TOKEN_KEY];
85
+ }
86
+ else{
87
+ self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY] =
88
+ self::getDefaultAccessToken();
89
+ }
90
+ if(
91
+ array_key_exists(FacebookPluginConfig::OLD_PIXEL_ID_KEY,$old_options)
92
+ && !empty($old_options[FacebookPluginConfig::OLD_PIXEL_ID_KEY])
93
+ && is_numeric($old_options[FacebookPluginConfig::OLD_PIXEL_ID_KEY])
94
+ ){
95
+ self::$options[FacebookPluginConfig::PIXEL_ID_KEY] =
96
+ $old_options[FacebookPluginConfig::OLD_PIXEL_ID_KEY];
97
+ }
98
+ else{
99
+ self::$options[FacebookPluginConfig::PIXEL_ID_KEY] =
100
+ self::getDefaultPixelID();
101
+ }
102
+ }
103
+ // If no options are present, the default values are used
104
+ else{
105
+ self::$options = \get_option(
106
+ FacebookPluginConfig::SETTINGS_KEY,
107
+ array(
108
+ FacebookPluginConfig::PIXEL_ID_KEY => self::getDefaultPixelID(),
109
+ FacebookPluginConfig::ACCESS_TOKEN_KEY =>
110
+ self::getDefaultAccessToken(),
111
+ FacebookPluginConfig::EXTERNAL_BUSINESS_ID_KEY =>
112
+ self::getDefaultExternalBusinessId(),
113
+ FacebookPluginConfig::IS_FBE_INSTALLED_KEY =>
114
+ self::getDefaultIsFbeInstalled()
115
+ )
116
+ );
117
+ }
118
  }
119
  }
120
 
126
  return self::getDefaultPixelID();
127
  }
128
 
129
+ public static function getExternalBusinessId() {
130
+ if(
131
+ array_key_exists(FacebookPluginConfig::EXTERNAL_BUSINESS_ID_KEY,
132
+ self::$options)
133
+ ){
134
+ return self::$options[FacebookPluginConfig::EXTERNAL_BUSINESS_ID_KEY];
135
  }
136
 
137
+ return self::getDefaultExternalBusinessId();
138
  }
139
 
140
+ public static function getIsFbeInstalled(){
141
+ if(
142
+ array_key_exists(FacebookPluginConfig::IS_FBE_INSTALLED_KEY,
143
+ self::$options)
144
+ ){
145
+ return self::$options[FacebookPluginConfig::IS_FBE_INSTALLED_KEY];
146
  }
147
 
148
+ return self::getDefaultIsFbeInstalled();
149
  }
150
 
151
+ public static function getAccessToken() {
152
+ if (array_key_exists(
153
+ FacebookPluginConfig::ACCESS_TOKEN_KEY, self::$options)) {
154
+ return self::$options[FacebookPluginConfig::ACCESS_TOKEN_KEY];
155
  }
156
 
157
+ return self::getDefaultAccessToken();
158
  }
159
 
160
  public static function getUserInfo() {
173
 
174
  public static function registerUserInfo() {
175
  $current_user = wp_get_current_user();
176
+ if (0 === $current_user->ID ) {
177
+ // User not logged in
 
178
  self::$userInfo = array();
179
  } else {
180
+ $user_info = array_filter(
181
  array(
182
  // Keys documented in
183
  // https://developers.facebook.com/docs/facebook-pixel/pixel-with-ads/conversion-tracking#advanced_match
184
+ AAMSettingsFields::EMAIL => $current_user->user_email,
185
+ AAMSettingsFields::FIRST_NAME => $current_user->user_firstname,
186
+ AAMSettingsFields::LAST_NAME => $current_user->user_lastname
187
  ),
188
  function ($value) { return $value !== null && $value !== ''; });
189
+ self::$userInfo = AAMFieldsExtractor::getNormalizedUserData($user_info);
190
  }
191
  }
192
 
211
  self::$versionInfo['version'],
212
  self::$versionInfo['pluginVersion']);
213
  }
214
+
215
+ public static function getAAMSettings(){
216
+ return self::$aamSettings;
217
+ }
218
+
219
+ private static function setFbeBasedAAMSettings(){
220
+ $installed_pixel = self::getPixelId();
221
+ $settings_as_array = get_transient(FacebookPluginConfig::AAM_SETTINGS_KEY);
222
+ // If AAM_SETTINGS_KEY is present in the DB and corresponds to the installed
223
+ // pixel, it is converted into an AdsPixelSettings object
224
+ if( $settings_as_array !== false ){
225
+ $aam_settings = new AdsPixelSettings();
226
+ $aam_settings->setPixelId($settings_as_array['pixelId']);
227
+ $aam_settings->setEnableAutomaticMatching($settings_as_array['enableAutomaticMatching']);
228
+ $aam_settings->setEnabledAutomaticMatchingFields($settings_as_array['enabledAutomaticMatchingFields']);
229
+ if($installed_pixel == $aam_settings->getPixelId()){
230
+ self::$aamSettings = $aam_settings;
231
+ }
232
+ }
233
+ // If the settings are not present
234
+ // they are fetched from Facebook domain
235
+ // and cached in WP database if they are not null
236
+ if(!self::$aamSettings){
237
+ $refresh_interval =
238
+ self::AAM_SETTINGS_REFRESH_IN_MINUTES*MINUTE_IN_SECONDS;
239
+ $aam_settings = AdsPixelSettings::buildFromPixelId( $installed_pixel );
240
+ if($aam_settings){
241
+ $settings_as_array = array(
242
+ 'pixelId' => $aam_settings->getPixelId(),
243
+ 'enableAutomaticMatching' =>
244
+ $aam_settings->getEnableAutomaticMatching(),
245
+ 'enabledAutomaticMatchingFields' =>
246
+ $aam_settings->getEnabledAutomaticMatchingFields(),
247
+ );
248
+ set_transient(FacebookPluginConfig::AAM_SETTINGS_KEY,
249
+ $settings_as_array, $refresh_interval);
250
+ self::$aamSettings = $aam_settings;
251
+ }
252
+ }
253
+ }
254
+
255
+ private static function setOldAAMSettings(){
256
+ $old_options = \get_option(FacebookPluginConfig::OLD_SETTINGS_KEY);
257
+ if($old_options
258
+ && array_key_exists(FacebookPluginConfig::OLD_USE_PII, $old_options)
259
+ && $old_options[FacebookPluginConfig::OLD_USE_PII]){
260
+ self::$aamSettings = new AdsPixelSettings(
261
+ array(
262
+ 'enableAutomaticMatching' => true,
263
+ 'enabledAutomaticMatchingFields' =>
264
+ AAMSettingsFields::getAllFields(),
265
+ )
266
+ );
267
+ } else {
268
+ self::$aamSettings = new AdsPixelSettings(
269
+ array(
270
+ 'enableAutomaticMatching' => false,
271
+ 'enabledAutomaticMatchingFields' => array(),
272
+ )
273
+ );
274
+ }
275
+ }
276
+
277
+ private static function setAAMSettings(){
278
+ self::$aamSettings = null;
279
+ if( empty(self::getPixelId()) ){
280
+ return;
281
+ }
282
+ if(self::getIsFbeInstalled()){
283
+ self::setFbeBasedAAMSettings();
284
+ } else {
285
+ self::setOldAAMSettings();
286
+ }
287
+ }
288
  }
core/FacebookWordpressPixelInjection.php CHANGED
@@ -46,16 +46,14 @@ class FacebookWordpressPixelInjection {
46
  }
47
 
48
  public function sendPendingEvents(){
49
- if(FacebookWordpressOptions::getUseS2S()){
50
- $pending_events =
51
- FacebookServerSideEvent::getInstance()->getPendingEvents();
52
- if(count($pending_events) > 0){
53
- do_action(
54
- 'send_server_events',
55
- $pending_events,
56
- count($pending_events)
57
- );
58
- }
59
  }
60
  }
61
 
46
  }
47
 
48
  public function sendPendingEvents(){
49
+ $pending_events =
50
+ FacebookServerSideEvent::getInstance()->getPendingEvents();
51
+ if(count($pending_events) > 0){
52
+ do_action(
53
+ 'send_server_events',
54
+ $pending_events,
55
+ count($pending_events)
56
+ );
 
 
57
  }
58
  }
59
 
core/FacebookWordpressSettingsPage.php CHANGED
@@ -17,260 +17,160 @@
17
 
18
  namespace FacebookPixelPlugin\Core;
19
 
 
 
20
  defined('ABSPATH') or die('Direct access not allowed');
21
 
22
  class FacebookWordpressSettingsPage {
23
  private $optionsPage = '';
24
 
25
  public function __construct($plugin_name) {
26
- add_action('admin_menu', array($this, 'addMenu'));
27
- add_action('admin_init', array($this, 'registerSettingsPage'));
28
- add_action('admin_init', array($this, 'dismissNotices'));
29
- add_action('admin_enqueue_scripts', array($this, 'registerPluginStyles'));
30
- add_action('current_screen', array($this, 'registerNotices'));
31
  add_filter(
32
  'plugin_action_links_'.$plugin_name,
33
  array($this, 'addSettingsLink'));
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
- public function addMenu() {
37
  $this->optionsPage = add_options_page(
38
  FacebookPluginConfig::ADMIN_PAGE_TITLE,
39
  FacebookPluginConfig::ADMIN_MENU_TITLE,
40
  FacebookPluginConfig::ADMIN_CAPABILITY,
41
  FacebookPluginConfig::ADMIN_MENU_SLUG,
42
- array($this, 'createMenuPage'));
43
  }
44
 
45
- public function createMenuPage() {
46
  if (!current_user_can(FacebookPluginConfig::ADMIN_CAPABILITY)) {
47
  wp_die(__(
48
  'You do not have sufficient permissions to access this page',
49
  FacebookPluginConfig::TEXT_DOMAIN));
50
  }
51
-
52
- printf(
53
- '
54
- <div class="wrap">
55
- <h2>%s</h2>
56
- <form action="options.php" method="POST">
57
- ',
58
- FacebookPluginConfig::ADMIN_PAGE_TITLE);
59
- settings_fields(FacebookPluginConfig::ADMIN_OPTION_GROUP);
60
- do_settings_sections(FacebookPluginConfig::ADMIN_MENU_SLUG);
61
- submit_button();
62
- printf(
63
- '
64
- </form>
65
- </div>
66
- ');
67
- }
68
-
69
- public function registerSettingsPage() {
70
- register_setting(
71
- FacebookPluginConfig::ADMIN_OPTION_GROUP,
72
- FacebookPluginConfig::SETTINGS_KEY,
73
- array($this, 'sanitizeInput'));
74
- add_settings_section(
75
- FacebookPluginConfig::ADMIN_SECTION_ID,
76
- null,
77
- array($this, 'sectionSubTitle'),
78
- FacebookPluginConfig::ADMIN_MENU_SLUG);
79
- add_settings_field(
80
- FacebookPluginConfig::PIXEL_ID_KEY,
81
- 'Pixel ID',
82
- array($this, 'pixelIdFormField'),
83
- FacebookPluginConfig::ADMIN_MENU_SLUG,
84
- FacebookPluginConfig::ADMIN_SECTION_ID);
85
- add_settings_field(
86
- FacebookPluginConfig::USE_PII_KEY,
87
- 'Use Advanced Matching on pixel?',
88
- array($this, 'usePiiFormField'),
89
- FacebookPluginConfig::ADMIN_MENU_SLUG,
90
- FacebookPluginConfig::ADMIN_SECTION_ID);
91
- add_settings_field(
92
- FacebookPluginConfig::USE_S2S_KEY,
93
- 'Use Conversions API?',
94
- array($this, 'useS2SFormField'),
95
- FacebookPluginConfig::ADMIN_MENU_SLUG,
96
- FacebookPluginConfig::ADMIN_SECTION_ID);
97
- add_settings_field(
98
- FacebookPluginConfig::ACCESS_TOKEN_KEY,
99
- 'Access Token',
100
- array($this, 'accessTokenFormField'),
101
- FacebookPluginConfig::ADMIN_MENU_SLUG,
102
- FacebookPluginConfig::ADMIN_SECTION_ID);
103
- }
104
-
105
- public function sanitizeInput($input) {
106
- $input[FacebookPluginConfig::USE_PII_KEY] =
107
- !empty($input[FacebookPluginConfig::USE_PII_KEY])
108
- ? '1'
109
- : '0';
110
- $input[FacebookPluginConfig::PIXEL_ID_KEY] =
111
- !empty($input[FacebookPluginConfig::PIXEL_ID_KEY])
112
- ? FacebookPluginUtils::isPositiveInteger($input[FacebookPluginConfig::PIXEL_ID_KEY])
113
- ? $input[FacebookPluginConfig::PIXEL_ID_KEY]
114
- : ''
115
- : FacebookPixel::getPixelId();
116
- return $input;
117
- }
118
-
119
- public function sectionSubTitle() {
120
- printf(
121
- esc_html__(
122
- 'Please note that we are now also supporting lower funnel pixel events
123
- for Contact Form 7, Easy Digital Downloads, Ninja Forms and WP Forms',
124
- FacebookPluginConfig::TEXT_DOMAIN));
125
  }
126
 
127
- public function pixelIdFormField() {
128
- $description = esc_html__(
129
- 'The unique identifier for your Facebook pixel.',
130
- FacebookPluginConfig::TEXT_DOMAIN);
131
-
132
- $pixel_id = FacebookWordpressOptions::getPixelId();
133
- printf(
134
- '
135
- <input name="%s" id="%s" value="%s" />
136
- <p class="description">%s</p>
137
- ',
138
- FacebookPluginConfig::SETTINGS_KEY . '[' .
139
- FacebookPluginConfig::PIXEL_ID_KEY . ']',
140
- FacebookPluginConfig::PIXEL_ID_KEY,
141
- isset($pixel_id)
142
- ? esc_attr($pixel_id)
143
- : '',
144
- $description);
145
  }
146
 
 
 
 
 
 
 
 
147
 
148
- public function accessTokenFormField() {
149
- $description = esc_html__(
150
- '',
151
- FacebookPluginConfig::TEXT_DOMAIN);
152
-
153
- $access_token = FacebookWordpressOptions::getAccessToken();
154
- $existing_access_token_value =
155
- isset($access_token) ? esc_attr($access_token) : '';
156
- $input_name = FacebookPluginConfig::SETTINGS_KEY .
157
- '[' . FacebookPluginConfig::ACCESS_TOKEN_KEY . ']';
158
-
159
- printf(
160
- '
161
- <textarea name="%s" id="%s" rows=4 cols=60 maxlength=250>%s</textarea>
162
- <p class="description">%s</p>
163
- ',
164
- $input_name,
165
- FacebookPluginConfig::ACCESS_TOKEN_KEY,
166
- $existing_access_token_value,
167
- $description);
 
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
 
170
- public function usePiiFormField() {
171
- $link = sprintf(
172
- wp_kses(
173
- __(
174
- 'For businesses that operate in the European Union, you may need to
175
- take additional action. Read the <a href="%s" target="_blank">
176
- Cookie Consent Guide for Sites and Apps</a> for suggestions on
177
- complying with EU privacy requirements.',
178
- FacebookPluginConfig::TEXT_DOMAIN),
179
- array('a' => array('href' => array(), 'target' => array()))),
180
- esc_url(FacebookPluginConfig::ADMIN_PRIVACY_URL));
181
- printf(
182
- '
183
- <label for="%s">
184
- <input
185
- type="checkbox"
186
- name="%s"
187
- id="%s"
188
- value="1"
189
- ',
190
- FacebookPluginConfig::USE_PII_KEY,
191
- FacebookPluginConfig::SETTINGS_KEY . '[' .
192
- FacebookPluginConfig::USE_PII_KEY . ']',
193
- FacebookPluginConfig::USE_PII_KEY);
194
- checked(1, FacebookWordpressOptions::getUsePii());
195
- printf(
196
- '
197
- />
198
- %s
199
- </label>
200
- <p class="description">%s</p>
201
- ',
202
- esc_html__(
203
- 'Enabling Advanced Matching improves audience building.',
204
- FacebookPluginConfig::TEXT_DOMAIN),
205
- $link);
206
- }
207
-
208
- // Allow to the Plugin to send S2S Events
209
- public function useS2SFormField() {
210
- $link = sprintf(
211
- wp_kses(
212
- __(
213
- 'An access token is required to use the Conversions API.<br>
214
- <a href="%s" target="_blank"> Generate Access Token</a>',
215
- FacebookPluginConfig::TEXT_DOMAIN),
216
- array('a' => array('href' => array(), 'target' => array()))),
217
- esc_url(FacebookPluginConfig::ADMIN_S2S_URL));
218
- printf(
219
- '
220
- <label for="%s">
221
- <input
222
- type="checkbox"
223
- name="%s"
224
- id="%s"
225
- value="1"
226
- ',
227
- FacebookPluginConfig::USE_S2S_KEY,
228
- FacebookPluginConfig::SETTINGS_KEY . '[' .
229
- FacebookPluginConfig::USE_S2S_KEY . ']',
230
- FacebookPluginConfig::USE_S2S_KEY);
231
- checked(1, FacebookWordpressOptions::getUseS2S());
232
- printf(
233
- '
234
- />
235
- %s
236
- </label>
237
- <p class="description">%s</p>
238
- ',
239
- esc_html__(
240
- 'Also send events directly from your web server to Facebook through the
241
- Conversions API. This can help you capture more events.',
242
- FacebookPluginConfig::TEXT_DOMAIN),
243
- $link);
244
  }
245
 
246
-
247
  public function registerNotices() {
248
- // Update class field
249
- $pixel_id = FacebookWordpressOptions::getPixelId();
250
- $use_s2s = FacebookWordpressOptions::getUseS2S();
251
- $access_token = FacebookWordpressOptions::getAccessToken();
252
  $current_screen_id = get_current_screen()->id;
253
 
254
  if (current_user_can(FacebookPluginConfig::ADMIN_CAPABILITY) &&
255
- in_array($current_screen_id, array('dashboard', 'plugins'), true))
256
- {
257
- if (!FacebookPluginUtils::isPositiveInteger($pixel_id)
258
- && !get_user_meta(
259
- get_current_user_id(),
260
- FacebookPluginConfig::ADMIN_IGNORE_PIXEL_ID_NOTICE,
261
- true))
262
- {
263
- add_action('admin_notices', array($this, 'pixelIdNotSetNotice'));
264
- } else if ((!$use_s2s || empty($access_token))
265
- && !get_user_meta(
266
  get_current_user_id(),
267
- FacebookPluginConfig::ADMIN_IGNORE_SSAPI_NOTICE,
268
- true))
269
- {
270
- add_action('admin_notices',
271
- array($this, 'serverSideApiNotEnabledNotice'));
 
 
 
 
 
 
 
 
 
 
 
 
272
  }
 
 
 
 
 
 
 
273
  }
 
 
274
  }
275
 
276
  public function setNotice($notice, $dismiss_config) {
@@ -278,9 +178,7 @@ class FacebookWordpressSettingsPage {
278
  FacebookPluginConfig::ADMIN_MENU_SLUG);
279
 
280
  $link = sprintf(
281
- wp_kses(
282
- $notice,
283
- array('a' => array('href' => array()))),
284
  esc_url($url));
285
  printf(
286
  '
@@ -301,53 +199,24 @@ class FacebookWordpressSettingsPage {
301
  FacebookPluginConfig::TEXT_DOMAIN));
302
  }
303
 
304
- public function pixelIdNotSetNotice() {
 
305
  $this->setNotice(
306
- __('The Facebook Pixel plugin requires a Pixel ID.
307
- Click <a href="%s">here</a> to configure the plugin.',
308
  FacebookPluginConfig::TEXT_DOMAIN),
309
- FacebookPluginConfig::ADMIN_DISMISS_PIXEL_ID_NOTICE);
310
- }
311
-
312
- public function serverSideApiNotEnabledNotice() {
313
- $this->setNotice(
314
- __('The Facebook Pixel plugin now includes support for the Conversions
315
- API, which lets you send events directly from your page\'s website.
316
- Click <a href="%s">here</a> to configure the plugin.',
317
- FacebookPluginConfig::TEXT_DOMAIN),
318
- FacebookPluginConfig::ADMIN_DISMISS_SSAPI_NOTICE);
319
  }
320
 
321
  public function dismissNotices() {
322
  $user_id = get_current_user_id();
323
- if (isset($_GET[FacebookPluginConfig::ADMIN_DISMISS_PIXEL_ID_NOTICE])) {
 
 
324
  update_user_meta($user_id,
325
- FacebookPluginConfig::ADMIN_IGNORE_PIXEL_ID_NOTICE,
326
  true);
327
  }
328
 
329
- if (isset($_GET[FacebookPluginConfig::ADMIN_DISMISS_SSAPI_NOTICE])) {
330
- update_user_meta($user_id,
331
- FacebookPluginConfig::ADMIN_IGNORE_SSAPI_NOTICE,
332
- true);
333
- }
334
- }
335
-
336
- public function registerPluginStyles() {
337
- wp_register_style(
338
- FacebookPluginConfig::TEXT_DOMAIN,
339
- plugins_url('../css/admin.css', __FILE__));
340
- wp_enqueue_style(FacebookPluginConfig::TEXT_DOMAIN);
341
- }
342
-
343
- public function addSettingsLink($links) {
344
- $settings = array(
345
- 'settings' => sprintf(
346
- '<a href="%s">%s</a>',
347
- admin_url('options-general.php?page=' .
348
- FacebookPluginConfig::ADMIN_MENU_SLUG),
349
- 'Settings')
350
- );
351
- return array_merge($settings, $links);
352
  }
353
  }
17
 
18
  namespace FacebookPixelPlugin\Core;
19
 
20
+ use FacebookAds\ApiConfig;
21
+
22
  defined('ABSPATH') or die('Direct access not allowed');
23
 
24
  class FacebookWordpressSettingsPage {
25
  private $optionsPage = '';
26
 
27
  public function __construct($plugin_name) {
 
 
 
 
 
28
  add_filter(
29
  'plugin_action_links_'.$plugin_name,
30
  array($this, 'addSettingsLink'));
31
+ add_action('admin_menu', array($this, 'addMenuFbe'));
32
+ add_action('admin_init', array($this, 'dismissNotices'));
33
+ add_action('admin_enqueue_scripts', array($this, 'registerPluginScripts'));
34
+ add_action('current_screen', array($this, 'registerNotices'));
35
+ }
36
+
37
+ public function registerPluginScripts(){
38
+ wp_register_script('fbe_allinone_script',
39
+ plugins_url('../js/fbe_allinone.js', __FILE__));
40
+ wp_register_style(
41
+ FacebookPluginConfig::TEXT_DOMAIN,
42
+ plugins_url('../css/admin.css', __FILE__));
43
+ wp_enqueue_style(FacebookPluginConfig::TEXT_DOMAIN);
44
  }
45
 
46
+ public function addMenuFbe() {
47
  $this->optionsPage = add_options_page(
48
  FacebookPluginConfig::ADMIN_PAGE_TITLE,
49
  FacebookPluginConfig::ADMIN_MENU_TITLE,
50
  FacebookPluginConfig::ADMIN_CAPABILITY,
51
  FacebookPluginConfig::ADMIN_MENU_SLUG,
52
+ array($this, 'addFbeBox'));
53
  }
54
 
55
+ public function addFbeBox(){
56
  if (!current_user_can(FacebookPluginConfig::ADMIN_CAPABILITY)) {
57
  wp_die(__(
58
  'You do not have sufficient permissions to access this page',
59
  FacebookPluginConfig::TEXT_DOMAIN));
60
  }
61
+ $pixel_id_message = $this->getPreviousPixelIdMessage();
62
+ if($pixel_id_message){
63
+ echo $pixel_id_message;
64
+ }
65
+ echo $this->getFbeBrowserSettings();
66
+ wp_enqueue_script('fbe_allinone_script');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
+ private function getPreviousPixelIdMessage(){
70
+ if(FacebookWordpressOptions::getIsFbeInstalled()){
71
+ return null;
72
+ }
73
+ $pixel_id = FacebookWordPressOptions::getPixelId();
74
+ if(empty($pixel_id)){
75
+ return null;
76
+ }
77
+ $message =
78
+ sprintf('<p>Reuse the pixel id from your previous setup: '.
79
+ '<strong>%s</strong></p>',
80
+ $pixel_id
81
+ );
82
+ return $message;
 
 
 
 
83
  }
84
 
85
+ private function getFbeBrowserSettings(){
86
+ ob_start();
87
+ ?>
88
+ <div>
89
+ <div id="fbe-iframe">
90
+ </div>
91
+ </div>
92
 
93
+ <script>
94
+ window.facebookBusinessExtensionConfig = {
95
+ pixelId: '<?php echo FacebookWordpressOptions::getPixelId() ?>'
96
+ ,popupOrigin: "https://business.facebook.com"
97
+ ,setSaveSettingsRoute: '<?php echo $this->getFbeSaveSettingsAjaxRoute() ?>'
98
+ ,externalBusinessId: '<?php echo FacebookWordpressOptions::getExternalBusinessId() ?>'
99
+ ,fbeLoginUrl: "https://business.facebook.com/fbe-iframe-get-started/?"
100
+ ,deleteConfigKeys: '<?php echo $this->getDeleteFbeSettingsAjaxRoute() ?>'
101
+ ,appId: '221646389321681'
102
+ ,timeZone: 'America/Los_Angeles'
103
+ ,installed: '<?php echo FacebookWordpressOptions::getIsFbeInstalled() ?>'
104
+ ,systemUserName: '<?php echo FacebookWordpressOptions::getExternalBusinessId() ?>' + '_system_user'
105
+ ,businessVertical: 'ECOMMERCE'
106
+ ,version: 'v8.0'
107
+ ,currency: 'USD'
108
+ ,businessName: 'Solutions Engineering Team'
109
+ ,debug: true
110
+ ,channel: 'CONVERSIONS_API'
111
+ };
112
+ console.log(JSON.stringify(window.facebookBusinessExtensionConfig));
113
+ </script>
114
+ <?php
115
+ $initialScript = ob_get_clean();
116
+ return $initialScript;
117
+ }
118
+
119
+ public function getFbeSaveSettingsAjaxRoute(){
120
+ return admin_url('admin-ajax.php?action=save_fbe_settings');
121
+ }
122
+
123
+ public function getDeleteFbeSettingsAjaxRoute(){
124
+ return admin_url('admin-ajax.php?action=delete_fbe_settings');
125
  }
126
 
127
+ public function addSettingsLink($links) {
128
+ $settings = array(
129
+ 'settings' => sprintf(
130
+ '<a href="%s">%s</a>',
131
+ admin_url('options-general.php?page=' .
132
+ FacebookPluginConfig::ADMIN_MENU_SLUG),
133
+ 'Settings')
134
+ );
135
+ return array_merge($settings, $links);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
 
 
138
  public function registerNotices() {
139
+ $is_fbe_installed = FacebookWordpressOptions::getIsFbeInstalled();
 
 
 
140
  $current_screen_id = get_current_screen()->id;
141
 
142
  if (current_user_can(FacebookPluginConfig::ADMIN_CAPABILITY) &&
143
+ in_array($current_screen_id, array('dashboard', 'plugins'), true)){
144
+ if( $is_fbe_installed == '0' && !get_user_meta(
 
 
 
 
 
 
 
 
 
145
  get_current_user_id(),
146
+ FacebookPluginConfig::ADMIN_IGNORE_FBE_NOT_INSTALLED_NOTICE,
147
+ true)){
148
+ add_action('admin_notices', array($this, 'fbeNotInstalledNotice'));
149
+ }
150
+ }
151
+ }
152
+
153
+ public function getCustomizedFbeNotInstalledNotice(){
154
+ $valid_pixel_id = !empty(FacebookWordPressOptions:: getPixelId());
155
+ $valid_access_token = !empty(FacebookWordPressOptions::getAccessToken());
156
+ $message = '';
157
+ $plugin_name_tag = sprintf('<strong>%s</strong>',
158
+ FacebookPluginConfig::PLUGIN_NAME);
159
+ if($valid_pixel_id){
160
+ if($valid_access_token){
161
+ $message = sprintf('Easily manage your connection to Facebook with %s.',
162
+ $plugin_name_tag);
163
  }
164
+ else{
165
+ $message = sprintf('%s gives you access to the Conversions API.',
166
+ $plugin_name_tag);
167
+ }
168
+ }
169
+ else{
170
+ $message = sprintf('%s is almost ready.', $plugin_name_tag);
171
  }
172
+ return $message.' To complete your configuration, '.
173
+ '<a href="%s">follow the setup steps.</a>';
174
  }
175
 
176
  public function setNotice($notice, $dismiss_config) {
178
  FacebookPluginConfig::ADMIN_MENU_SLUG);
179
 
180
  $link = sprintf(
181
+ $notice,
 
 
182
  esc_url($url));
183
  printf(
184
  '
199
  FacebookPluginConfig::TEXT_DOMAIN));
200
  }
201
 
202
+ public function fbeNotInstalledNotice() {
203
+ $message = $this->getCustomizedFbeNotInstalledNotice();
204
  $this->setNotice(
205
+ __(
206
+ $message,
207
  FacebookPluginConfig::TEXT_DOMAIN),
208
+ FacebookPluginConfig::ADMIN_DISMISS_FBE_NOT_INSTALLED_NOTICE);
 
 
 
 
 
 
 
 
 
209
  }
210
 
211
  public function dismissNotices() {
212
  $user_id = get_current_user_id();
213
+ if (isset(
214
+ $_GET[FacebookPluginConfig::ADMIN_DISMISS_FBE_NOT_INSTALLED_NOTICE]
215
+ )){
216
  update_user_meta($user_id,
217
+ FacebookPluginConfig::ADMIN_IGNORE_FBE_NOT_INSTALLED_NOTICE,
218
  true);
219
  }
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
  }
core/FacebookWordpressSettingsRecorder.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace FacebookPixelPlugin\Core;
3
+
4
+ class FacebookWordpressSettingsRecorder {
5
+
6
+ public function init(){
7
+ add_action('wp_ajax_save_fbe_settings', array($this, 'saveFbeSettings'));
8
+ add_action('wp_ajax_delete_fbe_settings',
9
+ array($this, 'deleteFbeSettings')
10
+ );
11
+ }
12
+
13
+ private function handleSuccessRequest($body){
14
+ $res = array(
15
+ 'success' => true,
16
+ 'msg' => $body,
17
+ );
18
+ wp_send_json($res);
19
+ return $res;
20
+ }
21
+
22
+ private function handleUnauthorizedRequest(){
23
+ $res = array(
24
+ 'success' => false,
25
+ 'msg' => 'Unauthorized user',
26
+ );
27
+ wp_send_json($res);
28
+ return $res;
29
+ }
30
+
31
+ public function saveFbeSettings(){
32
+ if (!current_user_can('administrator')) {
33
+ $this->handleUnauthorizedRequest();
34
+ }
35
+ $pixel_id = $_POST['pixelId'];
36
+ $access_token = $_POST['accessToken'];
37
+ $external_business_id = $_POST['externalBusinessId'];
38
+ $settings = array(
39
+ FacebookPluginConfig::PIXEL_ID_KEY => $pixel_id,
40
+ FacebookPluginConfig::ACCESS_TOKEN_KEY => $access_token,
41
+ FacebookPluginConfig::EXTERNAL_BUSINESS_ID_KEY =>
42
+ $external_business_id,
43
+ FacebookPluginConfig::IS_FBE_INSTALLED_KEY => '1'
44
+ );
45
+ \update_option(
46
+ FacebookPluginConfig::SETTINGS_KEY,
47
+ $settings
48
+ );
49
+ return $this->handleSuccessRequest($settings);
50
+ }
51
+
52
+ public function deleteFbeSettings(){
53
+ if (!current_user_can('administrator')) {
54
+ $this->handleUnauthorizedRequest();
55
+ }
56
+ \delete_option( FacebookPluginConfig::SETTINGS_KEY );
57
+ \delete_transient( FacebookPluginConfig::AAM_SETTINGS_KEY );
58
+ return $this->handleSuccessRequest('Done');
59
+ }
60
+ }
core/ServerEventAsyncTask.php CHANGED
@@ -19,16 +19,102 @@ namespace FacebookPixelPlugin\Core;
19
 
20
  use FacebookPixelPlugin\Core\FacebookServerSideEvent;
21
 
 
 
 
 
 
22
  defined('ABSPATH') or die('Direct access not allowed');
23
 
24
  class ServerEventAsyncTask extends \WP_Async_Task {
25
  protected $action = 'send_server_events';
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  protected function prepare_data($data) {
28
  try {
29
  if (!empty($data)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  return array(
31
- 'event_data' => base64_encode(serialize($data[0])),
32
  'num_events'=>$data[1]
33
  );
34
  }
@@ -45,14 +131,19 @@ class ServerEventAsyncTask extends \WP_Async_Task {
45
  if( $num_events == 0 ){
46
  return;
47
  }
48
- $events = unserialize(base64_decode($_POST['event_data']));
49
- // When an array has just one object, the deserialization process
50
- // returns just the object
51
- // and we want an array
52
- if( $num_events == 1 ){
53
- $events = array( $events );
 
 
 
 
 
 
54
  }
55
-
56
  FacebookServerSideEvent::send($events);
57
  }
58
  catch (\Exception $ex) {
19
 
20
  use FacebookPixelPlugin\Core\FacebookServerSideEvent;
21
 
22
+ use FacebookAds\Object\ServerSide\Event;
23
+ use FacebookAds\Object\ServerSide\UserData;
24
+ use FacebookAds\Object\ServerSide\CustomData;
25
+ use FacebookAds\Object\ServerSide\Content;
26
+
27
  defined('ABSPATH') or die('Direct access not allowed');
28
 
29
  class ServerEventAsyncTask extends \WP_Async_Task {
30
  protected $action = 'send_server_events';
31
 
32
+ private function convert_user_data($user_data_normalized){
33
+ $norm_key_to_key = [
34
+ AAMSettingsFields::EMAIL => 'email',
35
+ AAMSettingsFields::FIRST_NAME => 'first_name',
36
+ AAMSettingsFields::LAST_NAME => 'last_name',
37
+ AAMSettingsFields::GENDER => 'gender',
38
+ AAMSettingsFields::DATE_OF_BIRTH => 'date_of_birth',
39
+ AAMSettingsFields::EXTERNAL_ID => 'external_id',
40
+ AAMSettingsFields::PHONE => 'phone',
41
+ AAMSettingsFields::CITY => 'city',
42
+ AAMSettingsFields::STATE => 'state',
43
+ AAMSettingsFields::ZIP_CODE => 'zip_code',
44
+ AAMSettingsFields::COUNTRY => 'country_code',
45
+ ];
46
+ $user_data = array();
47
+ foreach($user_data_normalized as $norm_key => $field){
48
+ if(array_key_exists($norm_key, $norm_key_to_key)){
49
+ $user_data[$norm_key_to_key[$norm_key]] = $field;
50
+ }
51
+ else{
52
+ $user_data[$norm_key] = $field;
53
+ }
54
+ }
55
+ return $user_data;
56
+ }
57
+
58
+ private function convert_array_to_event($event_as_array){
59
+ $event = new Event($event_as_array);
60
+ // If user_data exists, an UserData object is created
61
+ // and set
62
+ if(array_key_exists('user_data', $event_as_array)){
63
+ // The method convert_user_data converts the keys used in the
64
+ // normalized array to the keys used in the constructor of UserData
65
+ $user_data = new UserData($this->convert_user_data(
66
+ $event_as_array['user_data']
67
+ ));
68
+ $event->setUserData($user_data);
69
+ }
70
+ // If custom_data exists, a CustomData object is created and set
71
+ if(array_key_exists('custom_data', $event_as_array)){
72
+ $custom_data = new CustomData($event_as_array['custom_data']);
73
+ // If contents exists in custom_data, an array of Content is created
74
+ // and set
75
+ if(array_key_exists('contents', $event_as_array['custom_data'])){
76
+ $contents = array();
77
+ foreach(
78
+ $event_as_array['custom_data']['contents'] as $contents_as_array
79
+ ){
80
+ // The normalized contents array encodes product id as id
81
+ // but the constructor of Content requires product_id
82
+ if(array_key_exists('id', $contents_as_array)){
83
+ $contents_as_array['product_id'] = $contents_as_array['id'];
84
+ }
85
+ $contents[] = new Content($contents_as_array);
86
+ }
87
+ $custom_data->setContents($contents);
88
+ }
89
+ if(array_key_exists('fb_integration_tracking',
90
+ $event_as_array['custom_data'])){
91
+ $custom_data->addCustomProperty('fb_integration_tracking',
92
+ $event_as_array['custom_data']['fb_integration_tracking']);
93
+ }
94
+ $event->setCustomData($custom_data);
95
+ }
96
+ return $event;
97
+ }
98
+
99
  protected function prepare_data($data) {
100
  try {
101
  if (!empty($data)) {
102
+ $num_events = $data[1];
103
+ $events = $data[0];
104
+ // $data[0] can be a single event or an array
105
+ // We want to receive it as an array
106
+ if($num_events == 1){
107
+ $events = array($events);
108
+ }
109
+ // Each event is casted to a php array with normalize()
110
+ $events_as_array = array();
111
+ foreach($events as $event){
112
+ $events_as_array[] = $event->normalize();
113
+ }
114
+ // The array of events is converted to a JSON string
115
+ // and encoded in base 64
116
  return array(
117
+ 'event_data' => base64_encode(json_encode($events_as_array)),
118
  'num_events'=>$data[1]
119
  );
120
  }
131
  if( $num_events == 0 ){
132
  return;
133
  }
134
+ // $_POST['event_data'] is decoded from base 64, returning a JSON string
135
+ // and decoded as a php array
136
+ $events_as_array = json_decode(base64_decode($_POST['event_data']), true);
137
+ // If the passed json string is invalid, no processing is done
138
+ if(!$events_as_array){
139
+ return;
140
+ }
141
+ $events = array();
142
+ // Every event is a php array and casted to an Event object
143
+ foreach( $events_as_array as $event_as_array ){
144
+ $event = $this->convert_array_to_event($event_as_array);
145
+ $events[] = $event;
146
  }
 
147
  FacebookServerSideEvent::send($events);
148
  }
149
  catch (\Exception $ex) {
core/ServerEventFactory.php CHANGED
@@ -20,6 +20,10 @@ namespace FacebookPixelPlugin\Core;
20
  use FacebookAds\Object\ServerSide\Event;
21
  use FacebookAds\Object\ServerSide\UserData;
22
  use FacebookAds\Object\ServerSide\CustomData;
 
 
 
 
23
  use FacebookPixelPlugin\Core\EventIdGenerator;
24
  use FacebookPixelPlugin\Core\FacebookWordpressOptions;
25
 
@@ -134,6 +138,41 @@ class ServerEventFactory {
134
  | FILTER_FLAG_NO_RES_RANGE);
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  public static function safeCreateEvent(
138
  $event_name,
139
  $callback,
@@ -145,79 +184,124 @@ class ServerEventFactory {
145
 
146
  try {
147
  $data = call_user_func_array($callback, $arguments);
148
-
149
- if (FacebookWordpressOptions::getUsePii()) {
150
- $user_data = $event->getUserData();
151
- if (!empty($data['email'])) {
152
- $user_data->setEmail($data['email']);
153
- }
154
-
155
- if (!empty($data['first_name'])) {
156
- $user_data->setFirstName($data['first_name']);
157
- }
158
-
159
- if (!empty($data['last_name'])) {
160
- $user_data->setLastName($data['last_name']);
161
- }
162
-
163
- if (!empty($data['phone'])) {
164
- $user_data->setPhone($data['phone']);
165
- }
166
-
167
- if(!empty($data['state'])){
168
- $user_data->setState($data['state']);
169
- }
170
-
171
- if(!empty($data['country'])){
172
- $user_data->setCountryCode($data['country']);
173
- }
174
-
175
- if(!empty($data['city'])){
176
- $user_data->setCity($data['city']);
177
- }
178
-
179
- if(!empty($data['zip'])){
180
- $user_data->setZipCode($data['zip']);
181
- }
182
-
183
- if(!empty($data['gender'])){
184
- $user_data->setGender($data['gender']);
185
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
187
 
188
  $custom_data = $event->getCustomData();
189
  $custom_data->addCustomProperty('fb_integration_tracking', $integration);
190
 
191
  if (!empty($data['currency'])) {
192
- $custom_data->setCurrency($data['currency']);
193
  }
194
 
195
  if (!empty($data['value'])) {
196
- $custom_data->setValue($data['value']);
197
  }
198
 
199
  if (!empty($data['contents'])) {
200
- $custom_data->setContents($data['contents']);
201
  }
202
 
203
  if (!empty($data['content_ids'])) {
204
- $custom_data->setContentIds($data['content_ids']);
205
  }
206
 
207
  if (!empty($data['content_type'])) {
208
- $custom_data->setContentType($data['content_type']);
209
  }
210
 
211
  if (!empty($data['num_items'])) {
212
- $custom_data->setNumItems($data['num_items']);
213
  }
214
 
215
  if (!empty($data['content_name'])) {
216
- $custom_data->setContentName($data['content_name']);
217
  }
218
 
219
  if (!empty($data['content_category'])){
220
- $custom_data->setContentCategory($data['content_category']);
221
  }
222
  } catch (\Exception $e) {
223
  // Need to log
20
  use FacebookAds\Object\ServerSide\Event;
21
  use FacebookAds\Object\ServerSide\UserData;
22
  use FacebookAds\Object\ServerSide\CustomData;
23
+ use FacebookAds\Object\ServerSide\Normalizer;
24
+
25
+ use FacebookPixelPlugin\Core\AAMFieldsExtractor;
26
+ use FacebookPixelPlugin\Core\AAMSettingsFields;
27
  use FacebookPixelPlugin\Core\EventIdGenerator;
28
  use FacebookPixelPlugin\Core\FacebookWordpressOptions;
29
 
138
  | FILTER_FLAG_NO_RES_RANGE);
139
  }
140
 
141
+ /*
142
+ Given that the data extracted by the integration classes is a mix of
143
+ user data and custom data,
144
+ this function splits these fields in two arrays
145
+ and user data is formatted with the AAM field setting
146
+ */
147
+ private static function splitUserDataAndCustomData($data){
148
+ $user_data = array();
149
+ $custom_data = array();
150
+ $key_to_aam_field = array(
151
+ 'email' => AAMSettingsFields::EMAIL,
152
+ 'first_name' => AAMSettingsFields::FIRST_NAME,
153
+ 'last_name' => AAMSettingsFields::LAST_NAME,
154
+ 'phone' => AAMSettingsFields::PHONE,
155
+ 'state' => AAMSettingsFields::STATE,
156
+ 'country' => AAMSettingsFields::COUNTRY,
157
+ 'city' => AAMSettingsFields::CITY,
158
+ 'zip' => AAMSettingsFields::ZIP_CODE,
159
+ 'gender' => AAMSettingsFields::GENDER,
160
+ 'date_of_birth' => AAMSettingsFields::DATE_OF_BIRTH,
161
+ );
162
+ foreach( $data as $key => $value ){
163
+ if( array_key_exists( $key, $key_to_aam_field ) ){
164
+ $user_data[$key_to_aam_field[$key]] = $value;
165
+ }
166
+ else{
167
+ $custom_data[$key] = $value;
168
+ }
169
+ }
170
+ return array(
171
+ 'user_data' => $user_data,
172
+ 'custom_data' => $custom_data
173
+ );
174
+ }
175
+
176
  public static function safeCreateEvent(
177
  $event_name,
178
  $callback,
184
 
185
  try {
186
  $data = call_user_func_array($callback, $arguments);
187
+ $data_split = self::splitUserDataAndCustomData($data);
188
+ $user_data_array = $data_split['user_data'];
189
+ $custom_data_array = $data_split['custom_data'];
190
+ $user_data_array =
191
+ AAMFieldsExtractor::getNormalizedUserData($user_data_array);
192
+
193
+ $user_data = $event->getUserData();
194
+
195
+ if(
196
+ array_key_exists(AAMSettingsFields::EMAIL, $user_data_array)
197
+ ){
198
+ $user_data->setEmail(
199
+ $user_data_array[AAMSettingsFields::EMAIL]
200
+ );
201
+ }
202
+ if(
203
+ array_key_exists(AAMSettingsFields::FIRST_NAME, $user_data_array)
204
+ ){
205
+ $user_data->setFirstName(
206
+ $user_data_array[AAMSettingsFields::FIRST_NAME]
207
+ );
208
+ }
209
+ if(
210
+ array_key_exists(AAMSettingsFields::LAST_NAME, $user_data_array)
211
+ ){
212
+ $user_data->setLastName(
213
+ $user_data_array[AAMSettingsFields::LAST_NAME]
214
+ );
215
+ }
216
+ if(
217
+ array_key_exists(AAMSettingsFields::GENDER, $user_data_array)
218
+ ){
219
+ $user_data->setGender(
220
+ $user_data_array[AAMSettingsFields::GENDER]
221
+ );
222
+ }
223
+ if(
224
+ array_key_exists(AAMSettingsFields::DATE_OF_BIRTH, $user_data_array)
225
+ ){
226
+ $user_data->setDateOfBirth(
227
+ $user_data_array[AAMSettingsFields::DATE_OF_BIRTH]);
228
+ }
229
+ if(
230
+ array_key_exists(AAMSettingsFields::EXTERNAL_ID, $user_data_array)
231
+ ){
232
+ $user_data->setExternalId(
233
+ Util::hash($user_data_array[AAMSettingsFields::EXTERNAL_ID])
234
+ );
235
+ }
236
+ if(
237
+ array_key_exists(AAMSettingsFields::PHONE, $user_data_array)
238
+ ){
239
+ $user_data->setPhone(
240
+ $user_data_array[AAMSettingsFields::PHONE]
241
+ );
242
+ }
243
+ if(
244
+ array_key_exists(AAMSettingsFields::CITY, $user_data_array)
245
+ ){
246
+ $user_data->setCity(
247
+ $user_data_array[AAMSettingsFields::CITY]
248
+ );
249
+ }
250
+ if(
251
+ array_key_exists(AAMSettingsFields::STATE, $user_data_array)
252
+ ){
253
+ $user_data->setState(
254
+ $user_data_array[AAMSettingsFields::STATE]
255
+ );
256
+ }
257
+ if(
258
+ array_key_exists(AAMSettingsFields::ZIP_CODE, $user_data_array)
259
+ ){
260
+ $user_data->setZipCode(
261
+ $user_data_array[AAMSettingsFields::ZIP_CODE]
262
+ );
263
+ }
264
+ if(
265
+ array_key_exists(AAMSettingsFields::COUNTRY, $user_data_array)
266
+ ){
267
+ $user_data->setCountryCode(
268
+ $user_data_array[AAMSettingsFields::COUNTRY]
269
+ );
270
  }
271
 
272
  $custom_data = $event->getCustomData();
273
  $custom_data->addCustomProperty('fb_integration_tracking', $integration);
274
 
275
  if (!empty($data['currency'])) {
276
+ $custom_data->setCurrency($custom_data_array['currency']);
277
  }
278
 
279
  if (!empty($data['value'])) {
280
+ $custom_data->setValue($custom_data_array['value']);
281
  }
282
 
283
  if (!empty($data['contents'])) {
284
+ $custom_data->setContents($custom_data_array['contents']);
285
  }
286
 
287
  if (!empty($data['content_ids'])) {
288
+ $custom_data->setContentIds($custom_data_array['content_ids']);
289
  }
290
 
291
  if (!empty($data['content_type'])) {
292
+ $custom_data->setContentType($custom_data_array['content_type']);
293
  }
294
 
295
  if (!empty($data['num_items'])) {
296
+ $custom_data->setNumItems($custom_data_array['num_items']);
297
  }
298
 
299
  if (!empty($data['content_name'])) {
300
+ $custom_data->setContentName($custom_data_array['content_name']);
301
  }
302
 
303
  if (!empty($data['content_category'])){
304
+ $custom_data->setContentCategory($custom_data_array['content_category']);
305
  }
306
  } catch (\Exception $e) {
307
  // Need to log
facebook-for-wordpress.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
- * Plugin Name: Official Facebook Pixel
4
  * Plugin URI: https://www.facebook.com/business/help/881403525362441
5
  * Description: <strong><em>***ATTENTION: After upgrade the plugin may be deactivated due to a known issue, to workaround please refresh this page and activate plugin.***</em></strong> The Facebook pixel is an analytics tool that helps you measure the effectiveness of your advertising. You can use the Facebook pixel to understand the actions people are taking on your website and reach audiences you care about.
6
  * Author: Facebook
7
  * Author URI: https://www.facebook.com/
8
- * Version: 2.2.2
9
  * Text Domain: official-facebook-pixel
10
  */
11
 
@@ -36,6 +36,7 @@ use FacebookPixelPlugin\Core\FacebookPluginConfig;
36
  use FacebookPixelPlugin\Core\FacebookWordpressOptions;
37
  use FacebookPixelPlugin\Core\FacebookWordpressPixelInjection;
38
  use FacebookPixelPlugin\Core\FacebookWordpressSettingsPage;
 
39
  use FacebookPixelPlugin\Core\ServerEventAsyncTask;
40
 
41
  class FacebookForWordpress {
@@ -77,6 +78,7 @@ class FacebookForWordpress {
77
  if (is_admin()) {
78
  $plugin_name = plugin_basename(__FILE__);
79
  new FacebookWordpressSettingsPage($plugin_name);
 
80
  }
81
  }
82
  }
1
  <?php
2
  /**
3
+ * Plugin Name: Facebook for WordPress
4
  * Plugin URI: https://www.facebook.com/business/help/881403525362441
5
  * Description: <strong><em>***ATTENTION: After upgrade the plugin may be deactivated due to a known issue, to workaround please refresh this page and activate plugin.***</em></strong> The Facebook pixel is an analytics tool that helps you measure the effectiveness of your advertising. You can use the Facebook pixel to understand the actions people are taking on your website and reach audiences you care about.
6
  * Author: Facebook
7
  * Author URI: https://www.facebook.com/
8
+ * Version: 3.0.0
9
  * Text Domain: official-facebook-pixel
10
  */
11
 
36
  use FacebookPixelPlugin\Core\FacebookWordpressOptions;
37
  use FacebookPixelPlugin\Core\FacebookWordpressPixelInjection;
38
  use FacebookPixelPlugin\Core\FacebookWordpressSettingsPage;
39
+ use FacebookPixelPlugin\Core\FacebookWordpressSettingsRecorder;
40
  use FacebookPixelPlugin\Core\ServerEventAsyncTask;
41
 
42
  class FacebookForWordpress {
78
  if (is_admin()) {
79
  $plugin_name = plugin_basename(__FILE__);
80
  new FacebookWordpressSettingsPage($plugin_name);
81
+ (new FacebookWordpressSettingsRecorder())->init();
82
  }
83
  }
84
  }
integration/FacebookWordpressEasyDigitalDownloads.php CHANGED
@@ -122,8 +122,7 @@ jQuery(document).ready(function ($) {
122
  }
123
 
124
  public static function injectAddToCartEventId(){
125
- if(FacebookPluginUtils::isInternalUser()
126
- || !FacebookWordpressOptions::getUseS2S()){
127
  return;
128
  }
129
  $eventId = EventIdGenerator::guidv4();
122
  }
123
 
124
  public static function injectAddToCartEventId(){
125
+ if(FacebookPluginUtils::isInternalUser()){
 
126
  return;
127
  }
128
  $eventId = EventIdGenerator::guidv4();
js/fbe_allinone.js ADDED
@@ -0,0 +1,21734 @@