Setting Up the Emma Add-On

Setting Up the Emma Add-On

Pre-RequisitesSetup

Pre-Requisites

Download and install the add-on
An Emma account

Setup

Log into your WordPress admin dashboard.
On the left side navigation menu, hover over Forms and click on Settings.
From this page, click the Emma tab.
Enter your Public API Key, Private API Key, and Account ID. Your Emma API account information can be found by logging into your Emma account. Go to your Account Settings page and access your API key information. Please be aware that the Private API Key will only be displayed the first time it is generated by Emma, so be sure to copy-n-paste the Private API Key as soon as it is displayed.
Click Update Settings. If you』ve entered your account information correctly, you will be notified by green check marks beside each box. If you do not see green check marks, please double check this information and try again.

Once you have entered your API key, you』re ready to begin creating a feed for the Emma Add-On.

Emma Change Log

Emma Change Log

1.5 | 2021-05-071.4 | 2020-09-211.3 | 2020-03-171.2 | 2017-04-281.1 | 2015-08-261.0 | 2015-04-29

1.5 | 2021-05-07

Fixed a deprecation notice with PHP 8.

1.4 | 2020-09-21

Added support for Gravity Forms 2.5.

1.3 | 2020-03-17

Added translations for Hebrew, Hindi, Japanese, and Turkish.
Added additional logging statements.
Updated the order of the API settings on the Forms > Settings > Emma page.
Updated API library to public property in support of Emma block.
Fixed PHP 7.4 notices which occur when the API is initializing and the settings are empty.
Fixed a PHP 7.4 notice which occurs on the feed configuration page when saving a new feed.
Fixed a fatal error which can occur if the Emma class is included by another plugin.

1.2 | 2017-04-28

Added security enhancements.
Added translations.
Added feed duplication support.
Fixed strings for translations

1.1 | 2015-08-26

Added support for delaying feed processing until payment by PayPal Standard is successfully completed.
Added gf_emma() for easily getting an Emma instance.
Added Spanish (es_ES) translation.
Updated 'Opt-In Condition' setting label to 'Conditional Logic'.
Updated feed processing to use get_field_value() when retrieving mapped field values, enabling support for GF_Field::get_value_export with GF 1.9.12.4 and later.
Updated feed processing to abort if email is empty or invalid.
Fixed PHP notice caused by Add-On Framework change in Gravity Forms 1.9.10.19.

1.0 | 2015-04-29

It's all new!

Emma Feed Meta

Emma Feed Meta

IntroductionUsagePropertiesCustom Field Properties

Introduction
The Feed Object meta for the Emma add-on is an associative array containing the properties which determine how the add-on should process the form submission.
$feed['meta'] = array(
'feed_name' => 'Your Feed Name',
'email_address' => '2',
'custom_fields' => array(),
'feed_condition_conditional_logic' => true,
'feed_condition_conditional_logic_object' => array(
'conditionalLogic' => array(),
),
);

Usage
We recommend accessing the $feed meta using the rgar() or rgars() functions, e.g.:
$conditional_logic_enabled = rgars( $feed, 'meta/feed_condition_conditional_logic' );

Properties

feed_name string
The feed name which appears on the add-ons feeds tab.

group string
The Emma Group ID this feed will add the member to.

email_address string
The ID of the form field containing the member email.

custom_fields array
A multidimensional array containing the Emma contact fields. See Custom Field Properties.

double_optin boolean
Should Emma send a confirmation email to the member. Default is false.

feed_condition_conditional_logic boolean
Is the feed condition (conditional logic) setting enabled. Default is false.

feed_condition_conditional_logic_object array
An associative array containing the conditional logic rules. See the Conditional Logic Object for more details.

Custom Field Properties
array(
'key' => 'address-full',
'value' => '3',
)

Each custom field is an associative array containing the following properties:

key string
The Emma contact fields Shortcut name.

value string
The ID of the form field or entry meta item containing the value for this custom field.

Enabling Conditional Logic for Confirmations

Enabling Conditional Logic for Confirmations

SummaryConfirmations SettingsExample

Summary

Sometimes you may want to send a user to a different page or display different information to them based on what they submit within the form. Here we will show you how to use conditional logic within your form confirmation messages.

Confirmations Settings

You will need to create a new confirmation as conditional logic is only available in additional confirmations.

Note: The Default Confirmation doesn』t have support for logic. This is intended as the form always needs to process one confirmation. The Default Confirmation will be used if the logic failed in additional confirmations.

Go to the Confirmations settings page of the form.

Here you can determine the criteria for sending the Confirmation.

Example

