This commit is contained in:
2026-07-02 15:54:39 -06:00
commit 9883323161
17470 changed files with 4470592 additions and 0 deletions
@@ -0,0 +1,573 @@
<?php
/**
* Object responsible for organizing and constructing the form settings page.
*/
namespace Gravity_Forms\Gravity_Forms_Google_Analytics\Settings;
defined( 'ABSPATH' ) || die();
use Gravity_Forms\Gravity_Forms_Google_Analytics\GF_Google_Analytics;
use Gravity_Forms\Gravity_Forms\Settings\Settings;
use GFCommon;
use GFAddOn;
use GFAPI;
use GFFormsModel;
use GFCache;
class Form_Settings {
/**
* Add-on instance.
*
* @var GF_Google_Analytics
*/
private $addon;
/**
* Defines the capability needed to access the Add-On form settings page.
*
* @since 1.0.0
* @access protected
* @var string $_capabilities_form_settings The capability needed to access the Add-On form settings page.
*/
protected $_capabilities_form_settings = 'gravityforms_googleanalytics';
/**
* Plugin_Settings constructor.
*
* @since 1.0
*
* @param GF_Google_Analytics $addon GF_Google_Analytics instance.
*/
public function __construct( $addon ) {
$this->addon = $addon;
}
/**
* Get tab attributes so correct tab appears as selected.
*
* @since 1.0
*
* @return array Array of tab attributes.
*/
public function get_tab_attributes() {
$active_attrs = 'aria-selected=true class=active';
$inactive_attrs = 'aria-selected=false';
$tab_attributes = array();
if ( rgget( 'settingstype' ) == 'form' ) {
$tab_attributes['current_tab'] = 'form_settings';
$tab_attributes['feed_link_attrs'] = $inactive_attrs;
$tab_attributes['form_link_attrs'] = $active_attrs;
} else {
$tab_attributes['current_tab'] = 'feed';
$tab_attributes['feed_link_attrs'] = $active_attrs;
$tab_attributes['form_link_attrs'] = $inactive_attrs;
}
return $tab_attributes;
}
/**
* Display the form settings page.
*
* This form settings page has tabs for the feed settings and the form settings.
*
* @since 1.0
*
* @param array $form the current form.
*/
public function form_settings_page( $form ) {
// Set up the data we need to display the tabs.
$tab_attributes = $this->get_tab_attributes();
// Remove the feed id from the form settings url to ensure correct saving.
$form_settings_params = $_GET;
unset( $form_settings_params['fid'] );
$feed_settings_url = http_build_query( array_merge( $_GET, array( 'settingstype' => 'feed' ) ) );
$form_settings_url = http_build_query( array_merge( $form_settings_params, array( 'settingstype' => 'form' ) ) );
// Display the navigation tabs.
echo '<nav class="gform-settings-tabs__navigation" role="tablist" style="margin-bottom:.875rem">
<a role="tab" href="' . admin_url( 'admin.php?' . esc_html( $feed_settings_url ) ) . '" ' . esc_attr( $tab_attributes['feed_link_attrs'] ) . '>' . esc_html__( 'Feed Settings', 'gravityformsgoogleanalytics' ) . '</a>
<a role="tab" href="' . admin_url( 'admin.php?' . esc_html( $form_settings_url ) ) . '" ' . esc_attr( $tab_attributes['form_link_attrs'] ) . '>' . esc_html__( 'Form Settings', 'gravityformsgoogleanalytics' ) . '</a>
</nav>';
// Display the tab contents.
if ( 'form_settings' == $tab_attributes['current_tab'] ) {
if ( ! $this->addon->can_create_feed() ) {
printf( '<div>%s</div>', $this->addon->configure_addon_message() );
return;
}
// Get fields.
$sections = array_values( $this->addon->form_settings_fields( $form ) );
$sections = $this->addon->prepare_settings_sections( $sections, 'form_settings' );
$renderer = new Settings(
array(
'capability' => $this->_capabilities_form_settings,
'fields' => $sections,
'initial_values' => GF_Google_Analytics::get_instance()->get_form_settings( $form ),
'save_callback' => function( $values ) use ( $form ) {
$this->save_form_settings( $form, $values );
},
'before_fields' => function() use ( $form ) {
?>
<script type="text/javascript">
gform.addFilter( 'gform_merge_tags', 'addPaginationMergeTags' );
function addPaginationMergeTags( mergeTags, elementId, hideAllFields, excludeFieldTypes, isPrepop, option ) {
mergeTags[ 'other' ].tags.push( {
tag: '{source_page_number}',
label: <?php echo json_encode( __( 'Source Page Number', 'gravityforms' ) ) ?> } );
mergeTags[ 'other' ].tags.push( {
tag: '{current_page_number}',
label: <?php echo json_encode( __( 'Current Page Number', 'gravityforms' ) ) ?> } );
return mergeTags;
}
</script>
<?php
},
'after_fields' => function() use ( $form ) {
printf(
'<script type="text/javascript">var form = %s;</script>',
wp_json_encode( $form )
);
},
)
);
$renderer->render();
} else {
if ( $this->addon->is_detail_page() ) {
// Feed edit page.
$feed_id = $this->addon->get_current_feed_id();
$this->addon->feed_edit_page( $form, $feed_id );
} else {
// Feed list UI.
$this->addon->feed_list_page( $form );
}
}
}
/***
* Saves form settings to form object.
*
* @since 1.0
*
* @param array $form the current form.
* @param array $settings the settings to save.
*
* @return true|false True on success or false on error
*/
public function save_form_settings( $form, $settings ) {
$form[ $this->addon->get_slug() ] = $settings;
$result = GFFormsModel::update_form_meta( $form['id'], $form );
return ! ( false === $result );
}
/**
* Configures the settings which should be rendered on the feed edit page.
*
* @since 1.0.0
*
* @return array
*/
public function get_feed_settings_fields() {
$form_id = rgget( 'id' );
$form = GFAPI::get_form( $form_id );
return array(
array(
'title' => esc_html__( 'Feed Name', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'label' => esc_html__( 'Feed Name', 'gravityformsgoogleanalytics' ),
'type' => 'text',
'name' => 'feedName',
'class' => 'medium',
'required' => true,
'tooltip' => '<strong>' . esc_html__( 'Feed Name', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Enter a feed name to uniquely identify this feed.', 'gravityformsgoogleanalytics' ),
),
),
),
array(
'title' => esc_html__( 'Event Parameters', 'gravityformsgoogleanalytics' ),
'fields' => $this->get_ga4_event_fields( $form, 'feed' ),
),
array(
'title' => __( 'Conditional Logic Settings', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'name' => 'conditionalLogic',
'label' => esc_html__( 'Conditional Logic', 'gravityformsgoogleanalytics' ),
'type' => 'feed_condition',
'tooltip' => '<strong>' . __( 'Conditional Logic', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'When conditions are enabled, conversions will only be sent when the conditions are met.', 'gravityformsgoogleanalytics' ),
),
),
),
);
}
/**
* Get event parameter fieldmap field.
*
* @since 2.0
*
* @param array $form The current form object.
* @param string $type Whether we're rendering feed or pagination fields.
*
* @return array Array of fields.
*/
public function get_ga4_event_fields( $form, $type ) {
if ( $type !== 'pagination' && $type !== 'feed' ) {
return;
}
$options = $this->addon->get_options();
$mode = rgar( $options, 'mode' );
$prefix = ( $type === 'pagination' ) ? 'pagination_' : 'submission_';
if ( $mode !== 'gtm' ) {
return array(
array(
'name' => $prefix . 'parameters',
'description' => esc_html__( 'Parameter names must be 40 characters or fewer and are limited to alphanumeric characters and underscores. They cannot begin or end with an underscore. Values are limited to 100 characters or fewer.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Parameters', 'gravityformsgoogleanalytics' ),
'type' => 'generic_map',
'tooltip' => '<h6>' . esc_html__( 'Submission Parameters', 'gravityformsgoogleanalytics' ) . '</h6>' . esc_html__( 'Set the parameters that will be sent to Google Analytics for this feed.', 'gravityformsgoogleanalytics' ),
'limit' => 25,
'key_field' => array(
'title' => esc_html__( 'Parameter Name', 'gravityformsgoogleanalytics' ),
'allow_custom' => true,
'placeholder' => esc_html__( 'Enter a parameter name', 'gravityformsgoogleanalytics' ),
),
'value_field' => array(
'title' => esc_html__( 'Parameter Value', 'gravityformsgoogleanalytics' ),
'allow_custom' => true,
'placeholder' => esc_html__( 'Enter a value', 'gravityformsgoogleanalytics' ),
),
'validation_callback' => array( $this, 'custom_parameter_validation_callback' ),
),
);
} else {
$trigger_choices = $this->get_tag_manager_trigger_choices( $options );
$variable_choices = $this->get_tag_manager_variable_choices( $options );
if ( empty( $trigger_choices ) ) {
$trigger_setting = array(
'name' => $prefix . 'trigger',
'type' => 'text',
'label' => esc_html__( 'Tag Manager Trigger', 'gravityformsgoogleanalytics' ),
'tooltip' => '<h6>' . esc_html__( 'Tag Manager Trigger', 'gravityformsgoogleanalytics' ) . '</h6>' . esc_html__( 'Set the trigger that will be sent to tag manager when this feed is processed.', 'gravityformsgoogleanalytics' ),
'required' => true,
);
} else {
$trigger_setting = array(
'name' => $prefix . 'trigger',
'type' => 'select_custom',
'label' => esc_html__( 'Tag Manager Trigger', 'gravityformsgoogleanalytics' ),
'choices' => $trigger_choices,
'tooltip' => '<h6>' . esc_html__( 'Tag Manager Trigger', 'gravityformsgoogleanalytics' ) . '</h6>' . esc_html__( 'Set the trigger that will be sent to tag manager when this feed is processed.', 'gravityformsgoogleanalytics' ),
'required' => true,
);
}
return array(
$trigger_setting,
array(
'name' => $prefix . 'parameters',
'label' => esc_html__( 'Parameters', 'gravityformsgoogleanalytics' ),
'type' => 'generic_map',
'tooltip' => '<h6>' . esc_html__( 'Submission Parameters', 'gravityformsgoogleanalytics' ) . '</h6>' . esc_html__( 'Set the parameters that will be sent to Google Analytics for this feed.', 'gravityformsgoogleanalytics' ),
'limit' => 25,
'key_field' => array(
'title' => esc_html__( 'Parameter Name', 'gravityformsgoogleanalytics' ),
'allow_custom' => true,
'placeholder' => esc_html__( 'Enter a parameter name', 'gravityformsgoogleanalytics' ),
'choices' => $variable_choices,
),
'value_field' => array(
'title' => esc_html__( 'Parameter Value', 'gravityformsgoogleanalytics' ),
'allow_custom' => true,
'placeholder' => esc_html__( 'Enter a value', 'gravityformsgoogleanalytics' ),
),
),
);
}
}
/**
* Callback for validation the custom parameters.
*
* @since 2.0
*
* @param object $field The field being validated.
* @param array $parameters The parameters being validated.
*
* @return void
*/
public function custom_parameter_validation_callback( $field, $parameters ) {
foreach ( $parameters as $parameter ) {
$key = 'gf_custom' === $parameter['key'] ? $parameter['custom_key'] : $parameter['key'];
if ( 'gf_custom' === $parameter['value'] ) {
$value = $parameter['custom_value'];
} else {
$value = $parameter['value'];
}
$field_error = $this->validate_parameter( $key, $value );
if ( $field_error ) {
$this->addon->set_field_error( $field, $field_error );
}
}
}
/**
* Parameter validation
*
* @since 2.0
*
* @param string $key The parameter key.
* @param string $value The parameter value.
*
* @return string The validation error.
*/
public function validate_parameter( $key, $value ) {
if ( ! is_string( $key ) || ! is_string( $value ) ) {
return esc_html__( 'Parameter names and values must be strings.', 'gravityformsgoogleanalytics' );
}
if ( mb_strlen( $key ) > 40 ) {
return esc_html__( 'Parameter names must be 40 characters or less.', 'gravityformsgoogleanalytics' );
}
if ( mb_strlen( $value ) > 100 ) {
return esc_html__( 'Parameter values must be 100 characters or less.', 'gravityformsgoogleanalytics' );
}
if ( ! preg_match( '/^(?!_)[\w]*(?<!_)$/u', $key ) ) {
return esc_html__( 'Parameter names cannot begin or end with an underscore, and must contain only letters, numbers, and underscores.', 'gravityformsgoogleanalytics' );
}
}
/**
* Get tag manager trigger choices.
*
* @since 2.0
*
* @param array $options The add-on's options.
*
* @return array Array of trigger choices.
*/
private function get_tag_manager_trigger_choices( $options ) {
if ( rgar( $options, 'is_manual' ) === true ) {
return array();
}
$trigger_choices = \GFCache::get( 'tag_manager_trigger_choices' );
if ( $trigger_choices ) {
return $trigger_choices;
}
$ga4_account = rgar( $options, 'ga4_account' );
$api_path = rgar( $ga4_account, 'gtm_api_path' );
$workspace = rgar( $ga4_account, 'gtm_workspace_id' );
$triggers = rgar( $this->addon->get_tag_manager_triggers( array(), $api_path, $workspace ), 'trigger' );
if ( is_wp_error( $triggers ) || empty( $triggers ) || ! is_array( $triggers ) ) {
return false;
}
$trigger_choices = array();
foreach ( $triggers as $trigger ) {
$trigger_event_name = $this->get_trigger_event_name( $trigger );
$trigger_choices[] = array(
'label' => $trigger['name'],
'value' => $trigger_event_name,
);
}
\GFCache::set( 'tag_manager_trigger_choices', $trigger_choices );
return $trigger_choices;
}
/**
* Get the trigger event name.
*
* @since 2.1
*
* @param array $trigger The trigger.
*
* @return string The trigger event name.
*/
private function get_trigger_event_name( $trigger ) {
if ( $trigger['type'] !== 'customEvent' ) {
return $trigger['name'];
}
// There's no convenient api method to get this value, but it should always be in the same place for custom events.
$event_name = rgars( $trigger, 'customEventFilter/0/parameter/1/value' );
if ( $event_name ) {
return $event_name;
} else {
return $trigger['name'];
}
}
/**
* Get tag manager variable choices.
*
* @since 2.0
*
* @param array $options The add-on's options.
*
* @return array Array of variable choices.
*/
private function get_tag_manager_variable_choices( $options ) {
if ( rgar( $options, 'is_manual' ) === true ) {
return array();
}
$variable_choices = \GFCache::get( 'tag_manager_variable_choices' );
if ( $variable_choices ) {
return $variable_choices;
}
$ga4_account = rgar( $options, 'ga4_account' );
$api_path = rgar( $ga4_account, 'gtm_api_path' );
$workspace = rgar( $ga4_account, 'gtm_workspace_id' );
$variables = rgar( $this->addon->get_tag_manager_variables( array(), $api_path, $workspace ), 'variable' );
$variable_choices = array();
if ( rgempty( $variables ) ) {
return $variable_choices;
}
foreach ( $variables as $variable ) {
if ( rgar( $variable, 'type' ) !== 'v' ) {
continue;
}
$variable_choices[] = array(
'label' => $variable['name'],
'value' => $this->get_variable_value( $variable ),
);
}
\GFCache::set( 'tag_manager_variable_choices', $variable_choices );
return $variable_choices;
}
/**
* Get the value of the tag manager variable
*
* @since 2.0
*
* @param array $variable The variable from which to retrieve the value.
*
* @return string Returns the variable's value or a blank string if the variable isn't found.
*/
public function get_variable_value( $variable ) {
foreach ( $variable['parameter'] as $parameter ) {
if ( rgar( $parameter, 'key' ) === 'name' ) {
return rgar( $parameter, 'value' );
}
}
return '';
}
/**
* Configures the columns for the feed page.
*
* @since 1.0.0
*
* @return array
*/
public function feed_list_columns() {
$columns = array( 'feedName' => esc_html__( 'Name', 'gravityformsgoogleanalytics' ) );
if ( $this->addon->get_options( '', 'mode' ) == 'gtm' ) {
$columns['submission_trigger'] = esc_html__( 'Trigger', 'gravityformsgoogleanalytics' );
}
return $columns;
}
/**
* Add pagination form settings to Gravity Forms.
*
* @since 1.0.0
*
* @param array $form The form.
*
* @return array Updated form settings
*/
public function pagination_form_settings( $form ) {
if ( rgget( 'settingstype' ) !== 'form' ) {
return array();
}
if ( isset( $form['pagination'] ) ) {
return array(
array(
'title' => esc_html__( 'Form Settings', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'name' => 'google_analytics_pagination',
'label' => esc_html__( 'Pagination Tracking', 'gravityformsgoogleanalytics' ),
'type' => 'checkbox',
'choices' => array(
array(
'label' => esc_html__( 'Enable pagination tracking', 'gravityformsgoogleanalytics' ),
'name' => 'google_analytics_pagination',
),
),
),
),
),
array(
'title' => esc_html__( 'Event Parameters', 'gravityformsgoogleanalytics' ),
'fields' => $this->get_ga4_event_fields( $form, 'pagination' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'google_analytics_pagination',
'values' => array( '1' ),
),
),
),
),
);
} else {
return array(
array(
'title' => esc_html__( 'Form Settings', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'label' => esc_html__( 'Pagination Tracking', 'gravityformsgoogleanalytics' ),
'type' => 'html',
'html' => '<p>' . esc_html__( 'Add a Page field to your form to begin tracking pagination events.', 'gravityformsgoogleanalytics' ) . '</p>',
),
),
),
);
}
}
}
@@ -0,0 +1,768 @@
<?php
/**
* Object responsible for organizing and constructing the plugin settings page.
*/
namespace Gravity_Forms\Gravity_Forms_Google_Analytics\Settings;
defined( 'ABSPATH' ) || die();
use Gravity_Forms\Gravity_Forms_Google_Analytics\GF_Google_Analytics;
use GFCommon;
class Plugin_Settings {
/**
* Add-on instance.
*
* @var GF_Google_Analytics
*/
private $addon;
/**
* Defines the capability needed to access the Add-On form settings page.
*
* @since 1.0.0
* @access protected
* @var string $_capabilities_form_settings The capability needed to access the Add-On form settings page.
*/
protected $_capabilities_form_settings = 'gravityforms_googleanalytics';
/**
* Stores the auth_payload returned after OAuth has been completed.
*
* @since 1.0
*
* @var array
*/
protected $auth_payload;
/**
* Plugin_Settings constructor.
*
* @since 1.0
*
* @param GF_Google_Analytics $addon GF_Google_Analytics instance.
*/
public function __construct( $addon ) {
$this->addon = $addon;
}
/**
* Get the plugin settings fields.
*
* @since 1.0
* @see GF_Google_Analytics::plugin_settings_fields()
*
* @return array
*/
public function get_fields() {
if ( $this->is_connected() ) {
return array(
$this->get_connection_display(),
$this->get_advanced_fields(),
);
}
if ( $this->is_manual_configuration() ) {
return array( $this->manual_connection_settings() );
}
if ( $this->is_unconfigured_connection() ) {
return $this->show_settings_for_action( rgget( 'action' ) );
}
return $this->get_connection_mode_fields();
}
/**
* Display the settings updated notice
*
* @since 2.0.0
*/
public function maybe_display_settings_updated() {
if ( rgget( 'updated' ) ) {
printf(
'<div class="alert gforms_note_success" role="alert">%s</div>',
esc_html__( 'Settings Updated.', 'gravityformsgoogleanalytics' )
);
}
}
/**
* Determine if this is connection mode selected was manual configuration.
*
* @since 2.0
*
* @return bool
*/
private function is_manual_configuration() {
return $this->addon->get_options( 'is_manual' );
}
/**
* Checks if the add-on can initialize the API and that an action exists.
*
* Determines if the user has been redirected from the OAuth flow with a token and an action
* but the settings have not been saved yet.
*
* @since 1.0
*
* @return bool
*/
private function is_unconfigured_connection() {
return empty( $this->addon->get_options( 'mode' ) ) && rgget( 'action' ) && $this->addon->initialize_api();
}
/**
* Checks if the addon can initialize the API and that settings were saved.
*
* @since 1.0
*
* @return bool
*/
private function is_connected() {
return ! empty( $this->addon->get_options( 'mode' ) ) && $this->addon->initialize_api();
}
/**
* Shows the settings fields for a certain action.
*
* @since 1.0
*
* @param string $action The action extracted from the query args to show the settings for.
*
* @return array
*/
public function show_settings_for_action( $action ) {
if ( 'gaselect' === $action ) {
return $this->google_analytics_connection_settings();
}
if ( 'gtmselect' === $action ) {
return $this->google_tag_manager_settings();
}
return $this->get_connection_mode_fields();
}
/**
* Get the connection mode fields. These are the fields that let the user choose between the three connection types.
*
* @since 1.0
*
* @return array
*/
private function get_connection_mode_fields() {
$card_choices = array(
array(
'label' => esc_html__( 'Measurement Protocol', 'gravityformsgoogleanalytics' ),
'value' => 'gmp',
'icon' => $this->addon->get_base_url() . '/img/google.svg',
'tag' => esc_html__( 'Recommended', 'gravityformsgoogleanalytics' ),
'color' => 'orange',
'title' => esc_html__( 'Google Measurement Protocol', 'gravityformsgoogleanalytics' ),
'description' => esc_html__( 'The Measurement Protocol is a server-to-server connection with Google Analytics. It is the most reliable mechanism for event tracking, but it does not include data such as AdWords, Remarketing, or tracking variables.', 'gravityformsgoogleanalytics' ),
),
array(
'label' => esc_html__( 'Google Analytics', 'gravityformsgoogleanalytics' ),
'value' => 'ga',
'icon' => $this->addon->get_base_url() . '/img/analytics.svg',
'tag' => esc_html__( 'Flexible', 'gravityformsgoogleanalytics' ),
'color' => 'blue-ribbon',
'title' => esc_html__( 'Google Analytics', 'gravityformsgoogleanalytics' ),
'description' => esc_html__( 'Google Analytics mode will send data such as Source/Medium (e.g., the page leading to a conversion). Additionally, Google Analytics mode will send information about your user such as location, language, browser information, and AdWords/Remarketing information.', 'gravityformsgoogleanalytics' ),
),
array(
'label' => esc_html__( 'Tag Manager', 'gravityformsgoogleanalytics' ),
'value' => 'gtm',
'icon' => $this->addon->get_base_url() . '/img/gtm.svg',
'tag' => esc_html__( 'Advanced', 'gravityformsgoogleanalytics' ),
'color' => 'orange',
'title' => esc_html__( 'Google Tag Manager', 'gravityformsgoogleanalytics' ),
'description' => esc_html__( 'If you need more control after a form has been submitted, such as setting up a remarketing tag, then Google Tag Manager may be the best option.', 'gravityformsgoogleanalytics' ),
),
);
if ( $this->display_manual_connection_mode() ) {
$card_choices[] = array(
'label' => esc_html__( 'Manual Configuration', 'gravityformsgoogleanalytics' ),
'value' => 'manual',
'icon' => $this->addon->get_base_url() . '/img/manual.svg',
'tag' => esc_html__( 'Advanced', 'gravityformsgoogleanalytics' ),
'color' => 'orange',
'title' => esc_html__( 'Manual Configuration', 'gravityformsgoogleanalytics' ),
'description' => esc_html__( 'Use this option if you are an advanced user and would like to manually enter your Google Analytics information.', 'gravityformsgoogleanalytics' ),
);
}
return array(
array(
'title' => esc_html__( 'Select Tracking Connection Type', 'gravityformsgoogleanalytics' ),
'description' => esc_html__( 'Using the Google Analytics Platform you can easily add your Google Analytics tracking code to any of your Gravity Forms, in order to track visitor behavior and demographics. We offer three ways to connect to the service.', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'name' => 'nonce',
'type' => 'nonce_connect',
'readonly' => true,
),
array(
'name' => 'action',
'type' => 'hidden',
'readonly' => true,
'value' => 'google_analytics_setup',
'id' => 'google-analytics-setup',
),
array(
'type' => 'save',
'value' => esc_html__( 'Continue &rarr;', 'gravityformsgoogleanalytics' ),
'id' => 'ga-connect',
),
),
),
array(
'fields' => array(
array(
'name' => 'mode',
'type' => 'card',
'choices' => $card_choices,
),
),
),
);
}
/**
* Determines if the manual connection mode options should be displayed.
*
* @since 2.0.0
*
* @return bool Returns true if the manual connection mode options should be displayed. Returns false otherwise.
*/
private function display_manual_connection_mode() {
$version_info = GFCommon::get_version_info();
return apply_filters( 'gform_googleanalytics_allow_manual_configuration', $version_info['is_valid_key'] );
}
/**
* Get the connection specific settings for Google Analytics.
*
* @since 1.0
*
* @return array
*/
private function google_analytics_connection_settings() {
return array(
array(
'id' => 'google-analytics-settings',
'fields' => array(
array(
'name' => 'gafields',
'type' => 'ga_select_account',
'label' => esc_html__( 'Select a Google Analytics Account', 'gravityformsgoogleanalytics' ),
),
array(
'name' => 'nonce',
'type' => 'nonce_connect',
),
array(
'name' => 'action',
'type' => 'ga_action',
),
array(
'name' => 'save',
'type' => 'save',
'value' => __( 'Complete Setup', 'gravityformsgoogleanalytics' ),
),
),
),
);
}
/**
* Get the connection specific settings for Google Tag Manager.
*
* @since 1.0
*
* @return array
*/
private function google_tag_manager_settings() {
return array(
array(
'id' => 'google-analytics-settings',
'fields' => array(
array(
'name' => 'gtmfields',
'type' => 'gtm_select',
'label' => esc_html__( 'Select a Google Tag Manager Account', 'gravityformsgoogleanalytics' ),
),
array(
'name' => 'nonce',
'type' => 'nonce_connect',
'readonly' => true,
),
array(
'name' => 'action',
'type' => 'gtm_action',
),
array(
'name' => 'save',
'type' => 'save',
'value' => __( 'Complete Setup', 'gravityformsgoogleanalytics' ),
),
),
),
);
}
/**
* Get the manual connection settings.
*
* @since 2.0
*
* @return array
*/
private function manual_connection_settings() {
$options = $this->addon->get_options();
return array(
'id' => 'google-analytics-settings',
'fields' => array(
array(
'name' => 'connection_mode',
'type' => 'connection_method',
'label' => esc_html__( 'Connection Mode', 'gravityformsgoogleanalytics' ),
),
array(
'name' => 'ga_connection_type',
'type' => 'select',
'label' => esc_html__( 'Connection Type', 'gravityformsgoogleanalytics' ),
'value' => rgar( $options, 'mode' ),
'choices' => array(
array(
'label' => esc_html__( 'Select a connection type', 'gravityformsgoogleanalytics' ),
'value' => '',
),
array(
'label' => esc_html__( 'Google Analytics', 'gravityformsgoogleanalytics' ),
'value' => 'ga',
),
array(
'label' => esc_html__( 'Measurement Protocol', 'gravityformsgoogleanalytics' ),
'value' => 'gmp',
),
array(
'label' => esc_html__( 'Tag Manager', 'gravityformsgoogleanalytics' ),
'value' => 'gtm',
),
),
),
array(
'name' => 'ga_measurement_id',
'type' => 'text',
'label' => esc_html__( 'Analytics Measurement ID', 'gravityformsgoogleanalytics' ),
'value' => rgars( $options, 'ga4_account/measurement_id' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'ga', 'gmp' ),
),
),
),
'description' => sprintf(
// Translators: 1. Opening anchor tag with link to Gravity Forms documentation. 2. Closing anchor tag.
__( 'Please enter the measurement ID (format: G-XXXXXX). %sLearn more about finding your measurement ID%s.', 'gravityformsgoogleanalytics' ),
'<a href="https://docs.gravityforms.com/google-analytics-add-on-setup/#h-measurement-protocol" target="_blank">',
'</a>'
),
),
array(
'type' => 'radio',
'name' => 'ga',
'horizontal' => false,
'label' => esc_html__( 'Google Analytics Script', 'gravityformsgoogleanalytics' ),
'default_value' => 'off',
'choices' => array(
array(
'name' => 'ga_off',
'tooltip' => '<strong>' . esc_html__( 'Don\'t Output Google Analytics Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you already have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'I already have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'value' => 'off',
),
array(
'name' => 'ga_on',
'tooltip' => '<strong>' . esc_html__( 'Output Google Analytics Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you would like to have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Output the Google Analytics Script.', 'gravityformsgoogleanalytics' ),
'value' => 'on',
),
),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'ga' ),
),
),
),
),
array(
'name' => 'ua_tracker',
'tooltip' => '<strong>' . esc_html__( 'UA Tracker Name', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Enter the Tracker Name you would like to send events from if you are using a custom Tracker for Google Analytics', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'UA Tracker Name', 'gravityformsgoogleanalytics' ),
'type' => 'text',
'class' => 'small',
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'ga' ),
),
),
),
),
array(
'name' => 'gmp_api_secret',
'type' => 'text',
'input_type' => 'password',
'label' => esc_html__( 'Measurement Protocol API Secret', 'gravityformsgoogleanalytics' ),
'value' => rgars( $options, 'ga4_account/gmp_api_secret' ),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'gmp' ),
),
),
),
'description' => sprintf(
// Translators: 1. Opening anchor tag with link to Gravity Forms documentation. 2. Closing anchor tag.
__( 'Please enter your API secret. %1$sLearn more about finding your API secret%2$s.', 'gravityformsgoogleanalytics' ),
'<a href="https://docs.gravityforms.com/google-analytics-add-on-setup/#h-measurement-protocol" target="_blank">',
'</a>'
),
),
array(
'name' => 'gtm_container_id',
'type' => 'text',
'label' => esc_html__( 'Tag Manager Container ID', 'gravityformsgoogleanalytics' ),
'value' => rgars( $options, 'ga4_account/gtm_container_id' ),
'description' => sprintf(
// Translators: 1. Opening anchor tag with link to Gravity Forms documentation. 2. Closing anchor tag.
__( 'Please enter the container ID (format: GTM-XXXXXX). %1$sLearn more about finding your container ID%2$s.', 'gravityformsgoogleanalytics' ),
'<a href="https://docs.gravityforms.com/google-analytics-add-on-setup/#h-tag-manager" target="_blank">',
'</a>'
),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'gtm' ),
),
),
),
),
array(
'name' => 'gtm_workspace_id',
'type' => 'text',
'label' => esc_html__( 'Tag Manager Workspace ID', 'gravityformsgoogleanalytics' ),
'value' => rgars( $options, 'ga4_account/gtm_workspace_id' ),
'description' => sprintf(
// Translators: 1. Opening anchor tag with link to Gravity Forms documentation. 2. Closing anchor tag.
__( 'Please enter the workspace name Id. %1$sLearn more about finding your Workspaces%2$s.', 'gravityformsgoogleanalytics' ),
'<a href="https://docs.gravityforms.com/google-analytics-add-on-setup/#h-tag-manager" target="_blank">',
'</a>'
),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'gtm' ),
),
),
),
),
array(
'type' => 'radio',
'name' => 'install_gtm',
'horizontal' => false,
'label' => esc_html__( 'Google Tag Manager Script', 'gravityformsgoogleanalytics' ),
'default_value' => 'off',
'choices' => array(
array(
'name' => 'gtm_off',
'tooltip' => '<strong>' . esc_html__( 'Don\'t Output the Google Tag Manager Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you already have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'I already have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'value' => 'off',
),
array(
'name' => 'gtm_on',
'tooltip' => '<strong>' . esc_html__( 'Output Google Tag Manager Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you would like to have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Output the Google Tag Manager Script.', 'gravityformsgoogleanalytics' ),
'value' => 'on',
),
),
'dependency' => array(
'live' => true,
'fields' => array(
array(
'field' => 'ga_connection_type',
'values' => array( 'gtm' ),
),
),
),
),
array(
'name' => 'manual_action',
'type' => 'manual_action',
),
array(
'name' => 'nonce',
'type' => 'nonce_connect',
),
),
);
}
/**
* Get the advanced settings fields.
*
* @since 1.0
*
* @return array
*/
private function get_advanced_fields() {
$options = $this->addon->get_options();
$mode = $options['mode'];
if ( $mode === 'gtm' ) {
return array(
'title' => esc_html__( 'Advanced', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'type' => 'radio',
'name' => 'install_gtm',
'horizontal' => false,
'label' => esc_html__( 'Google Tag Manager Script', 'gravityformsgoogleanalytics' ),
'default_value' => 'off',
'choices' => array(
array(
'name' => 'gtm_off',
'tooltip' => '<strong>' . esc_html__( 'Don\'t Output the Google Tag Manager Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you already have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'I already have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'value' => 'off',
),
array(
'name' => 'gtm_on',
'tooltip' => '<strong>' . esc_html__( 'Output Google Tag Manager Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you would like to have Google Tag Manager installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Output the Google Tag Manager Script.', 'gravityformsgoogleanalytics' ),
'value' => 'on',
),
),
),
),
);
} elseif ( $mode === 'ga' ) {
return array(
'title' => esc_html__( 'Advanced', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'type' => 'radio',
'name' => 'ga',
'horizontal' => false,
'label' => esc_html__( 'Google Analytics Script', 'gravityformsgoogleanalytics' ),
'default_value' => 'off',
'choices' => array(
array(
'name' => 'ga_off',
'tooltip' => '<strong>' . esc_html__( 'Don\'t Output Google Analytics Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you already have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'I already have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'value' => 'off',
),
array(
'name' => 'ga_on',
'tooltip' => '<strong>' . esc_html__( 'Output Google Analytics Script', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Choose this option if you would like to have Google Analytics installed.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Output the Google Analytics Script.', 'gravityformsgoogleanalytics' ),
'value' => 'on',
),
),
),
array(
'name' => 'ua_tracker',
'tooltip' => '<strong>' . esc_html__( 'UA Tracker Name', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Enter the Tracker Name you would like to send events from if you are using a custom Tracker for Google Analytics', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'UA Tracker Name', 'gravityformsgoogleanalytics' ),
'type' => 'text',
'class' => 'small',
),
),
);
} else {
return array(
'fields' => array(),
);
}
}
/**
* Show information about the current connection.
*
* @since 1.0
*
* @return array
*/
private function get_connection_display() {
$options = $this->addon->get_options();
$mode = $options['mode'];
return array(
'title' => esc_html__( 'Google Analytics Settings', 'gravityformsgoogleanalytics' ),
'fields' => array(
array(
'name' => 'connection_method',
'tooltip' => '<strong>' . esc_html__( 'Connection Type', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'Displays the current connection type. To change this, disconnect and reconnect using another type.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Connection Type', 'gravityformsgoogleanalytics' ),
'type' => 'connection_method',
),
array(
'name' => 'analytics_account',
'tooltip' => '<strong>' . esc_html__( 'Analytics Account', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'The Google Analytics Data Stream which will receive the conversion events.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Analytics Account', 'gravityformsgoogleanalytics' ),
'type' => 'analytics_account',
'hidden' => $mode == 'gtm',
),
array(
'name' => 'measurement_id',
'tooltip' => '<strong>' . esc_html__( 'Analytics Measurement ID', 'gravityformsgoogleanalytics' ) . '</strong>' . esc_html__( 'The measurement ID identifies the Google Analytics Data Stream which will receive the conversion events.', 'gravityformsgoogleanalytics' ),
'label' => esc_html__( 'Analytics Measurement ID', 'gravityformsgoogleanalytics' ),
'type' => 'measurement_id',
'hidden' => $mode == 'gtm',
),
array(
'name' => 'tag_manager_account',
'label' => esc_html__( 'Tag Manager Account', 'gravityformsgoogleanalytics' ),
'type' => 'tag_manager_account',
'hidden' => $mode != 'gtm',
),
array(
'type' => 'nonce_connect',
'name' => 'nonce',
'readonly' => true,
),
),
);
}
/**
* Store auth tokens when we get auth payload from Google Analytics.
*
* @since 1.0
*/
public function maybe_update_auth_tokens() {
$payload = $this->find_oauth_payload();
if ( ! $payload ) {
return;
}
if ( rgar( $payload, 'auth_error' ) ) {
GFCommon::add_message( esc_html__( 'An error occured while connecting to the API.', 'gravityformsgoogleanalytics' ) );
$this->addon->log_error( $payload['auth_error'] );
return;
}
$auth_payload = $this->get_decoded_auth_payload( $payload );
$this->auth_payload = $auth_payload;
// If access token is provided, save it.
if ( rgar( $auth_payload, 'access_token' ) ) {
// Get the authentication token.
$settings = array();
$settings['token'] = rgar( $auth_payload, 'access_token' );
$settings['refresh'] = rgar( $auth_payload, 'refresh_token' );
$settings['date_created'] = time();
$this->addon->update_options( $settings, 'auth_token' );
GFCommon::add_message( esc_html__( 'Google Analytics settings have been updated.', 'gravityformsgoogleanalytics' ) );
}
}
/**
* Determine if we have a valid nonce and capabilities.
*
* @since 1.0
*
* @param array $container The array that contains the nonce, defaults to $_POST.
*
* @return bool
*/
private function is_valid_action( $container = array() ) {
$container = empty( $container ) ? $_POST : $container;
return wp_verify_nonce( rgar( $container, 'state' ), 'gravityforms_googleanalytics_google_connect' ) && $this->addon->current_user_can_any( $this->_capabilities_form_settings );
}
/**
* Decodes the auth_payload returned form Gravity API.
*
* @since 1.0
*
* @param array $payload The payload received from Gravity API.
*
* @return array
*/
private function get_decoded_auth_payload( $payload ) {
$auth_payload_string = rgar( $payload, 'auth_payload' );
return empty( $auth_payload_string ) ? array() : json_decode( $auth_payload_string, true );
}
/**
* Get the authorization payload data.
*
* Returns the auth POST request if it's present, otherwise attempts to return a recent transient cache.
*
* @since 1.0
*
* @return array
*/
private function find_oauth_payload() {
$payload = array_filter(
array(
'auth_payload' => rgpost( 'auth_payload' ),
'auth_error' => rgpost( 'auth_error' ),
'state' => rgpost( 'state' ),
)
);
if (
(
$this->is_valid_action( $this->get_decoded_auth_payload( $payload ) )
&& count( $payload ) === 2
)
|| isset( $payload['auth_error'] )
) {
return $payload;
}
$payload = get_transient( 'gravityapi_response_' . $this->addon->get_slug() );
if ( rgar( $payload, 'state' ) !== get_transient( 'gravityapi_request_' . $this->addon->get_slug() ) ) {
return array();
}
delete_transient( 'gravityapi_response_' . $this->addon->get_slug() );
return is_array( $payload ) ? $payload : array();
}
/**
* Gets the auth_payload.
*
* @since 1.0
*
* @return array
*/
public function get_auth_payload() {
return $this->auth_payload;
}
}