IntroductionGetting StartedThe Class VariablesActivating FeaturesRequiring DependenciesInitializationSettings APICreating Form SettingsAccessing Form SettingsAdding Custom Settings to the Main Form Settings TabCreating Plugin SettingsAccessing Plugin SettingsEnqueuing Scripts and StylesResults PageEntry MetaObject Locking APIUninstallingSample Add-On
Introduction
The GFAddOn class provides basic functionality for developers when creating new add-ons for Gravity Forms. It facilitates the following:
InitializationEnforcing Gravity Forms minimum version requirementCreating settings pages (add-on and form settings)Permissions and integration with the Members pluginConditional script enqueuing including no-conflict mode integrationAdding custom meta fields to the entry objectCreating a results pageIntegration with the Gravity Forms Locking APIStandardization of UI elements and stylesAutomatic clean uninstall
Getting Started
These are the first steps you』ll need to take to create an add-on using the Add-On Framework:
Create two PHP files. The first file handles registering your add-on. The second file will contain your add-on』s functionality. See A Simple Add-On in the Add-On Framework article for an example.In the second PHP file you would include the Add-On Framework files by calling the following:
GFForms::include_addon_framework();
Inherit the Add-On Framework by creating a new class which extends GFAddOn:
class GFSimpleAddOn extends GFAddOn {}
Add the class variables to configure the add-on.
protected $_version = '1.0';
protected $_min_gravityforms_version = '1.9';
protected $_slug = 'simpleaddon';
protected $_path = 'simpleaddon/simpleaddon.php';
protected $_full_path = __FILE__;
protected $_title = 'Gravity Forms Simple Add-On';
protected $_short_title = 'Simple Add-On';
Add support for getting an instance of the add-on. When Gravity Forms is loading it initializes the add-ons; it does this by looping through each registered add-on and calling its get_instance function. Adding a get_instance function also helps other developers integrate with your add-on.
/**
* @var object|null $_instance If available, contains an instance of this class.
*/
private static $_instance = null;
/**
* Returns an instance of this class, and stores it in the $_instance property.
*
* @return object $_instance An instance of this class.
*/
public static function get_instance() {
if ( self::$_instance == null ) {
self::$_instance = new self();
}
return self::$_instance;
}
The Class Variables
$_version string
The version of this add-on.
$_min_gravityforms_version string
The version of Gravity Forms required for this add-on.
$_slug string
A short, lowercase, URL-safe unique identifier for the add-on. This will be used in option keys, filter, actions, URLs, and text-domain localization. The maximum size allowed for the slug is 33 characters.
$_path string
Relative path to the plugin from the plugins folder. Example 「gravityforms/gravityforms.php」
$_full_path string
The physical path to the main plugin file. Set this to __FILE__
$_title string
The complete title of the Add-On.
$_short_title string
The short title of the Add-On to be used in limited spaces.
Activating Features
The Add-On Framework contains many features that can be activated by overriding functions in the base class (GFAddOn). To override a function, add a function with the same name (and arguments) as the function in the base class.
A good example of this is the plugin page. If you take a look at the code in GFAddOn you』ll see an empty function called plugin_page() that looks like this:
/**
* Override this function to create a custom plugin page
*/
protected function plugin_page() {}
This function in GFAddOn does nothing; it』s just a placeholder with documentation explaining how to use it. To activate the plugin page and add a menu link for your add-on to the Forms menu, add the following function to the add-on:
/**
* Creates a custom page for this add-on.
*/
public function plugin_page() {
echo 'This page appears in the Forms menu';
}
Now the function in the base class has been overridden, the feature has been activated, and the link to the page will appear in the Forms menu.
There are many features like this in the Add-On Framework. Please read through the documentation on this page for further details of the features and how to activate them.
Requiring Dependencies
If your Gravity Forms add-on has any requirements that might not be present everywhere, it』s a good idea to define those dependencies using the minimum_requirements() class method. Within this class method, you will be able to define things such as Gravity Forms/WordPress/PHP versions, other Gravity Forms add-ons, PHP modules, and even other plugins that your Gravity Forms add-on might require.
Example:
array(
// Require WordPress version 4.6.2 or higher.
'wordpress' => array(
'version' => '4.6.2'
),
// Require PHP version 5.3 or higher.
'php' => array(
'version' => '5.3',
// Require specific PHP extensions.
'extensions' => array(
// Require cURL version 1.0 or higher.
'curl' => array(
'version' => '1.0'
),
// Require any version of mbstring.
'mbstring',
),
// Require specific functions to be available.
'functions' => array(
'openssl_random_pseudo_bytes',
'mcrypt_create_iv'
),
),
// Require other add-ons to be present.
'add-ons' => array(
// Require any version of the Mailchimp add-on.
'gravityformsmailchimp',
// Require the Stripe add-on and ensure the name matches.
'gravityformsstripe' => array(
'name' => 'Gravity Forms Stripe Add-On'
),
// Require the PayPal add-on version 5.0 or higher.
'gravityformspaypal' => array(
'version' => '5.0'
),
),
// Required plugins.
'plugins' => array(
// Require the REST API.
'rest-api/plugin.php',
// Require Jetpack and ensure the name matches.
'jetpack/jetpack.php' => 'Jetpack by WordPress.com',
),
// Any additional custom requirements via callbacks.
array( $this, 'custom_requirement' ),
);
Initialization
The Add-On Framework provides the following functions to help with initialization and to help organize your code:
pre_init()Override this function to perform any tasks that need to be done before the WordPress action 「init」 fires init()Override this function to perform tasks during WordPress initialization init_admin()Override this function to perform tasks only in the admin back-end init_frontend()Override this function to perform tasks only in the front-end init_ajax()Override this function to perform tasks only while processing ajax requests
IMPORTANT: call the parent function first. e.g. parent::init();
Example:
GFForms::include_addon_framework();
class GFSimpleAddOn extends GFAddOn {
// [snip: class variables]
public function pre_init() {
parent::pre_init();
// add tasks or filters here that you want to perform during the class constructor - before WordPress has been completely initialized
}
public function init() {
parent::init();
// add tasks or filters here that you want to perform both in the backend and frontend and for ajax requests
}
public function init_admin() {
parent::init_admin();
// add tasks or filters here that you want to perform only in admin
}
public function init_frontend() {
parent::init_frontend();
// add tasks or filters here that you want to perform only in the front end
}
public function init_ajax() {
parent::init_ajax();
// add tasks or filters here that you want to perform only during ajax requests
}
}
Settings API
The Add-On Framework includes a Settings API that can be used to create form and plugin settings pages. The API provides the mechanisms for rendering field UIs and saving values automatically. It supports standard field types like radio buttons, text boxes, and checkboxes and also custom field types.
See the Settings API for details about how to define sections of fields.
See the following articles for implementation examples of the various field types.
Text (『type』 => 『text』)Textarea Field (『type』 => 『textarea』)Hidden Field (『type』 => 『hidden』)Radio Field (『type』 => 『radio』)Checkbox Field (『type』 => 『checkbox』)Select Field (『type』 => 『select』)Select_Custom Field (『type』 => 『select_custom』)Field_Map Field (『type』 => 『field_map』)Field_Select Field (『type』 => 『field_select』)Dynamic_Field_Map Field (『type』 => 『dynamic_field_map』)Checkbox_And_Select Field (『type』 => 『checkbox_and_select』)Save Button (『type』 => 『save』)Custom Field Type
There are also a number of Helper Functions available for use when rendering custom settings.
Creating Form Settings
To create a tab on the Form Settings page, override the form_settings_fields() function returning an array with the configuration for the settings.
Complete example with all field types:
/**
* Configures the settings which should be rendered on the Form Settings > Simple Add-On tab.
*
* @return array
*/
public function form_settings_fields( $form ) {
return array(
array(
'title' => esc_html__( 'Simple Form Settings', 'simpleaddon' ),
'fields' => array(
array(
'label' => esc_html__( 'My checkbox', 'simpleaddon' ),
'type' => 'checkbox',
'name' => 'enabled',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'choices' => array(
array(
'label' => esc_html__( 'Enabled', 'simpleaddon' ),
'name' => 'enabled',
),
),
),
array(
'label' => esc_html__( 'My checkboxes', 'simpleaddon' ),
'type' => 'checkbox',
'name' => 'checkboxgroup',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'choices' => array(
array(
'label' => esc_html__( 'First Choice', 'simpleaddon' ),
'name' => 'first',
),
array(
'label' => esc_html__( 'Second Choice', 'simpleaddon' ),
'name' => 'second',
),
array(
'label' => esc_html__( 'Third Choice', 'simpleaddon' ),
'name' => 'third',
),
),
),
array(
'label' => esc_html__( 'My Radio Buttons', 'simpleaddon' ),
'type' => 'radio',
'name' => 'myradiogroup',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'choices' => array(
array(
'label' => esc_html__( 'First Choice', 'simpleaddon' ),
),
array(
'label' => esc_html__( 'Second Choice', 'simpleaddon' ),
),
array(
'label' => esc_html__( 'Third Choice', 'simpleaddon' ),
),
),
),
array(
'label' => esc_html__( 'My Horizontal Radio Buttons', 'simpleaddon' ),
'type' => 'radio',
'horizontal' => true,
'name' => 'myradiogrouph',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'choices' => array(
array(
'label' => esc_html__( 'First Choice', 'simpleaddon' ),
),
array(
'label' => esc_html__( 'Second Choice', 'simpleaddon' ),
),
array(
'label' => esc_html__( 'Third Choice', 'simpleaddon' ),
),
),
),
array(
'label' => esc_html__( 'My Dropdown', 'simpleaddon' ),
'type' => 'select',
'name' => 'mydropdown',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'choices' => array(
array(
'label' => esc_html__( 'First Choice', 'simpleaddon' ),
'value' => 'first',
),
array(
'label' => esc_html__( 'Second Choice', 'simpleaddon' ),
'value' => 'second',
),
array(
'label' => esc_html__( 'Third Choice', 'simpleaddon' ),
'value' => 'third',
),
),
),
array(
'label' => esc_html__( 'My Text Box', 'simpleaddon' ),
'type' => 'text',
'name' => 'mytext',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'class' => 'medium',
'feedback_callback' => array( $this, 'is_valid_setting' ),
),
array(
'label' => esc_html__( 'My Text Area', 'simpleaddon' ),
'type' => 'textarea',
'name' => 'mytextarea',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'class' => 'medium merge-tag-support mt-position-right',
),
array(
'label' => esc_html__( 'My Hidden Field', 'simpleaddon' ),
'type' => 'hidden',
'name' => 'myhidden',
),
array(
'label' => esc_html__( 'My Custom Field', 'simpleaddon' ),
'type' => 'my_custom_field_type',
'name' => 'my_custom_field',
'args' => array(
'text' => array(
'label' => esc_html__( 'A textbox sub-field', 'simpleaddon' ),
'name' => 'subtext',
'default_value' => 'change me',
),
'checkbox' => array(
'label' => esc_html__( 'A checkbox sub-field', 'simpleaddon' ),
'name' => 'my_custom_field_check',
'choices' => array(
array(
'label' => esc_html__( 'Activate', 'simpleaddon' ),
'name' => 'subcheck',
'default_value' => true,
),
),
),
),
),
),
),
);
}
/**
* Define the markup for the my_custom_field_type type field.
*
* @param array $field The field properties.
*/
public function settings_my_custom_field_type( $field ) {
echo '
';
// get the text field settings from the main field and then render the text field
$text_field = $field['args']['text'];
$this->settings_text( $text_field );
// get the checkbox field settings from the main field and then render the checkbox field
$checkbox_field = $field['args']['checkbox'];
$this->settings_checkbox( $checkbox_field );
}
/**
* The feedback callback for the 'mytextbox' setting on the plugin settings page and the 'mytext' setting on the form settings page.
*
* @param string $value The setting value.
*
* @return bool
*/
public function is_valid_setting( $value ) {
return strlen( $value ) > 10;
}
The code above will create a tab on the Form Settings page for the Simple Add-On and look similar to the following:
Accessing Form Settings
The form settings for the current add-on can be accessed easily by using the function get_form_settings($form). This returns an associative array with the settings for the current add-on for the given form.
Example:
$settings = $this->get_form_settings( $form );
Adding Custom Settings to the Main Form Settings Tab
To add a custom setting to the main form settings tab, please consult the documentation for the gform_form_settings hook. Here』s a quick example of how you』d implement it with the Add-On Framework:
GFForms::include_addon_framework();
class GFSimpleAddOn extends GFAddOn {
// [snip: class variables]
public function init() {
parent::init();
add_filter( 'gform_form_settings', array( $this, 'my_custom_form_setting' ), 10, 2 );
add_filter( 'gform_pre_form_settings_save', array( $this, 'save_my_custom_form_setting' ) );
}
function my_custom_form_setting( $settings, $form ) {
$settings['Form Basics']['my_custom_setting'] = '
';
return $settings;
}
function save_my_custom_form_setting( $form ) {
$form['my_custom_setting'] = rgpost( 'my_custom_setting' );
return $form;
}
}
Creating Plugin Settings
Plugin settings pages appear in a tab in the Gravity Forms settings page. To create a settings page, override the plugin_settings_fields() function using the same array structure as described above for the form settings.
Example:
/**
* Configures the settings which should be rendered on the add-on settings tab.
*
* @return array
*/
public function plugin_settings_fields() {
return array(
array(
'title' => esc_html__( 'Simple Add-On Settings', 'simpleaddon' ),
'fields' => array(
array(
'name' => 'mytextbox',
'tooltip' => esc_html__( 'This is the tooltip', 'simpleaddon' ),
'label' => esc_html__( 'This is the label', 'simpleaddon' ),
'type' => 'text',
'class' => 'small',
'feedback_callback' => array( $this, 'is_valid_setting' ),
)
)
)
);
}
[/php]
Accessing Plugin Settings
The plugin settings for the current add-on can be accessed easily by using the following functions:
get_plugin_settings()returns all plugin settings in an associative array get_plugin_setting( $setting_name )returns a single setting with the given setting name e.g. 「my_setting_name」
Example:
$all_plugin_settings = $this->get_plugin_settings();
$text = $this->get_plugin_setting( 'mytextbox');
Enqueuing Scripts and Styles
See the Including Scripts and Styles When Using the Add-on Framework article.
Results Page
To add a results page, override the get_results_page_config() function and return the configuration array with the following properties:
title string
The title of the results page.
capabilities array
An array of capabilities that can view the results page.
callbacks array
An array of callback functions. Possible values: fields, markup, calculation
Example:
public function get_results_page_config() {
return array(
'title' => 'Poll Results',
'capabilities' => array( 'gravityforms_polls_results' ),
'callbacks' => array(
'fields' => array( $this, 'results_fields' )
)
);
}
public function results_fields( $form ) {
return GFAPI::get_fields_by_type( $form, array( 'poll' ) );
}
[/php]
Entry Meta
See the Including and using Entry Meta with the Add-On Framework article.
Object Locking API
The Gravity Forms Object Locking API prevents conflicts from occurring by preventing concurrent editing by different users of forms, entries, form settings and plugin settings. This eliminates the problem of users overwriting the changes made be other users. When one user is editing an object, the second user will be offered the choice to request control over the object. The first user will then be offered the choice to accept or deny that request. If the first user fails to respond, the second user will be offered control.
The Locking API uses the WordPress Heartbeat API to send updates at regular intervals, usually every 15 seconds when the page has focus, and every 2 minutes when the page doesn』t have the focus.
The Add-On Framework provides developers access to the Object Locking API in 2 ways:
Locking is automatically implemented for form settings and plugin settings – nothing additional is required for this to work. Locking for custom objects. For example, an add-on that manages employee information may have an 「employee」 object. The Add-On Framework will prevent concurrent editing of the employee profile.
Locking is activated by overriding the following functions:
get_locking_config()Return an array with the locking configuration to activate locking get_locking_object_id()Return the object id is_locking_edit_page()Return true if the current page is the edit page is_locking_view_page()Return true if the current page is the view page is_locking_list_page()Return true if the current page is the list page
public function get_locking_config(){
$strings = array(
"currently_locked" => __('This contact is currently locked. Click on the "Request Control" button to let %s know you'd like to take over.', "gravityforms"),
"currently_editing" => "%s is currently editing this contact",
"taken_over" => "%s has taken over and is currently editing this contact.",
"lock_requested" => __("%s has requested permission to take over control of this contact.", "gravityforms")
);
$contact_id = $this->get_object_id();
$config = array(
"object_type" => "contact",
"capabilities" => array("gravityforms_contacts_edit_contacts"),
"redirect_url" => admin_url(sprintf("admin.php?page=gf_contacts&view=contact&subview=profile&id=%d&edit=0", $contact_id)),
"edit_url" => admin_url(sprintf("admin.php?page=gf_contacts&view=contact&subview=profile&id=%d&edit=1", $contact_id)),
"strings" => $strings
);
return $config;
}
public function get_locking_object_id(){
return rgget("id");
}
public function is_locking_edit_page(){
$is_edit_page = rgget("page") == "gf_contacts" && rgget("view") == "contact" && rgget("subview") == "profile" && rgget("edit") == 1;
return $is_edit_page;
}
public function is_locking_view_page(){
$is_view_page = rgget("page") == "gf_contacts" && rgget("view") == "contact" && rgget("subview") == "profile" && rgget("edit") == 0;
return $is_view_page;
}
public function is_locking_list_page(){
$is_list_page = rgget("page") == "gf_contacts" && rgempty("view", $_GET);
return $is_list_page;
}
Uninstalling
All Gravity Forms Add-Ons should provide a way to remove settings completely before the user deactivates and deletes the plugin. The Add-On Framework handles much of this for you so you don』t need to configure anything unless you』ve added settings or database tables of your own. The uninstall button will be on the plugin settings page. The following elements will be removed automatically when the user uninstalls the add-on.
Form settingsPlugin settingsEntry metaVersion information
If you need to perform additional tasks such as removing custom options or database tables then override the uninstall() function. This will be called after permissions have been checked and before removing all the settings.
Example:
public function uninstall() {
// custom code to drop database tables and remove custom options
}
The uninstall section of the settings page can be modified or removed completely by overriding the render_uninstall() function.
Example:
public function render_uninstall() {
// an empty function will remove the uninstall section on the settings page
}
Sample Add-On
A sample add-on is available which demonstrates the basic features of the Add-On Framework:
Plugin pageForm SettingsPlugin SettingsScripts and Styles
https://github.com/rocketgenius/simpleaddon