JezK
Edit File: class-facebookpixel.php
<?php /** * Facebook Pixel Plugin FacebookPixel class. * * This file contains the main logic for FacebookPixel. * * @package FacebookPixelPlugin */ /** * Define FacebookPixel class. * * @return void */ /* * Copyright (C) 2017-present, Meta, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ namespace FacebookPixelPlugin\Core; defined( 'ABSPATH' ) || die( 'Direct access not allowed' ); use ReflectionClass; /** * Class FacebookPixel */ class FacebookPixel { const ADDPAYMENTINFO = 'AddPaymentInfo'; const ADDTOCART = 'AddToCart'; const ADDTOWISHLIST = 'AddToWishlist'; const COMPLETEREGISTRATION = 'CompleteRegistration'; const CONTACT = 'Contact'; const CUSTOMIZEPRODUCT = 'CustomizeProduct'; const DONATE = 'Donate'; const FINDLOCATION = 'FindLocation'; const INITIATECHECKOUT = 'InitiateCheckout'; const LEAD = 'Lead'; const PAGEVIEW = 'PageView'; const PURCHASE = 'Purchase'; const SCHEDULE = 'Schedule'; const SEARCH = 'Search'; const STARTTRIAL = 'StartTrial'; const SUBMITAPPLICATION = 'SubmitApplication'; const SUBSCRIBE = 'Subscribe'; const VIEWCONTENT = 'ViewContent'; const FB_INTEGRATION_TRACKING_KEY = 'fb_integration_tracking'; /** * The Facebook Pixel ID. * * @var string */ private static $pixel_id = ''; /** * The Facebook Pixel base code. * * @var string */ private static $pixel_base_code = " <!-- Meta Pixel Code --> <script type='text/javascript'> !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','https://connect.facebook.net/en_US/fbevents.js'); </script> <!-- End Meta Pixel Code --> "; /** * The Facebook Pixel fbq code without script. * * @var string */ private static $pixel_fbq_code_without_script = " fbq('%s', '%s'%s%s); "; /** * The Facebook Pixel noscript code. * * @var string */ private static $pixel_noscript_code = ' <!-- Meta Pixel Code --> <noscript> <img height="1" width="1" style="display:none" alt="fbpx" src="https://www.facebook.com/tr?id=%s&ev=%s%s&noscript=1" /> </noscript> <!-- End Meta Pixel Code --> '; /** * Initializes the Facebook Pixel with the given pixel ID. * * @param string $pixel_id The Facebook Pixel ID to be set. * Defaults to an empty string. */ public static function initialize( $pixel_id = '' ) { self::$pixel_id = $pixel_id; } /** * Gets FB pixel ID */ public static function get_pixel_id() { return self::$pixel_id; } /** * Sets FB pixel ID * * @param string $pixel_id The Facebook Pixel ID to be set. */ public static function set_pixel_id( $pixel_id ) { self::$pixel_id = $pixel_id; } /** * Gets FB pixel base code */ public static function get_pixel_base_code() { return self::$pixel_base_code; } /** * Gets FB pixel track code * $param is the parameter for the pixel event. * If it is an array, FB_INTEGRATION_TRACKING_KEY parameter with * $tracking_name value will automatically * be added into the $param. If it is a string, please append the * FB_INTEGRATION_TRACKING_KEY parameter * with its tracking name into the JS Parameter block * * @param string $event The name of the pixel event. * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the script tag in * the pixel track code. * @return string The pixel track code. */ public static function get_pixel_track_code( $event, $param = array(), $tracking_name = '', $with_script_tag = true ) { if ( empty( self::$pixel_id ) ) { return; } if ( self::are_signals_held() ) { return self::get_pixel_queue_code( $event, $param, $tracking_name, $with_script_tag ); } $code = $with_script_tag ? "<script type='text/javascript'>" . self::$pixel_fbq_code_without_script . '</script>' : self::$pixel_fbq_code_without_script; $param_str = $param; if ( is_array( $param ) ) { if ( ! empty( $tracking_name ) ) { $param[ self::FB_INTEGRATION_TRACKING_KEY ] = $tracking_name; } $param_str = wp_json_encode( $param, JSON_PRETTY_PRINT ); } $class = new ReflectionClass( __CLASS__ ); $const_name = strtoupper( (string) $event ); return sprintf( $code, $class->hasConstant( $const_name ) ? 'track' : 'trackCustom', $event, ', ' . $param_str, '' ); } /** * Gets queueing code for a held event. * * @param string $event Event name. * @param array $param Event parameters. * @param string $tracking_name Integration tracking name. * @param bool $with_script_tag Whether to include a script wrapper. * * @return string */ private static function get_pixel_queue_code( $event, $param, $tracking_name, $with_script_tag ) { $is_custom = ( new ReflectionClass( __CLASS__ ) ) ->getConstant( strtoupper( $event ) ) === false; if ( is_array( $param ) ) { $payload = self::build_queue_payload( $event, $param, $tracking_name, $is_custom ); $code = 'FacebookSignal.queueEvent(' . wp_json_encode( $payload, JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ) . ');'; } else { $code = sprintf( 'FacebookSignal.queueEvent({"event_name":%s,' . '"custom_data":%s,"event_id":null,"event_time":%d,' . '"is_custom":%s});', wp_json_encode( $event, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ), (string) $param, time(), $is_custom ? 'true' : 'false' ); } if ( ! $with_script_tag ) { return $code; } return "<script type='text/javascript'>{$code}</script>"; } /** * Build queue payload for a held event. * * @param string $event Event name. * @param array|string $param Event params. * @param string $tracking_name Integration tracking name. * @param bool|null $is_custom Whether the event is a custom event; * null = auto-detect. * * @return array */ public static function build_queue_payload( $event, $param = array(), $tracking_name = '', $is_custom = null ) { $custom_data = is_array( $param ) ? $param : array(); $event_id = null; if ( isset( $custom_data['eventID'] ) ) { $event_id = $custom_data['eventID']; unset( $custom_data['eventID'] ); } if ( ! empty( $tracking_name ) ) { $custom_data[ self::FB_INTEGRATION_TRACKING_KEY ] = $tracking_name; } if ( null === $is_custom ) { $is_custom = ( new ReflectionClass( __CLASS__ ) ) ->getConstant( strtoupper( $event ) ) === false; } $payload = array( 'event_name' => $event, 'custom_data' => $custom_data, 'event_id' => $event_id, 'event_time' => time(), 'is_custom' => (bool) $is_custom, ); if ( ! empty( $event_id ) ) { $queued_user_data = FacebookSignalState::get_queued_user_data( $event_id ); if ( null !== $queued_user_data ) { $payload['user_data'] = $queued_user_data; } } return $payload; } /** * Whether signals are held for the current request. * * @return bool */ private static function are_signals_held() { return class_exists( '\FacebookPixelPlugin\Core\FacebookSignalState' ) && FacebookSignalState::is_held(); } /** * Gets FB pixel noscript code * * @param string $event The name of the pixel event. * @param array $cd The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. */ public static function get_pixel_noscript_code( $event = 'PageView', $cd = array(), $tracking_name = '' ) { if ( empty( self::$pixel_id ) ) { return; } $data = ''; foreach ( $cd as $k => $v ) { $data .= '&cd[' . $k . ']=' . $v; } if ( ! empty( $tracking_name ) ) { $data .= '&cd[' . self::FB_INTEGRATION_TRACKING_KEY . ']=' . $tracking_name; } return sprintf( self::$pixel_noscript_code, self::$pixel_id, $event, $data ); } /** * Gets FB pixel AddToCart code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the script * tag in the pixel track code. */ public static function get_pixel_add_to_cart_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::ADDTOCART, $param, $tracking_name, $with_script_tag ); } /** * Gets FB pixel InitiateCheckout code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the * script tag in the pixel track code. */ public static function get_pixel_initiate_checkout_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::INITIATECHECKOUT, $param, $tracking_name, $with_script_tag ); } /** * Gets FB pixel Lead code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the * script tag in the pixel track code. */ public static function get_pixel_lead_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::LEAD, $param, $tracking_name, $with_script_tag ); } /** * Gets FB pixel PageView code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the script * tag in the pixel track code. */ public static function get_pixel_page_view_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::PAGEVIEW, $param, $tracking_name, $with_script_tag ); } /** * Gets FB pixel Purchase code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the script * tag in the pixel track code. */ public static function get_pixel_purchase_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::PURCHASE, $param, $tracking_name, $with_script_tag ); } /** * Gets FB pixel ViewContent code * * @param array $param The parameters for the pixel event. * @param string $tracking_name The tracking name for the pixel event. * @param bool $with_script_tag Whether to include the script tag in * the pixel track code. */ public static function get_pixel_view_content_code( $param = array(), $tracking_name = '', $with_script_tag = true ) { return self::get_pixel_track_code( self::VIEWCONTENT, $param, $tracking_name, $with_script_tag ); } }