Version Description
Download this release
Release Info
Developer | |
Plugin | Official Facebook Pixel |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.2.2 to 3.0.0
- changelog.txt +4 -0
- core/AAMFieldsExtractor.php +84 -0
- core/AAMSettingsFields.php +46 -0
- core/FacebookPluginConfig.php +21 -8
- core/FacebookServerSideEvent.php +19 -13
- core/FacebookWordpressOptions.php +168 -50
- core/FacebookWordpressPixelInjection.php +8 -10
- core/FacebookWordpressSettingsPage.php +125 -256
- core/FacebookWordpressSettingsRecorder.php +60 -0
- core/ServerEventAsyncTask.php +99 -8
- core/ServerEventFactory.php +130 -46
- facebook-for-wordpress.php +4 -2
- integration/FacebookWordpressEasyDigitalDownloads.php +1 -2
- js/fbe_allinone.js +21734 -0
- languages/official-facebook-pixel-ar_AR.po +3 -3
- languages/official-facebook-pixel-cs_CZ.po +3 -3
- languages/official-facebook-pixel-da_DK.po +3 -3
- languages/official-facebook-pixel-de_DE.po +3 -3
- languages/official-facebook-pixel-en_GB.po +3 -3
- languages/official-facebook-pixel-es_ES.po +3 -3
- languages/official-facebook-pixel-es_LA.po +3 -3
- languages/official-facebook-pixel-fi_FI.po +3 -3
- languages/official-facebook-pixel-fr_CA.po +3 -3
- languages/official-facebook-pixel-fr_FR.po +3 -3
- languages/official-facebook-pixel-he_IL.po +3 -3
- languages/official-facebook-pixel-it_IT.po +3 -3
- languages/official-facebook-pixel-ja_JP.po +3 -3
- languages/official-facebook-pixel-ko_KR.po +3 -3
- languages/official-facebook-pixel-nb_NO.po +3 -3
- languages/official-facebook-pixel-nl_NL.po +3 -3
- languages/official-facebook-pixel-pl_PL.po +3 -3
- languages/official-facebook-pixel-pt_BR.po +3 -3
- languages/official-facebook-pixel-pt_PT.po +3 -3
- languages/official-facebook-pixel-ru_RU.po +3 -3
- languages/official-facebook-pixel-sv_SE.po +3 -3
- languages/official-facebook-pixel-th_TH.po +3 -3
- languages/official-facebook-pixel-tr_TR.po +3 -3
- languages/official-facebook-pixel-vi_VN.po +3 -3
- languages/official-facebook-pixel-zh_CN.po +3 -3
- languages/official-facebook-pixel-zh_TW.po +3 -3
- languages/official-facebook-pixel.pot +4 -4
- readme.txt +15 -7
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- 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 = '
|
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
|
48 |
-
const
|
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(
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
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 |
-
$
|
|
|
|
|
|
|
|
|
93 |
|
94 |
-
|
95 |
->setEvents($events)
|
96 |
->setPartnerAgent($agent);
|
97 |
|
98 |
-
|
|
|
|
|
|
|
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::
|
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 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
}
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
return (is_null(FacebookPluginConfig::USE_S2S_DEFAULT)
|
56 |
-
|| !FacebookPluginConfig::USE_S2S_DEFAULT) ? '0' : '1';
|
57 |
}
|
58 |
|
59 |
-
private static function
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
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 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
}
|
81 |
|
@@ -87,30 +126,35 @@ class FacebookWordpressOptions {
|
|
87 |
return self::getDefaultPixelID();
|
88 |
}
|
89 |
|
90 |
-
public static function
|
91 |
-
if
|
92 |
-
FacebookPluginConfig::
|
93 |
-
|
|
|
|
|
94 |
}
|
95 |
|
96 |
-
return self::
|
97 |
}
|
98 |
|
99 |
-
public static function
|
100 |
-
if
|
101 |
-
FacebookPluginConfig::
|
102 |
-
|
|
|
|
|
103 |
}
|
104 |
|
105 |
-
return self::
|
106 |
}
|
107 |
|
108 |
-
public static function
|
109 |
-
if (array_key_exists(
|
110 |
-
|
|
|
111 |
}
|
112 |
|
113 |
-
return self::
|
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 |
-
$
|
133 |
-
|
134 |
-
// User not logged in or admin chose not to send PII.
|
135 |
self::$userInfo = array();
|
136 |
} else {
|
137 |
-
|
138 |
array(
|
139 |
// Keys documented in
|
140 |
// https://developers.facebook.com/docs/facebook-pixel/pixel-with-ads/conversion-tracking#advanced_match
|
141 |
-
|
142 |
-
|
143 |
-
|
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 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
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
|
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, '
|
43 |
}
|
44 |
|
45 |
-
public function
|
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 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
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 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
$pixel_id
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
<p
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
isset($pixel_id)
|
142 |
-
? esc_attr($pixel_id)
|
143 |
-
: '',
|
144 |
-
$description);
|
145 |
}
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
''
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
'
|
161 |
-
|
162 |
-
|
163 |
-
'
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
169 |
|
170 |
-
public function
|
171 |
-
$
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
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 |
-
|
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::
|
268 |
-
true))
|
269 |
-
|
270 |
-
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
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
|
|
|
305 |
$this->setNotice(
|
306 |
-
__(
|
307 |
-
|
308 |
FacebookPluginConfig::TEXT_DOMAIN),
|
309 |
-
FacebookPluginConfig::
|
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(
|
|
|
|
|
324 |
update_user_meta($user_id,
|
325 |
-
FacebookPluginConfig::
|
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(
|
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 |
-
|
49 |
-
//
|
50 |
-
|
51 |
-
//
|
52 |
-
if(
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
$
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
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($
|
193 |
}
|
194 |
|
195 |
if (!empty($data['value'])) {
|
196 |
-
$custom_data->setValue($
|
197 |
}
|
198 |
|
199 |
if (!empty($data['contents'])) {
|
200 |
-
$custom_data->setContents($
|
201 |
}
|
202 |
|
203 |
if (!empty($data['content_ids'])) {
|
204 |
-
$custom_data->setContentIds($
|
205 |
}
|
206 |
|
207 |
if (!empty($data['content_type'])) {
|
208 |
-
$custom_data->setContentType($
|
209 |
}
|
210 |
|
211 |
if (!empty($data['num_items'])) {
|
212 |
-
$custom_data->setNumItems($
|
213 |
}
|
214 |
|
215 |
if (!empty($data['content_name'])) {
|
216 |
-
$custom_data->setContentName($
|
217 |
}
|
218 |
|
219 |
if (!empty($data['content_category'])){
|
220 |
-
$custom_data->setContentCategory($
|
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:
|
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:
|
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 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|