In this example we are using conditional logic to determine which confirmation the user should see based on their answer to the question 「Do you own a pet?」.

First we create a form with a field containing the question 「Do you own a pet?」.

Then we create a new confirmation for the people who answer yes.

Then we set the conditional logic accordingly. We set the condition to 「Do you own a pet?」 is 「Yes」.

The users who answer no will receive the default confirmation.

Enabling Conditional Logic for Notifications

Enabling Conditional Logic for Notifications

SummaryNotifications SettingsExample

Summary

Conditional logic can be used with Notifications to determine which notification is sent to the user based on the data they input into the form.

Notifications Settings

Go to the Notifications settings page of the form to enable conditional logic.

Here you can determine the criteria for sending the Notification.

Example

In this example we are using conditional logic to determine which notification should be sent to the user based on their answer to the question 「Do you own a pet?」.

First, we create a form with a field containing the question 「Do you own a pet?」.

Then we create two separate notifications: one for people who answer no and one for people for answer yes.

Then we enable conditional logic for each form accordingly. For the notification for people who do not have a pet, we set the conditional logic to 「Do you own a pet?」 is 「No」. This will send this notification to the users who said they do not own a pet.

For the notification for people who do have a pet, we set the conditional logic to 「Do you own a pet?」 is 「Yes」. This will send this notification to the users who said they do own a pet.

Click here to view a video demonstration.

Enabling Conditional Logic For A Field

Enabling Conditional Logic For A Field

IntroductionBasic Conditional Logic ExampleConditional Logic Example using SectionsLimitationsPerformance

Introduction

The Enable Conditional Logic option in the field settings allows you to create rules to dynamically display or hide the field based on values from another field. In order to use conditional logic, you will need to add a field to your form which supports conditional logic.

After enabling conditional logic for a field, you will have the option to show or hide the field depending on whether all/any of the conditions you specify are met. You can specify additional conditions by clicking the plus icon to right of the conditions. Clicking the minus sign will remove the corresponding condition.

Basic Conditional Logic Example

In this example, we will use conditional logic to show different products based on a parent category. A dropdown field will determine what products may be purchased based on the current selection.

First, set up your fields. As we will be using a dropdown to handle the display of various products, start off by creating a single dropdown, a few product fields, and a total field to display the order total. In this example, we have created 3 different options within the dropdown for Jeep, Ford, and Honda, as well as product fields such as Wrangler, Cherokee, and Mustang.

As we want Jeep models to show up when Jeep is selected, Ford models when Ford is selected, and Honda models when Honda is selected, we will need to enable conditional logic on each of these products. Open the options on one of your products by clicking on the field, and click on the Conditional Logic section.

Within the fly-out, you should see a toggle labeled Enable Conditional Logic. When toggled on, the options to conditionally display or hide this field will be shown.

On each of your products, simply enable conditional logic, and use the dropdowns to only show when your dropdown equals the desired selection. For example, for our Wrangler product, we have set it to only show if the Option field equals Jeep.

That』s all there is to creating basic conditional logic within products. You should now be able to conditionally show or hide fields based on other fields in your form.

Conditional Logic Example using Sections

In this example, we will use conditional logic to show different sections of a form based on the user』s input. A radio button field will determine which form section displays based on the current selection.

As we will be using a radio button field to handle the display of the sections, start off by creating a single radio button field. In this example, we have created 3 different options within the radio button for Cat, Dog, and Fish.

Next you will need to create the different sections of the form using the Section field. Create the 3 sections of Cat, Dog, and Fish with the necessary fields under each section break. In this case we used Single Line Text, Number, and Paragraph fields.

As we want the Cat section to show up when Cat is selected, Dog section when Dog is selected, and Fish section when Fish is selected, we will need to enable conditional logic on each of these sections. Open the options on one of your sections by clicking on the field, and click on the Conditional Logic section.

Within the fly-out, you should see a toggle labeled Enable Conditional Logic. If you click the toggle on, the options to conditionally display or hide this field will be shown.

On each of your sections, simply enable conditional logic, and use the dropdowns to only show when your dropdown equals the desired selection. For example, for our Cat section, we have set it to only show if the radio button field equals Cat.

Limitations

As mentioned above in the introduction, conditional logic rules must be based on values from another field, configuring conditional logic to display or hide a field based on its own values is not supported. Fields hidden by conditional logic are ignored on form submission, this is one of the main reasons to use conditional logic and can』t be changed. This means fields hidden will be not available for any process done after form submission (e.g. Calculations) and not saved in the entry.Certain special characters, like pipe (|) greater than and less than ( < > ) or HTML tags in field values, can prevent conditional logic rules from working as expected. To avoid this problem when using a field with pre-defined choices, like a Drop Down or Radio Buttons field, we recommend enabling the 「show values」 setting in the field and ensure you use only plain text in the Value column for the choices, without any special character or HTML tags. Nested conditional logic. Please check the following documentation page for more details.

