Add-On Framework

Introduction

The Add-On Framework provides basic functionality for developers when creating new add-ons for Gravity Forms. It facilitates the following:

  • Initialization
  • Enforcing Gravity Forms minimum version requirement
  • Creating settings pages (add-on and form settings)
  • Permissions and integration with the Members plugin
  • Conditional script enqueuing including no-conflict mode integration
  • Adding custom meta fields to the entry object
  • Creating form feeds
  • Creating a results page
  • Adding notes to the entry
  • Integration with the Gravity Forms Locking API
  • Registering notification events
  • Standardization of UI elements and styles
  • Automatic clean uninstall

How It Works

To create a new add-on, simply extend one of the following classes:

  • GFAddOn Extend the GFAddOn class to create add-ons that are either very simple or that don't fit into the more specialized cases below (GFFeedsAddOn and GFPaymentAddOn). This class will help to make sure all the scripts are enqueued on the right page. It'll speed up the development of settings pages and it eliminates the need to write some of the housekeeping tasks like clean uninstall.

  • GFFeedAddOn Extend the GFFeedAddOn class to create add-ons that give users the ability to create form feeds. A feed is a user-configurable action that gets processed after a form is submitted. With this class, you get all of the features of the GFAddOn class plus some additional functionality to facilitate the development of the feed settings UI and conditional processing. For examples of add-ons that use feeds, check out the MailChimp Add-On and the Coupons Add-On.

  • GFPaymentAddOn Extend the GFPaymentAddOn class when creating new add-ons for Gravity Forms that collect payments. It handles payments which redirect to a third-party website (e.g., PayPal Standard) and payments which are made using a credit card with the transaction hidden behind-the-scenes (e.g., Authorize.Net, PayPal Payments Pro, and Stripe).

Settings API

The Settings API can be used to create feed 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, checkboxes and also custom field types.

A Simple Add-On

The following code demonstrates the following:

  • basic configuration of the add-on
  • including the Add-On Framework in a plugin
  • extending the GFAddOn class
  • enforcing the requirement for the minimum version of Gravity Forms
  • adding a top-level page to the Forms menu
  • adding a form settings tab and add one checkbox
  • adding an add-on settings tab to the Gravity Forms settings page with one textbox

The bootstrap file, simpleaddon.php, contains no dependency on Gravity Forms. This is important because it allows the add-on to load correctly by WordPress even if Gravity Forms hasn't been loaded yet.

This file then uses the "gform_loaded" Gravity Forms hook to properly initialize the add-on once Gravity Forms has been loaded.

Below is an example of what this bootstrap file should look like (minus the plugin headers).

define( 'GF_SIMPLE_ADDON_VERSION', '2.0' );

add_action( 'gform_loaded', array( 'GF_Simple_AddOn_Bootstrap', 'load' ), 5 );

class GF_Simple_AddOn_Bootstrap {

    public static function load() {

        if ( ! method_exists( 'GFForms', 'include_addon_framework' ) ) {
            return;
        }

        require_once( 'class-gfsimpleaddon.php' );

        GFAddOn::register( 'GFSimpleAddOn' );
    }

}

function gf_simple_addon() {
    return GFSimpleAddOn::get_instance();
}

Note in the above example that the add-on is initialized by including the class-gfsimpleaddon.php file when gform_loaded is fired.

GFForms::include_addon_framework();

class GFSimpleAddOn extends GFAddOn {

    protected $_version = GF_SIMPLE_ADDON_VERSION;
    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';

    private static $_instance = null;

    public static function get_instance() {
        if ( self::$_instance == null ) {
            self::$_instance = new GFSimpleAddOn();
        }

        return self::$_instance;
    }

    public function init() {
        parent::init();
        add_filter( 'gform_submit_button', array( $this, 'form_submit_button' ), 10, 2 );
    }

    public function scripts() {
        $scripts = array(
            array(
                'handle'  => 'my_script_js',
                'src'     => $this->get_base_url() . '/js/my_script.js',
                'version' => $this->_version,
                'deps'    => array( 'jquery' ),
                'strings' => array(
                    'first'  => esc_html__( 'First Choice', 'simpleaddon' ),
                    'second' => esc_html__( 'Second Choice', 'simpleaddon' ),
                    'third'  => esc_html__( 'Third Choice', 'simpleaddon' )
                ),
                'enqueue' => array(
                    array(
                        'admin_page' => array( 'form_settings' ),
                        'tab'        => 'simpleaddon'
                    )
                )
            ),

        );

        return array_merge( parent::scripts(), $scripts );
    }

    public function styles() {
        $styles = array(
            array(
                'handle'  => 'my_styles_css',
                'src'     => $this->get_base_url() . '/css/my_styles.css',
                'version' => $this->_version,
                'enqueue' => array(
                    array( 'field_types' => array( 'poll' ) )
                )
            )
        );

        return array_merge( parent::styles(), $styles );
    }

    function form_submit_button( $button, $form ) {
        $settings = $this->get_form_settings( $form );
        if ( isset( $settings['enabled'] ) && true == $settings['enabled'] ) {
            $text   = $this->get_plugin_setting( 'mytextbox' );
            $button = "</pre>
<div>{$text}</div>
<pre>" . $button;
        }

        return $button;
    }

    public function plugin_page() {
        echo 'This page appears in the Forms menu';
    }

    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' ),
                    )
                )
            )
        );
    }

    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,
                                    ),
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        );
    }

    public function settings_my_custom_field_type( $field, $echo = true ) {
        echo '</pre>
<div>' . esc_html__( 'My custom field contains a few settings:', 'simpleaddon' ) . '</div>
<pre>';

        // 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 );
    }

    public function is_valid_setting( $value ) {
        return strlen( $value ) > 5;
    }

}

The above example add-on is available on GitHub, including inline documentation: https://github.com/rocketgenius/simpleaddon.