Support

Home Forums Event Espresso Premium Facebook Pixel – Populate Dynamically Fields From Event Espresso Event

Facebook Pixel – Populate Dynamically Fields From Event Espresso Event

Posted: November 11, 2018 at 4:55 pm

Viewing 13 reply threads


Ash

November 11, 2018 at 4:55 pm

I am using Event Espresso plugin on my wordpress site to host in person events. We need to integrate facebook standard events into the site for facebook advertising that we will be doing. We need help in pulling data dynamically from Event Espresso and populating facebook standard event pixel data.

We do not want to use facebook plugins or site specific plugin.

I have searched your support forums and read everything related to facebook pixel but still have not found my issue.

I need help with the following EVENT ESSPRESSO SUPPORT TODO in each function as we need to populate the Pixel data dynamically. Please can you tell me the custom code I need to write to achieve all of the below.

1. For Each Event Page:

// EVENT ESSPRESSO SUPPORT TODO: needs to only fire on an each event espresso event page. is there some code to check if it is a event page?

function add_fb_lead_event_to_header(){

$page_post_name = get_queried_object()->post_name;
#echo “post name = “; echo $page_post_name;

if(empty($page_post_name)) {
return;
}

// EVENT ESSPRESSO SUPPORT TODO: Need more elegant solution then this, can you suggest?
$pages = array(‘amazon-ppc-sponsored-ad’, ‘kk1’, ‘kk2’, ‘kkmm’, ‘dd1’, ‘ddd2’, ‘bigs’, ‘bigs2’, ‘oct’, ‘friday’, ‘friday2’);

if(in_array($page_post_name, $pages)) {
?>
<!– Facebook Pixel Code –>
<script>
fbq(‘track’, ‘ViewContent’, {
value: 0.10, //TODO EVENT ESSPRESSO SUPPORT: needs to be dynamic
currency: ‘GBP’, // hardcoded to ‘GBP’
content_name: ‘Content Name’, //TODO EVENT ESSPRESSO SUPPORT: needs to be dynamic (espresso event slug)
content_type: ‘product’, // Required for Dynamic Product Ads -> hardcoded to ‘product’
content_ids: ‘woo-123’ //TODO EVENT ESSPRESSO SUPPORT: Required for Dynamic Product Ads -> dynamic espresso event id
});
</script>
<!– End Facebook Pixel Code –>
<?php
}

}
add_action(‘wp_head’, ‘add_fb_lead_event_to_header’);

2. Initiate Checkout Page:

function add_fb_initiate_checkout_event_to_header(){

if(is_page(‘registration-checkout’)) {
?>
fbq(‘track’, ‘InitiateCheckout’, {
value: 0.10, // EVENT ESSPRESSO SUPPORT TODO: needs to be dynamic and total value of all tickets sold
currency: ‘GBP’, // hardcoded to ‘GBP’
content_name: ‘Checkout’, // hardcoded to ‘Checkout’
content_category: ‘Checkout’, // hardcoded to ‘Checkout’
content_ids: ‘woo-123’, //EVENT ESSPRESSO SUPPORT TODO: dynamic espresso event id
num_ids: 1 //EVENT ESSPRESSO SUPPORT TODO: dynamic number of espresso tickets bought
});
<?php
}

add_action(‘wp_head’, ‘add_fb_initiate_checkout_event_to_header’);

3. Thank You Page:

function add_fb_purchase_event_to_header(){

$pagename = get_query_var(‘pagename’);
//echo “page name = “; echo $pagename;

if($pagename == ‘thank-you’){

EE_Registry::instance()->load_model( ‘Transaction’ );
$transaction = EE_Registry::instance()->load_model( ‘Transaction’ )->get_transaction_from_reg_url_link();

if ( ! $transaction instanceof EE_Transaction ) {
exit();
}

$registrations = $transaction->registrations();

// FOR DEVELOPER: This maybe incorrect as if nultiple tickets are we getting correct total price?
foreach ($registrations as $key => $registration) {

if ( $_REQUEST[‘e_reg_url_link’] == $registration->reg_url_link() ) {

// DEBUG
#echo ‘

'; print_r($registration); echo '

‘;

//FB Tracking Code
?>
<script>
fbq(‘track’, ‘Purchase’, {
value: 10.00, // EVENT ESSPRESSO SUPPORT TODO: needs to be dynamic and total value of all tickets sold
currency: ‘GBP’, // hardcoded to ‘GBP’
content_name: ‘Product Name’, // EVENT ESSPRESSO SUPPORT TODO: needs to be dynamic (espresso event slug)
content_type: ‘product’, // hardcode to ‘product’
content_ids: ‘woo-123’, //EVENT ESSPRESSO SUPPORT TODO: dynamic espresso event id
num_items: 1 //EVENT ESSPRESSO SUPPORT TODO: dynamic number of espresso tickets bought
});

</script>

<?php
}
}
}
}

add_action( ‘wp_head’, ‘add_fb_purchase_event_to_header’ );

Please help!


Josh

  • Support Staff

November 12, 2018 at 4:42 pm

Hi Ash,

What you have in your example here, I’m afraid, isn’t going to work as is or even after a few fill in the blanks.

I’ll try help get you pointed in the right direction for making this happen:

1) First, you can use this conditional to make sure you’re on an event page:

<?php if(is_single('espresso_events')) {
  //do stuff here
} ?>

2) If you’re in the middle of inline JavaScript, you can grab a PHP value if need be e.g. if you’re on the event page, the event ID is also the post ID:
content_ids: <?php echo $post->ID; ?>

3) Getting the event ID from later checkout pages is tricky but possible. Here’s a gist that shows how to get the event ID from the active transaction:
https://gist.github.com/joshfeck/7887c8a0f984e11e50cf

Getting other information about the order (such as pricing, quantity of tickets, and so on) is also possible via the model system:
https://github.com/eventespresso/event-espresso-core/tree/master/docs/G–Model-System


Ash

November 16, 2018 at 6:11 am

Thanks Josh!

With what you provided I am nearly 90% there. Couple more questions…please could you help?

Also, to note, I am happy to share my full code once this is done as it will really help anyone using Facebook Ads or Google Ads to help in conversion tracking.

1) How do I get the ticket price from the event page? What model is available on that page? Can you send me some sample code? We could have multiple tickets available so we want to get the active ticket.

2) How can I get the number of tickets bought from the registration page?

I used following code to help me get the the price and event id from the transaction, but not sure where to look to get the number of tickets bought.
https://gist.github.com/joshfeck/7887c8a0f984e11e50cf

Appreciate your help.

Ash


Josh

  • Support Staff

November 16, 2018 at 2:21 pm

1) How do I get the ticket price from the event page? What model is available on that page? Can you send me some sample code?

I can share an example of how EE4 core gets tickets and their prices when it’s the event page (used to output the structured event data in the source of the page, read by search engines like Google)

https://github.com/eventespresso/event-espresso-core/blob/master/core/helpers/EEH_Schema.helper.php#L51

We could have multiple tickets available so we want to get the active ticket.

To clarify your statement about getting the active ticket, do you mean there are other tickets for the event, but they’re either no longer on sale and/or they haven’t gone on sale yet? If that’s the case, then you use the is_on_sale() method when you loop through the tickets. Here’s a link to its source:

https://github.com/eventespresso/event-espresso-core/blob/master/core/db_classes/EE_Ticket.class.php#L227

2) How can I get the number of tickets bought from the registration page?
I used following code to help me get the the price and event id from the transaction, but not sure where to look to get the number of tickets bought.

Where you’ve got the transaction object, you can do this:
count($transaction->registrations());