Performance

Conditional logic evaluation is done at client side (the browser) using JavaScript, and unfortunately browsers are not super fast doing these tasks. The browser has to process all fields to evaluate conditional logic and know which fields to display/hide, along with any other JS scripts that you may have in the page. Also some conditional logic use cases can add extra work to the browser, e.g. If you』re using conditional logic to show/hide a field and also using this same field as value in another field conditional logic that would make the browser to be constantly checking both fields rules, creating a loop and increasing the CPU resource usage of the browser.

This means if you have a huge form with lots of fields you may experience slowness in the form displaying or usage, this is something expected due to the explained above. The only workaround for improving the conditional logic performance in this case would be to reduce the number of fields or split your form in many smaller forms.

In the following tutorial you can see how to pass data from one form to another if you need it: Using Confirmation Query Strings to Populate a Form Based on Another Submission. There』s also a third-party add-on that could help to simplify the process: Easy Passthrough.

Enable Editing of the Entry Payment Details

Enable Editing of the Entry Payment Details

The payment details panel on the entry detail page is usually only displayed when the entry was processed by a payment add-on. The ability to edit the payment details on this panel is usually only available when the entry was processed by the PayPal Standard add-on and the current payment status is set to Processing or Pending.
The following will allow you to enable the display of the payment details panel on the entry detail page and allow editing of those details for entries which were not processed by a payment add-on. Editing of Payment Details for entries already processed by a payment add-on is not supported.
For Gravity Forms 2.0 and newer you can use the Enable Gravity Forms Payment Details plugin.
For Gravity Forms versions older than 2.0, use the snippet below:
class RW_GF_Edit_Payment_Details {

public function __construct( $form_ids = array() ) {
if ( ! empty( $form_ids ) ) {
$this->_form_ids = $form_ids;
add_action( 'gform_loaded', array( $this, 'init' ) );
}
}

function init() {
if ( ! property_exists( 'GFForms', 'version' ) || ! version_compare( GFForms::$version, '1.9', '>=' ) ) {
return;
}

//add actions to allow the payment details to be modified
add_action( 'gform_payment_status', array( $this, 'admin_edit_payment_status' ), 10, 3 );
add_action( 'gform_payment_date', array( $this, 'admin_edit_payment_date' ), 10, 3 );
add_action( 'gform_payment_transaction_id', array( $this, 'admin_edit_payment_transaction_id' ), 10, 3 );
add_action( 'gform_payment_amount', array( $this, 'admin_edit_payment_amount' ), 10, 3 );
add_action( 'gform_after_update_entry', array( $this, 'admin_update_payment' ), 10, 2 );
add_action( 'gform_entries_first_column_actions', array( $this, 'maybe_set_payment_status' ), 10, 4 );

add_filter( 'gform_enable_entry_info_payment_details', '__return_false' );
}

public function maybe_set_payment_status( $form_id, $field_id, $value, $entry ) {
// payment details panel won't be displayed unless payment_status has a value
// only set the payment status when the entry is listed on the entries list page
// only set the payment status if its not already set and if it is the form we want
if ( rgempty( 'payment_status', $entry ) && in_array( $form_id, $this->_form_ids ) ) {
GFAPI::update_entry_property( $entry['id'], 'payment_status', 'Processing' );
}
}

public function admin_edit_payment_status( $payment_status, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_status;
}

//create drop down for payment status
$payment_string = '';

return $payment_string;
}

public function admin_edit_payment_date( $payment_date, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_date;
}

$payment_date = $entry['payment_date'];
if ( empty( $payment_date ) ) {
$payment_date = gmdate( 'y-m-d H:i:s' );
}

$input = '';

return $input;
}

public function admin_edit_payment_transaction_id( $transaction_id, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $transaction_id;
}

$input = '';

return $input;
}

public function admin_edit_payment_amount( $payment_amount, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_amount;
}

if ( empty( $payment_amount ) ) {
$payment_amount = GFCommon::get_order_total( $form, $entry );
}

$input = '';

return $input;
}

public function admin_update_payment( $form, $entry_id ) {
check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );

//update payment information in admin, need to use this function so the lead data is updated before displayed in the sidebar info section
$entry = GFFormsModel::get_lead( $entry_id );

