Note: this is the second in a series of tutorials helping developers to extend Gravity Forms.
In the first tutorial, I gave an introduction to the Gravity Forms developer platform and demonstrated how each of the tools could be used to build a simple add-on. In this second tutorial, I’m going to be delving a little deeper by using the Gravity Forms Feed Add-On Framework to demonstrate how Gravity Forms and WordPress can be extended further to build a fairly sophisticated workflow application.
There’s no shortage of use cases for a form-based approval workflow. Let’s take a look at a few to get some context for our solution:
- Flexible configuration by non-technical users; no hard-coded workflows.
- Each Form will have different rules for approval and different users as approvers.
- The rules for approval will depend on conditional logic for field values (e.g. invoice amount, approval status).
- Notifications must be sent in response to approval and rejection and must be flexible enough to send multiple notifications each with a different conditional logic.
- Notifications to approvers must contain a deep link to the form with immediate access to the approve and reject buttons.
- When approval is required for a form, delay actions performed by the User Registration Add-On and the Zapier Add-On until the form has been approved by all approvers.
- Pending approvals for each approver must appear in a personalised list on the WordPress Dashboard.
- Approved or rejected forms cannot be edited.
- Approvers can’t change their approval status once committed.
We’ll need to extend Gravity Forms in the following steps:
- Create an Add-On that uses the Feed Add-On Framework. One feed will be created for each approver and will support conditional logic.
- Add custom Entry Meta fields to store the approval status for each approver.
- Add a Feed Settings tab to the Form Settings UI that will list approvers and allow admins to add new approvers to a form.
- Add a box on the Entry detail page to show the current approval status and approval buttons to approvers.
- Add a WordPress Dashboard widget and display a list of pending approvals for the currently logged in user.
- Integrate with the User Registration Add-On and the Zapier Add-On so that form approval triggers WordPress user account creation and the sending of data to third party services e.g. Google Sheets, Freshbooks, OpenERP…
- Add a notification event ‘form is approved or rejected’ to the Notifications UI.
Step 1: Extending the Feed Add-On Framework
A feed is a user-defined action that gets processed conditionally after a form has been submitted. Feeds are used in a number of Gravity Forms Add-Ons including the Paypal Add-Ons, Coupons Add-On, User Registration Add-On, MailChimp Add-On, Zapier Add-On and the AWeber Add-On to allow multiple actions to be triggered after a form has been submitted. In this case, we’re going to use feeds to assign approvers to each form. Feeds support conditional logic so approvers can be assigned to entries based on the value of a field. For example, in the case of incoming invoices our admins can configure an approval feed for the Finance Director when the invoice amount exceeds $9,999.
Step 2: Entry Meta
Entry Meta fields are like form fields except they don’t appear either on the front-end form or the entry editor and they can only be updated via code. This makes them ideal for storing meta data such as approval status. Users will be able to filter the entries by approver and by approval status on the entry list and we’ll be able to use the Gravity Forms API to display the personalised list of pending approvals on the WordPress Dashboard.
To configure the Entry Meta fields we just override GFAddOn::get_entry_meta() and return the configuration for the approval status of each approver and the overall approval status.
Notice that we register a callback for the overall approval status update event, but not for the individual approval status for each approver. This is because we don’t need to set the entry meta for the approvers when the entry is updated – we only need to set the overall approval status. We’ll assign the approvers conditionally using the the GFFeedAddOn::process_feed() in the next step.
Step 3: Feed Settings
The Feed Settings UI is going to provide a way for admins to assign approvers conditionally to forms. So instead of overriding GFAddOn::form_settings_fields() as we did in the previous tutorial we’ll need to override GFFeedAddOn::feed_settings_fields() and return the array with the configuration of the fields.
We’ll need to override GFFeedAddOn::feed_list_columns() so our fields are added as columns to the feed list page, and GFFeedAddOn::process_feed() to handle the form submission event. The processing of the feed, in our case, just means assigning the approver to the entry. We don’t need to hardcode any conditional logic because this method will only run if the conditions are met – the logic is handled behind the scenes by the framework.
See the Settings API for further details on how to create settings pages.
This will produce a list of feeds and an edit page that looks like this:
Step 4: WordPress Dashboard Widget
The personalised inbox of pending approvals will be displayed using the WordPress Dashboard API.
For this we’ll need GFAPI::get_entries() to search the entries with a couple of search criteria to ensure we only get the entries pending approval for the current user.
Notice the three different links:
- All entries pending the approval of the current user
- All entries submitted by the requester
- Direct link to the entry
Step 5: Add a custom event to the Notifications UI
Notifications in Gravity Forms are user-defined emails that can be triggered conditionally, routed to different email addresses and contain field values. By default, notifications are processed on form submission.
The Notifications UI page contains a filter called gform_notification_events which allows us to add custom events. This provides us with a way to separate notifications sent on form submission from the notifications we’ll need to send when a form is approved or rejected. So for example, in the case of the incoming invoices, we don’t want to notify the Finance Director until the invoice has been approved by the department Director. We’ll still need to write the code to handle the event and send the notifications at the appropriate time but this is a handy way to reuse some existing admin functionality in Gravity Forms.
Step 6: Integration with the User Registration and Zapier Add-Ons
The Zapier Add-On providers users with point-and-click integration of Gravity Forms with literally hundreds of different Web Services, for example Freshbooks, QuickBooks, Trello and Salesforce. In our use cases, we can use the Zapier Add-On to send form data to Google Sheets and OpenERP.
The User Registration Add-On handles the creation and updating of WordPress user accounts. It’s very flexible and allows conditional registration and will map form field to user profile fields and custom fields.
For our solution, we’ll need to make sure that the Zapier and User Registration Add-Ons don’t trigger their actions immediately on form submission so our Approvals Add-on can trigger them once the entry has been approved. The User Registration Add-On has the gform_disable_registration filter we can use but Zapier currently doesn’t have an equivalent hook so we’ll need to get a little creative and make sure its registered action hook is removed before it can be triggered.
Step 7: Entry Detail Approvals Meta Box
Finally, this is the code that brings everything together. It’s the UI that approvers use to approve or reject entries. It also contains the code that triggers the notifications registered with our custom notification event, user account creation, and sending data to Zapier.
Complete Code Listing
View the complete listing: approvals.php
Download the complete zip file of the add-on: gravityformsapprovals.zip
Now we’ve got Gravity Forms to support approvals we need to set up the forms and configure the business logic for each workflow. If you’re already familiar with Gravity Forms then this section is perhaps unnecessary but I’ve included it here for for completeness and for readers who are not so familiar.
In the use cases described above, the HR dept needs only one approval feed per form and per department. The example vacation request form contains the following fields. Some of these fields can be set automatically by specifying the appropriate merge tags in the default value settings.
So for each form we need to add one approver per department. Each approval feed will look something like this.
Notifications are configured separately on the Notifications tab. In this case we’d need one notification for the approvers – something like this:
In the case of the incoming invoices form, we’ll need a form that looks something like this:
The approval feed for each department might like this:
We also need an additional feed for the Finance Director in the case of high value invoices.
We’ll need to configure a notification with conditional routing like the vacation request form and an additional notification for the Finance Director for forms that need her approval. Notice the conditional logic ensuring that the form has not previously been rejected by a colleague.
Although this add-on is very simple, it’s not intended to be used in a production environment and it hasn’t been tested in a multi-site installation. It’s intended to be used primarily as a learning tool. If you do decide to use it in a production environment, please ensure that you do sufficient testing and that security issues are taken into consideration. At minimum use SSL in the WordPress admin.
There are many ways this idea could be developed further or adapted to fit different scenarios. Here are some ideas for next steps:
- Integrate the forms with internal systems
- LDAP integration
- Create the default notifications automatically when each feed is saved
- Install the Members plugin or similar and configure appropriate permissions
- Add entry meta for approval comments, timestamp and previous status
- Add support for approval steps
- Add a visual workflow designer
- A desktop widget displaying pending approvals
If you decide to implement any of these, please do let me know.
With relatively little code (under 100 logical SLOC) it’s possible to turn Gravity Forms + WordPress into a sophisticated custom workflow application. Granted there are excellent dedicated solutions on the market with advanced features and visual workflow designers, so this approach is not going to be the most suitable for every situation, but if you’re aware of the possibilities it’ll help you make the right choice. Were you aware you could do this with Gravity Forms? I’m sure there are many additional use cases and adaptations for this application. If you come up with any, please let me know either in in a private message or in the comments below.
I’ll be very happy to answer any questions you have about this tutorial in the comments. Please direct all specific questions about your project to the Gravity Forms technical support team.
- The views expressed here are my own and do not necessarily reflect those of Rocketgenius.
- Gravity Forms is a trademark of Rocketgenius
- WordPress is a trademark of The WordPress Foundation