`


Ash

November 16, 2018 at 3:04 pm

Ok great point 2 works.

In regards to point one…how do I get a handle to the event object on the event page…is their a similar call to something like this but to get the event?


$checkout = EE_Registry::instance()->SSN->checkout();


Tony

  • Support Staff

November 19, 2018 at 4:27 am

It depends on the context of the code.

We have a helper method that attempts to pull in an EE_Event object in whichever way it can (based on the current post or an ID passed to the function), like so:

$event = EEH_Event_View::get_event($EVT_ID);

You can remove $EVT_ID from the above and EE will try to pull the event from the current global post object, or if you want to pass an ID, set it to the ID of the Event, if thats the current post you can use:

$event = EEH_Event_View::get_event( $post->ID );

I’d recommend taking a read of the documentation on our model system:

https://github.com/eventespresso/event-espresso-core/tree/master/docs/G–Model-System

We also have helpers within \event-espresso-core-reg\core\helpers\ for various different models.


Ash

November 19, 2018 at 6:36 pm

Here is my code that seems to be working for anyone else interested. Support team let me know if you spot any glaring mistakes here.


/**
* Code to trigger on every page.
*/
function onPageLoad() {

?>
<!-- Facebook Pixel Code -->
<!-- PageView -->
<script>
!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');
fbq('init', '<< ADD YOUR FB PIXEL ID HERE >>');
fbq('track', 'PageView');
</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=<< ADD YOUR FB PIXEL ID HERE >>&ev=PageView&noscript=1"
/></noscript>
<!-- End Facebook Pixel Code -->
<?php
}

add_action('wp_head', 'onPageLoad');

/**
* Code to trigger on event detail page.
*/
function onEventPageLoad() {

$post_type = get_post_type();

if ($post_type == 'espresso_events') {

$event_name = get_queried_object()->post_name;
#echo "event name = "; echo $event_name;

$event = EEH_Event_View::get_event( $post->ID );
#echo '

'; print_r($event); echo '

';

$price = 0;
foreach ($event->tickets() as $ticket) {
#echo '

 ** TicketID='; print_r($ticket->ID()); echo ', Available='; print_r($ticket->available()); echo ', Price='; print_r($ticket->price()); echo ' ** 

';
#echo '

'; print_r($ticket); echo '

';
if ($ticket->is_remaining() && !$ticket->is_expired()) {
$price = $ticket->price();
#echo '

Price='; print_r($price); echo '

';
break;
}
}
?>
<!-- Facebook Pixel Code -->
<script>
fbq('track', 'ViewContent', {
value: <?php echo $price ?>,
currency: 'GBP',
content_name: '<?php echo $event_name ?>',
content_type: 'product', // Required for Dynamic Product Ads
content_ids: '<?php echo get_the_ID(); ?>' //Required for Dynamic Product Ads -> Event Espresso Post ID
});
</script>
<!-- End Facebook Pixel Code -->
<?php
}

}
add_action('wp_head', 'onEventPageLoad');

/**
* Code to trigger on event registration page.
*/
function onEventInitiateCheckout(){

if (is_page('registration-checkout')) {

$checkout = EE_Registry::instance()->SSN->checkout();

if ( $checkout instanceof EE_Checkout ) {

$transaction = $checkout->transaction;
#echo '

** TRANSACTION **

';
#echo '

'; print_r($transaction); echo '

';

$transaction_total = $transaction->get('TXN_total');
#echo '

 TRANSACTION TOTAL='; print_r($transaction_total); echo '

';

if ( $transaction instanceof EE_Transaction ) {
foreach ( $transaction->registrations() as $registration ) {
if ( $registration instanceof EE_Registration ) {
$event = $registration->event();
if ( $event instanceof EE_Event ) {
$event_id = $event->ID();
$event_slug = $event->get(EVT_slug);
#echo '

 EventId='; print_r($event_id); echo '

';
}
}
}
}
}

?>

<!-- Facebook Pixel Code -->
<script>
fbq('track', 'InitiateCheckout', {
value: <?php echo $transaction_total; ?>,
currency: 'GBP',
content_name: '<?php echo $event_slug; ?>',
content_category: 'Checkout',
content_type: 'product', // Required for Dynamic Product Ads
content_ids: '<?php echo $event_id; ?>', //Required for Dynamic Product Ads -> dynamic espresso event id
num_ids: <?php echo count($transaction->registrations()); ?> //Number of espresso tickets bought
});
</script>
<!-- End Facebook Pixel Code -->
<?php
}
}

add_action('wp_head', 'onEventInitiateCheckout');

/**
* Code to trigger on checkout thank you page.
*/
function onEventCheckout() {

$pagename = get_query_var('pagename');
#echo "page name = "; echo $pagename;

if ($pagename == 'thank-you') {

$transaction = EE_Registry::instance()->load_model('Transaction')->get_transaction_from_reg_url_link();

if (!$transaction instanceof EE_Transaction) {
exit();
}

$registrations = $transaction->registrations();

foreach ($registrations as $key => $registration) {

if ($_REQUEST['e_reg_url_link'] == $registration->reg_url_link()) {

// DEBUG
#echo '

'; print_r($registration); echo '

';

$event = $registration->event();
if ( $event instanceof EE_Event ) {
$event_id = $event->ID();
$event_slug = $event->get(EVT_slug);
#echo '

 EventId='; print_r($event_id); echo '

';
}

//FB Tracking Code
?>
<script>
fbq('track', 'Purchase', {
value: <?php echo $registration->price_paid( ); ?>,
currency: 'GBP',
content_name: '<?php echo $event_slug; ?>', // Dynamic event name
content_type: 'product', // Required for Dynamic Product Ads
content_ids: '<?php echo $event_id; ?>', // Required for Dynamic Product Ads -> dynamic espresso event id
num_ids: <?php echo count($transaction->registrations()); ?> //Number of espresso tickets bought
});
</script>

<?php
}
}
}
}

add_action( 'wp_head', 'onEventCheckout' );


Ash

November 19, 2018 at 6:37 pm

Sorry for the bad formatting maybe Josh/Tony can make a gist to make the code more easily readable.


Ash

November 19, 2018 at 6:44 pm

<script src=”https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1.js”></script&gt;


Ash

November 19, 2018 at 6:45 pm

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1


Tony

  • Support Staff

November 20, 2018 at 4:40 am

Hi Ash,

Firstly, thank you for sharing your code, I’m sure some other users will find it useful.

There are a few places that could be improved to prevent errors and depending on the intention of the code could be incorrect under some use cases.

If you rename your gist filename to have the extension .php and add <?php to line 1 you’ll automatically have syntax highlighting from github.

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L34-L36

Can be condensed into just: if (get_post_type() === 'espresso_events') {

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L38-L42

That’s a lot of hoop jumping for the event name and then you use the global post anyway on the second line, try:

$event = EEH_Event_View::get_event();

if(! $event instanceof EE_Event ) {
    return;
}

(More on the event name below)

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L45-L53

If there is more than one ticket on the event, $price is always only going to be the price of whichever ticket is last in the loop, is that expected?

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L60

You have the EE_Event object, so rather than creating a variable to hold details from the event object, use the object directly for the name, like so:

<?php echo $event->name(); ?>

Same with the ID: <?php echo $event->ID(); ?>

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L89-L90

You’re using $transaction as an EE_Transaction object, just before actually checking if it is an EE_Transaction object, if it’s not (for whatever random reason) you’ll get a fatal. You could move that line just below Line 92, but if you already know you have an EE_Transaction object from Line 92, why not just use that directly to pull the total where you need it?

Meaning you don’t need a $transaction_total variable you can just do echo $transaction->total();

This is probably the most important so far:

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L93-L102

What if you have Multi Event Registrations enabled and add tickets from say 3 different events? That loop is going to set $event_id and $event_slug to the ‘last’ event, which isn’t where all the registrations are from, is that expected?

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L150

Are you only wanting this output once? For the primary registrant?


Ash

November 20, 2018 at 4:35 pm

Hi Tony,

Thank you for taking the time to review the code…really appreciate it.

Updated code can be found here

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1

POINT 1:

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L45-L54

You said…”If there is more than one ticket on the event, $price is always only going to be the price of whichever ticket is last in the loop, is that expected?”

I would expect the price to be the first ticket that is has spaces remaining and that is not expired, due to the break;. Am I mistaken here? In the testing in my staging environment this did seem to work as expected.

POINT 2:

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L95-L104

You said…”What if you have Multi Event Registrations enabled and add tickets from say 3 different events? That loop is going to set $event_id and $event_slug to the ‘last’ event, which isn’t where all the registrations are from, is that expected?”

We only have new single events every month so I believe this would still work for us. Am I mistaken here?

POINT 3:

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-L150

You said…”Are you only wanting this output once? For the primary registrant?”

Yes we only want it for the primary registrant as I believe if the ticket price is $20 and the primary registrant bought 2 tickets, the total price paid would still be reflected as $40 for the primary registrant. For the pixel we just need how many tickets sold and total price paid. Am I missing something here?

Ash


Tony

  • Support Staff

November 21, 2018 at 4:18 am

I would expect the price to be the first ticket that is has spaces remaining and that is not expired, due to the break;. Am I mistaken here? In the testing in my staging environment this did seem to work as expected.

No, that’s correct.

But what if you have more than 1 ticket available at a time on the event and the user does not select the ‘first’ ticket? Won’t that setup tracking for an incorrect price?

If you only have a single ticket available at any one time it won’t matter but as your sharing the code I thought it worth bringing up.

We only have new single events every month so I believe this would still work for us. Am I mistaken here?

Yes, if you only ever have 1 single event active at a time, it will work for you. If you ever have more than one and a user adds tickets from both events you’ll likely see unexpected results.

If you only ever want to track this on a single event, you don’t need this:

https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-php-L95-L104

It’s basically a loop pulling the same details X amount of times (X being the number of tickets for the event). This isn’t the end of the world its just a little inefficient as you could just the primary registration to track the event.

So the above could be swapped out for something like:

$primary_registration = $transaction->primary_registration();

if ( $primary_registration instanceof EE_Registration ) {
    $event = $primary_registration->event();
    if (! $event instanceof EE_Event ) {
        return;
    }
}

Grabs the event object for the primary registrant and if you don’t actually have an event you can’t output anything so returns before trying to use it.

Then further down again: https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-php-L114-L117

Just use the event object directly (you already know its an EE_Event object because of the above.

<?php echo $event->slug(); ?>
<?php echo $event->ID(); ?>

(A transaction should always have a registration assigned to it, and a registration should always be assigned to an event, so if you have an EE_Event from an EE_Registration from an EE_Transaction (say that 3 times fast….) you know everything is working as it should).

Yes we only want it for the primary registrant as I believe if the ticket price is $20 and the primary registrant bought 2 tickets, the total price paid would still be reflected as $40 for the primary registrant. For the pixel we just need how many tickets sold and total price paid. Am I missing something here?

Again, no, that’s correct, however, you’re basically pulling in more info than you need.

You can again use the primary_registrant method above on the transaction to pull just the primary registrant rather than pulling them all and then checking for the primary registrant based on the reg_url_link.

Then swap out the variable calls to use $primary_registrant and $event to pretty much remove all of this: https://gist.github.com/amistry007/a4cdc3af229aa77c3e960f0c083829e1#file-add_fb_events_to_event_espresso-php-L146-L160

I’ll leave that code to you as I’m sure you can work it out from the above 🙂

Edit – Actually, why are you using the registration to pull the price paid? The transaction has the total amount paid, would it not be better to use that value directly?

$transaction->paid();

—-

Just thought of one more change you might want to make.

This is_page('registration-checkout') and if ($pagename == 'thank-you')

Whilst nothing is actually wrong with them, if you run this code on a non-english site, will not work, or if someone has changed the page slugs for those slugs it wont work.

EE stores those pages within the config, so you can use:

Registration checkout = is_page( EE_Registry::instance()->CFG->core->reg_page_id )

Thank You = is_page( EE_Registry::instance()->CFG->core->thank_you_page_id )

I’m sorry if it seems like I’ve ripped your code apart here, the original code works the above is just some bulletproofing.


Tony

  • Support Staff

November 21, 2018 at 4:23 am

One final thought, I can see your using var_dump() to output debug info which is great, but imo not very helpful when you are looking for methods you can use.

Take a look a Kint Debugger, wrap whatever you want to debug in d(); and you’ll get a much better view of the object, its methods and various other information which makes it much easier to see what you can do.

Viewing 13 reply threads

The support post ‘Facebook Pixel – Populate Dynamically Fields From Event Espresso Event’ is closed to new replies.

Have a question about this support post? Create a new support post in our support forums and include a link to this existing support post so we can help you.

Event Espresso