Files
2026-07-02 15:54:39 -06:00

290 lines
8.9 KiB
JavaScript

( function () {
/**
* Send events to Google Analytics. Use Ajax call so no duplicate entries are recorded.
*
* @since 1.3.0
*
* @param {number} entryId The entry ID associated with this submission.
* @param {number} feedId The feed ID associated with this event.
* @param {array} parameters Event parameters to send to Google Analytics.
* @param {string} eventName Event name to be sent to Google Analytics.
*/
this.send_unique_to_ga = async function ( entryId, feedId, parameters, eventName ) {
let has_sent = await this.has_sent_feed( entryId, feedId );
if ( ! has_sent ) {
this.send_to_ga( parameters, eventName );
this.mark_feed_as_sent( entryId, feedId );
}
this.maybe_trigger_feeds_sent();
};
/**
* Send events to Google Analytics. Use ajax call so no duplicate entries are recorded.
*
* @since 1.0.0
* @param {array} parameters Event parameters to send to Google Analytics.
* @param {string} eventName Event name to be sent to Google Analytics.
*/
this.send_to_ga = function( parameters, eventName ) {
const eventTracker = gforms_google_analytics_frontend_strings.ua_tracker;
// Check for gtab implementation
if ( typeof window.parent.gtag != 'undefined' ) {
window.parent.gtag( 'event', eventName, parameters );
} else {
// Check for GA from Monster Insights Plugin
if ( typeof window.parent.ga == 'undefined' ) {
if ( typeof window.parent.__gaTracker != 'undefined' ) {
window.parent.ga = window.parent.__gaTracker;
}
}
if ( typeof window.parent.ga != 'undefined' ) {
let ga_send = 'send';
// Try to get original UA code from third-party plugins or tag manager
if ( eventTracker.length > 0 ) {
ga_send = eventTracker + '.' + ga_send;
}
// Use that tracker
window.parent.ga( ga_send, eventName, parameters );
} else {
console.error( 'Google Tag Manger script is not active. You may need to enable "Output the Google Analytics Script" setting on the Forms -> Settings -> Google Analytics page');
return;
}
}
// Logging if enabled.
const eventData = { 'type': 'ga', 'eventName' : eventName, 'parameters' : parameters };
this.consoleLog('Google Analytics event sent. Event data: ');
this.consoleLog( JSON.stringify( eventData, null, 2 ) );
// Triggering event_sent event.
this.trigger_event( 'googleanalytics/event_sent', eventData );
jQuery.post(
gforms_google_analytics_frontend_strings.ajaxurl,
{
action: 'gf_ga_log_event_sent',
parameters: parameters,
eventName: eventName,
connection: 'ga',
nonce: gforms_google_analytics_frontend_strings.logging_nonce,
}
);
}
/**
* Send events to Google Tag Manager.
*
* @since 1.3.0
*
* @param {number} entryId The entry ID associated with this submission.
* @param {number} feedId The feed ID associated with this event.
* @param {array} parameters Event parameters to send to Google Analytics.
* @param {string} triggerName Event type to be sent to Google Analytics.
*/
this.send_unique_to_gtm = async function( entryId, feedId, parameters, triggerName) {
let has_sent = await this.has_sent_feed( entryId, feedId );
if ( ! has_sent ) {
this.send_to_gtm( parameters, triggerName );
this.mark_feed_as_sent( entryId, feedId );
} else {
this.consoleLog( 'Event has already been sent. Aborting... Entry id: ' + entryId + '. Feed Id: ' + feedId );
}
this.maybe_trigger_feeds_sent();
}
/**
* Send events to Google Tag Manager.
*
* @since 1.0.0
*
* @param {array} parameters Event parameters to send to Google Analytics.
* @param {string} triggerName Event name to be sent to Google Tag Manger.
*/
this.send_to_gtm = function( parameters, triggerName) {
if ( typeof ( window.parent.dataLayer ) == 'undefined' ) {
console.error( 'Google Tag Manger script is not active. You may need to enable "Output the Google Tag Manager Script" setting on the Forms -> Settings -> Google Analytics page' );
return;
}
parameters['event'] = triggerName;
window.parent.dataLayer.push( parameters );
// Logging if enabled.
const eventData = { 'type': 'gtm', 'triggerName' : triggerName, 'parameters' : parameters };
this.consoleLog('Google Analytics event sent. Event data: ');
this.consoleLog( JSON.stringify( eventData, null, 2 ) );
// Triggering event_sent event.
this.trigger_event( 'googleanalytics/event_sent', eventData );
jQuery.post(
gforms_google_analytics_frontend_strings.ajaxurl,
{
action: 'gf_ga_log_event_sent',
parameters: parameters,
triggerName: triggerName,
connection: 'gtm',
nonce: gforms_google_analytics_frontend_strings.logging_nonce,
}
);
}
/**
* Determines if event for this entry and feed has already been sent.
*
* @since 1.3.0
*
* @param {number} entryId Current entry id.
* @param {number} feedId Current feed id.
*
* @returns {bool} Returns true if the event for this entry and feed has already been sent. Returns false if not.
*/
this.has_sent_feed = async function( entryId, feedId ) {
let response = await jQuery.post( gforms_google_analytics_frontend_strings.ajaxurl, { action: 'get_entry_meta', entry_id: entryId, feed_id: feedId, nonce: gforms_google_analytics_frontend_strings.nonce }, 'json' );
return response.data.event_sent;
}
/**
* Mark an event as sent via AJAX. Part of the system to prevent duplicate events from being sent.
*
* @since 1.3.0
*
* @param {number} entryId Current entry id.
* @param {number} feedId Current feed id.
*/
this.mark_feed_as_sent = function( entryId, feedId ) {
jQuery.post( gforms_google_analytics_frontend_strings.ajaxurl, { action: 'save_entry_meta', entry_id: entryId, feed_id: feedId, nonce: gforms_google_analytics_frontend_strings.nonce } );
}
/**
* Holds the number of feeds that have been sent.
*
* @since 1.3.0
*
* @type {number}
*/
this.feeds_sent = 0;
/**
* Triggers 'googleanalytics/all_events_sent' after the last feed has been sent.
*
* @since 1.3.0
*/
this.maybe_trigger_feeds_sent = function() {
this.feeds_sent++;
this.consoleLog( 'Google Analytics event successfully sent: ' + this.feeds_sent + ' of ' + window['ga_feed_count'] );
if ( this.feeds_sent >= window['ga_feed_count'] ) {
this.consoleLog( 'All Google Analytics events have been sent.' );
// All feeds have been sent. Trigger feeds sent event.
this.trigger_event( 'googleanalytics/all_events_sent' );
window['all_ga_events_sent'] = true;
// Reset counters.
this.feeds_sent = 0;
window['ga_feed_count'] = 0;
}
}
/**
* Triggers a Javascript event.
*
* @since 1.3.0
*
* @param {string} eventName Name of the event.
* @param {*} eventData Data associated with this event.
*/
this.trigger_event = function( eventName, eventData ) {
const event = new CustomEvent( eventName, { detail: eventData } );
window.dispatchEvent( event );
}
/**
* Logs to the console if logging is enabled in settings page.
*
* @since 1.3.0
*
* @param {*} message The message to be logged.
*/
this.consoleLog = function( message ) {
if ( gforms_google_analytics_frontend_strings.logging_enabled !== '1' ) {
return;
}
console.log( message );
}
this.handle_ajax_feeds = async function( data ) {
if ( ! data?.submissionResult?.data?.ajax_feeds ) {
return data;
}
for ( const feed of data.submissionResult.data.ajax_feeds ) {
if ( feed?.mode == 'ga' ) {
this.send_unique_to_ga( data.submissionResult.data.entry_id, feed.feed_id, feed.parameters, feed.eventName );
}
if ( feed?.mode == 'gtm' ) {
this.send_unique_to_gtm( data.submissionResult.data.entry_id, feed.feed_id, feed.parameters, feed.eventName );
}
window.parent[ 'ga_feed_count' ] = window.parent[ 'ga_feed_count' ] ? window.parent[ 'ga_feed_count' ] + 1 : 1;
}
}
this.handle_ajax_pagination = function( data ) {
if ( ! data?.submissionResult?.data?.ajax_pagination ) {
return data;
}
const ajaxPagination = data?.submissionResult?.data?.ajax_pagination
if ( ajaxPagination?.mode == 'ga' ) {
window.parent.GF_Google_Analytics.send_to_ga( ajaxPagination.parameters, ajaxPagination.eventName );
}
if ( ajaxPagination?.mode == 'gtm' ) {
window.parent.GF_Google_Analytics.send_to_gtm( ajaxPagination.parameters, ajaxPagination.eventName );
}
this.consoleLog( 'Pagination event has been sent.' );
return data;
}
/**
* Initializes this object.
*/
this.init = function() {
window.GF_Google_Analytics = this;
let ajaxFilterRegistered = false;
// Trigger script loaded event
this.trigger_event( 'googleanalytics/script_loaded' );
document.addEventListener( 'gform/post_render', ( ) => {
if ( ajaxFilterRegistered ) {
return;
}
window.gform.utils.addFilter( 'gform/ajax/post_ajax_submission', ( data ) => {
this.handle_ajax_feeds( data );
this.handle_ajax_pagination( data );
return data;
} );
ajaxFilterRegistered = true;
} );
}
this.init();
}() );