if ( $this->payment_details_editing_disabled( $entry, 'update' ) ) {
return;
}

//get payment fields to update
$payment_status = rgpost( 'payment_status' );
//when updating, payment status may not be editable, if no value in post, set to lead payment status
if ( empty( $payment_status ) ) {
$payment_status = $entry['payment_status'];
}

$payment_amount = GFCommon::to_number( rgpost( 'payment_amount' ) );
$payment_transaction = rgpost( 'custom_transaction_id' );
$payment_date = rgpost( 'payment_date' );
if ( empty( $payment_date ) ) {
$payment_date = gmdate( 'y-m-d H:i:s' );
} else {
//format date entered by user
$payment_date = date( 'Y-m-d H:i:s', strtotime( $payment_date ) );
}

global $current_user;
$user_id = 0;
$user_name = 'System';
if ( $current_user && $user_data = get_userdata( $current_user->ID ) ) {
$user_id = $current_user->ID;
$user_name = $user_data->display_name;
}

$entry['payment_status'] = $payment_status;
$entry['payment_amount'] = $payment_amount;
$entry['payment_date'] = $payment_date;
$entry['transaction_id'] = $payment_transaction;

//update lead, add a note
GFAPI::update_entry( $entry );
GFFormsModel::add_note( $entry['id'], $user_id, $user_name, sprintf( __( 'Payment information was manually updated. Status: %s. Amount: %s. Transaction Id: %s. Date: %s', 'gravityformspaypal' ), $entry['payment_status'], GFCommon::to_money( $entry['payment_amount'], $entry['currency'] ), $payment_transaction, $entry['payment_date'] ) );
}

public function payment_details_editing_disabled( $entry, $action = 'edit' ) {
$gateway = gform_get_meta( $entry['id'], 'payment_gateway' );

if ( ! empty( $gateway ) ) {
// Entry was processed by a payment add-on, don't allow editing.
return true;
}

if ( rgar( $entry, 'payment_status' ) != 'Processing' ) {
// Editing not allowed for this entry.
return true;
}

if ( $action == 'edit' && rgpost( 'screen_mode' ) == 'edit' ) {
// Editing is allowed for this entry.
return false;
}

if ( $action == 'update' && rgpost( 'screen_mode' ) == 'view' && rgpost( 'action' ) == 'update' ) {
// Updating the payment details for this entry is allowed.
return false;
}

// In all other cases editing is not allowed.

return true;
}

}

// pass in an array of form ids you want to allow editing the payment details for
new RW_GF_Edit_Payment_Details( array( 11, 407, 48 ) );

The code snippet would go in your theme functions.php file or a custom functionality plugin.

Deprecation of the Gravity Forms Credit Card Field

Deprecation of the Gravity Forms Credit Card Field

NoticeDetailHow to Change Your Payment Collection MethodMore Help Needed?

Notice
The Gravity Forms Credit Card Field has been deprecated in the Stripe Add-On from version 3.4. Forms that are currently using this field will continue to work, however, it is not possible to add the field to new forms.
We recommend you migrate any solutions using this field so they use an alternative Stripe payment collection method.
Detail
This field displays inputs for the credit card details. Gravity Forms turns the field values into a token in the browser just before submission. It then passes the token along to Stripe』s servers for processing with a script that has been deprecated by Stripe. The last 4 digits of the card number are later stored in the entry details.
With this payment method, you (the website admin/owner) takes on the burden of the safe storage, handling and transmission of sensitive payment data. The Gravity Forms Credit Card field collection method is not SCA capable, and will complicate attempts to obtain PCI compliance.
This approach is considered the least secure option for Stripe Add-on payment collection, and is discouraged by Stripe.
Gravity Forms and Stripe recommend you migrate your solution away from the Gravity Forms Credit Card field to either of the other Stripe payment collection methods.
Deprecation will not affect existing forms already using this field.
How to Change Your Payment Collection Method
The payment option is contained within Stripe Add-On settings − refer to this article for details.
BE AWARE of the implications:
1. You are modifying a payment gateway. Test extensively! Try on a development sandbox first, or duplicate your form and test on a hidden page. Care is needed, and make sure you have a fallback plan. Nothing hurts more than a problem with the page that collects money!
1. Removing the credit card field will result in you losing any saved entry data already collected for that field. It holds only partial digits of the payment method, but be conscious of this.
1. If you choose to upgrade to Stripe Checkout, don』t forget to configure the Checkout options within your Stripe dashboard. This is handled outside of Gravity Forms.
More Help Needed?
If you have any additional questions, please contact our Support Team who will be happy to help.
List of relevant links:
Download official Stripe Add-On
Stripe Add-On Change Log
About Stripe Payment Collection methods
Support of SCA
About SCA
Stripe Security and PCI Compliance Validation

