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).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | 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.