UPDATE 9 July 2015:
If you’re looking for a comprehension workflow solution to automate business processes on WordPress check out my new plugin Gravity Flow
Note: This post is written for developers with some knowledge of Gravity Forms.
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:
Requirements
- 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
GFFeedAddOn extends the Add-On Framework so we get everything that comes with GFAddOn except in place of the Form Settings UI we get the Feeds UI.
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
The complete add-on is available in the Github repository for Gravity Forms Approvals.
View the complete listing: approvals.php
Download the latest version of the add-on from the WordPress.org plugins repository: Gravity Forms Approvals Add-On
Configuration
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.
Vacation Request
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:
Incoming invoices
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.
Next Steps
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.
Conclusion
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.
********
Legal bits:
- 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
This is awesome! Thank you
Hi Steven,
This tutorial was extremely helpful to get my org’s change request workflow working with Gravity Forms. I downloaded and installed your plugin, created the feed and was able to successfully approve & reject form entries with notifications for each. However, it stopped working after one day. The only change I made was to the user who is selected to approve the feed. Thoughts? Any help is much appreciated.
Thanks,
Furqan
The changes will affect only new submissions. I’ve sent you a mail.
Same thing happened to me. It seems that the Approver has to be an administrator for the site. Is that accurate? Thanks! Very helpful plugin.
How can I change the settings so the Approver can be a role other than Administrator? I’d like to make the Editor role an Approver also. Which capabilities would I have to add to the Editor role? Thanks in advance!
Anyone figure this out?
The approver only needs permissions to edit the entires. Admin role is not necessary.
Hi Steven,
Could you please tell me a way to show up approval status on a page template? So that a logged in user can see their entries are approved or not?
How can I show the approval status on a page template (front end) ?
Please respond if you can.. thanks in advance.
Hi Subin, you can use the gform_get_meta() function.
This is exactly what I have been looking for! SO helpful. It took me awhile to figure out exactly how to install it as a plugin (this is all very new to me) but once I realized all I needed to do was upload the .php file into the Plugins WP folder it was a breeze.
I did have a couple questions – first is: how would you go about adding a date stamp to the approvals? We would like to track how responsive different people are.
Second, we would like to mark the overall status as complete (approved) or closed like you have here, but we are not using any third party software (like zapier) – we just would like an “Overall Status” that is either pending or closed. However we would also like to still be able to go in and edit entries if needed. Any advice? I figure I could just mess around with the final bits of code and see if I can make it work but I don’t want to break anything vital.
Thanks again for this great tutorial!
OK, I actually figured out the second question (there was a line of code I could just remove to bring back the edit button). My next question is related:
Would it be possible to add an approver after the entry has been created?
Here is my situation, someone fills out a form on the front-end of the site (a complaint form). This form has conditional logic that if a certain department is selected, a notification is sent to that department head and using your addon, they’re are marked as the approver (in some cases multiple departments would be selected). As the complaint is reviewed, one department may realize that a different department should be notified. I would like that person to be able to either go in and edit the entry to select the new department and have that new dept show up in the approvers, OR have a list that says “Add an Approver” that the person can select. Ideally that new person would also be emailed a notification as well. I know its a lot to ask, but any help is much appreciated!
Thanks again!
Hi Jaclyn, thanks for the feedback I really appreciate it. I’m pleased you got the first issue sorted. Yes, you can change the approvers by using hooking in to the gform_after_update_entry action. This is a feature of the Workflow Add-On I’m working on. If you’d like early access to the beta when it’s ready, please sign up at the top of this post.
Yes, I definitely signed up for the Beta 🙂
Any idea on the timeline for that?
Not sure if my last comment went through, but yes, I am definitely interested in the Beta and signed up. Any idea on a time line?
Also, I never did figure out how to add a datestamp, any quick fixes for that?
Gravity Workflow will have a log of comments and approval timestamps in the entry notes. An alpha version is nearly ready so I’ll be in touch very soon!
Is there a way to get this to send the form’s submitter a different message if the form is approved or rejected? It appears I can create a notification with the event “Form is approved or rejected”, but I don’t see how I can send a different message for each outcome… Thanks.
Never mind! I found it… Thanks.
David, or someone, I’m looking to separate notifications for when a application is approved and another for when its rejected as well and can’t figure it out. Can someone point me in the right direction?
Thanks.
Wait… found it. Can be set when editing a notification. At the bottom of the page you can set conditional logic and specify whether the notification should be sent when something is approved or rejected.
This is exactly what I was looking for. Great work Steven.
Can’t wait for the plugin.
Hi Steven,
I was wondering if there was any progress on the plugin. I’m using your code to make a scientific experiment submission/review/approval system with Gravity Forms and I could really use time stamps and comments and such.
Any chance that an approval could update one of the form fields?
Thanks!
Yes, lots of progress! I’ve sent you a mail.
Can give me some idea how to create unique id using address field in gravity forms?
Hello,
I am testing your approvals plugin on a multisite, the approval metabox is not showing up, getting this error..
WordPress database error Table ‘intrasbg_intranet.wp_5_rg_lead_meta’ doesn’t exist for query SELECT meta_value FROM wp_5_rg_lead_meta WHERE lead_id=18 AND meta_key=’processed_feeds’ made by require(‘wp-blog-header.php’), wp, WP->main, do_action_ref_array, call_user_func_array, GFForms::maybe_process_form, GFFormDisplay::process_form, GFFormDisplay::handle_submission, apply_filters(‘gform_entry_post_save’), call_user_func_array, GFFeedAddOn->maybe_process_feed, gform_get_meta
Any help is appreciated. Thx
Hi Subin, I’ve tested the code on multisite and it’s working fine. It looks like your Gravity Forms tables don’t exist for site 5. If the problem persists I suggest getting in touch with support.
You are correct!
I fixed it by creating a new table “wp_5_rg_lead_meta”
Thanks for your help!
I am trying to create a support ticket system using gravity forms and your approvals addon, is there any way to send notification email upon adding “Notes” within the entries ? http://prntscr.com/75fnaq
You could use the gform_post_note_added action to fire a notification: e.g.
add_action( ‘gform_post_note_added’, ‘my_post_note_added_func’, 10, 6);
function my_post_note_added_func( $note_id, $lead_id, $user_id, $user_name, $note, $note_type ) {
// perform action after the note has been added
}
Thanks for that,
I added the following as the action after the note has been added.
$notifications_to_send = GFCommon::get_notifications_to_send( ‘gform_post_note_added’, $form, $entry);
foreach ( $notifications_to_send as $notification ) {
GFCommon::send_notification( $notification, $form, $entry );
}
but not getting email notification 🙁
Check out GFAPI::send_notifications($form, $entry, $event)
Hi there,
Can u tell me how can i exclude specific form (ID) from being approved? like registration user form i need to turn off approving for this form but i don’t know how.
Hi a want to change approved, pending, rejected names on entries list but nothing happening when i am doing that. How to change this in proper way?
Hi Steven,
I integrated your plugin with Gravity View as it allows me to easily put a frontend to your dev effort. Question: I want to put the approve and disapprove buttons on the frontend also when someone is viewing an entry. Do you have any clue on how to do this?
-q
I sent you an email.
Hi Steven,
Mine is a case similar to Quincy’s. I, too, am using Gravity view to display entries on the frontend, and would want to add approve/reject capability on the frontend. Would really appreciate if you could help me achieve this.
Many Thanks.
I suggested he use the approval field in GravityView.
Hi Steven,
Mine is a case similar to Quincy’s. I, too, am using Gravity View to display entries on the frontend, and would want to approve/reject option from the frontend. Would really appreciate any help from your end to achieve this.
Many thanks.
Hi,
Thanks for the quick revert. However, the approval field i.e. approval status field only shows the status in the frontend. Is it also possible to approve the entry from the frontend while viewing it in a gravity view.
Many thanks.
I’m not that familiar with GravityView I’m afraid. If you have trouble getting it to work you might want to check out my workflow add-on for Gravity Forms: Gravity Flow
I had this working and now after updating WordPress, it is requiring approval from EVERY approver. To be more specific, I have 5 people set as approvers, and each one has a unique condition enabled to require approval from that person. Each entry should only have 1 approver based on the condition selected, but is now is requiring approval from all 5 people. It has even changed previous entries. Is it a ‘just me’ problem?
Hi Steven,
first of all – great work!
i have one question – i use gf for my booking system and now i need when someone do a entry direct from email approve, it is possible?
i had try with: http://localhos/wp-admin/admin.php?page=gf_entries&view=entry&id=3&lid=9&approval_status=approved
but without success…
can you help me here?
tnx.
regards,
Sandin
This is amazing 🙂
I just wanna ask one thing…
Is that possible to change that “If one person approves, the status changes to approved”
🙂
Hi, is there a way if we mistakenly approve someone to edit that?