Deprecation of the Rocketgenius Namespace for Gravity Forms 2.5

Deprecation of the Rocketgenius Namespace for Gravity Forms 2.5

SummaryAffected AreasAdditional updatesMoving Forward

Summary

The top-level Rocketgenius namespace is being replaced with Gravity_Forms. These changes may break third party add-ons using the old namespace, even though they may have tested fine in previous beta releases of Gravity Forms 2.5

These namespaces were introduced in Gravity Forms 2.5, and none of them existed in any previous release of Gravity Forms. As such, this change has the potential to affect beta testers only.

Affected Areas

Add-ons which are extending any class which previously had a Rocketgenius namespace will need to update those class references to Gravity_Forms.

These include:

RocketgeniusGravity_FormsSettings is now Gravity_FormsGravity_FormsSettingsSettingsRocketgeniusGravity_FormsFields, are all now Gravity_FormsGravity_FormsFieldsRocketgeniusGravity_FormsTranslationsPress_Updater is now Gravity_FormsGravity_FormsTranslationsPress_Updater

Additionally, if developers solutions are requiring any of the class files referenced above in their own add-ons, they』ll need to update those references, as well.

Additional updates

Changing the fully-qualified namespace for the new Settings class from RocketgeniusGravity_Forms to Gravity_FormsGravity_FormsSettings, because the Settings class file is in the settings subdirectory (thus, it now has the same namespace as the adjacent Fields class in the same directory.Renaming class files for Checkbox_And_Select and Text_And_Select to class-checkbox-and-select.php and class-text-and-select.php, respectively.Renaming the class file for TranslationsPress_Updater from class-t15s-updater.php to class-translationspress-updater.php, and updating associated require statements for that class file.

Moving Forward

This namespace update reflects the newly established standard for current and future Gravity Forms product development. Our expectation is that these namespaces will not change again. Any new classes which get added to Gravity Forms core or official Gravity Forms add-ons, will include the Gravity_Forms top-level namespace only.

CSS Visual Guide and Design Overview

CSS Visual Guide and Design Overview

Element Relationships (HTML and PNG)Element NamingConfigurable ClassesForm Wrapper ClassesTheme & Markup ClassesLabel Position ClassesField Size ClassesCustom ClassesCSS Ready ClassesCSS Targeting Examples

Element Relationships (HTML and PNG)

We』ve put together a visual guide to the Gravity Forms CSS hierarchy to illustrate the structure of a form and the CSS class relationship.

You can access it on a few formats here:

View Visual CSS Guide (HTML Version) | Download Guide (png)

Element Naming

Gravity Forms are structured so that every element can be targeted and manipulated via CSS. Most elements share reusable class names to affect styling, and many elements have unique ID』s that you can use to target specific elements within the form. By using CSS inheritance, you can effectively style every element in your form.

All element ID』s are based on the unique form ID and then a field ID.For example:

#gform_wrapper_xx where 「xx」 is the form ID, or#field_xx_yyy where 「xx」 is the form ID and 「yyy」 is the field ID.

Configurable Classes

Form Wrapper Classes

Theme & Markup Classes

There are 2 classes applied to the form wrapper based on whether or not legacy mode is enabled for a form. The class .gravity-theme is applied to all forms that do no have legacy mode enabled. The class .gform_legacy_markup_wrapper is applied to all forms that have legacy mode enabled.

Label Position Classes

There are 3 label classes that are applied to the form wrapper based on the individual form settings, .top_label, .left_label and .right_label.

Other elements change positions, widths, etc. based on inheritance from these label classes.

Field Size Classes

For many of the individual fields, there are classes of .small, .medium and .large which are defined in the form admin by changing the field size setting.

Custom Classes

Finally, for most of the fields, the user can define additional class names with the Custom CSS Class setting in order to apply additional custom styles or to target elements for other types of manipulation.

CSS Ready Classes

Using Ready Classes, you can easily create more advanced alternative layouts for the fields in your forms. Essentially, Ready Classes are class names that you can add to the parent element surrounding each field to take advantage of pre-defined styles included in the default form stylesheet.

Note that the column and inline ready classes were deprecated with the improvements made to the form editor in Gravity Forms 2.5.

CSS Targeting Examples

This article contains a few basic usage examples for targeting each element, one that would be generic for all forms and then one (or two) that would be specific to a unique form ID. If you』re styling a specific form, you would simply view your source, find the form ID and replace the ID in these examples with your own.