Adding Meta Boxes to the Entry Detail Page Using the Add-On Framework

Introduction

In Gravity Forms 2.0 we switched to using meta boxes for the sidebar panels on the entry detail page allowing the user to decide which meta boxes are displayed and their order. This change also makes it easier for add-ons to add their own custom meta boxes to the page.

In this tutorial we will show how you can add a custom meta box to the entry detail page.

Before reading on you should be familiar with the Add-On Framework.

The Hook

Adding a custom meta box to the entry detail page can be accomplished by using the gform_entry_detail_meta_boxes filter in the init or init_admin function of your add-on.

/**
 * Plugin starting point. Handles hooks, loading of language files, and PayPal delayed payment support.
 */
public function init() {

	parent::init();

	add_filter( 'gform_entry_detail_meta_boxes', array( $this, 'register_meta_box' ), 10, 3 );

}

The Hook Callback

The following example shows the function used with the gform_entry_detail_meta_boxes filter to add the meta box to the entry detail page.

Our feed add-on integrates with a third-party service so it has an initialize_api() function used to include the API files and connect to the service to validate any API credentials. If the credentials are valid and the form has an active feed for this add-on then the meta box will be added.

/**
 * Add the meta box to the entry detail page.
 *
 * @param array $meta_boxes The properties for the meta boxes.
 * @param array $entry The entry currently being viewed/edited.
 * @param array $form The form object used to process the current entry.
 *
 * @return array
 */
public function register_meta_box( $meta_boxes, $entry, $form ) {
	// If the form has an active feed belonging to this add-on and the API can be initialized, add the meta box.
	if ( $this->get_active_feeds( $form['id'] ) && $this->initialize_api() ) {
		$meta_boxes[ $this->_slug ] = array(
			'title'    => $this->get_short_title(),
			'callback' => array( $this, 'add_details_meta_box' ),
			'context'  => 'side',
		);
	}

	return $meta_boxes;
}

It’s also possible to use the form fields to determine if the meta box should be added. In this example the Quiz Add-On is checking to see if the form uses quiz type fields.

public function register_meta_box( $meta_boxes, $entry, $form ) {
	$fields = GFAPI::get_fields_by_type( $form, array( 'quiz' ) );

	if ( ! empty( $fields ) ) {
		$meta_boxes['gf_quiz'] = array(
			'title'    => esc_html__( 'Quiz Results', 'gravityformsquiz' ),
			'callback' => array( $this, 'add_quiz_meta_box' ),
			'context'  => 'side',
		);
	}

	return $meta_boxes;
}

The Meta Box Callback

This callback function is responsible for adding the actual content to our meta box. You could include anything in the meta box but we would recommend keeping it to the essential details.

In the process_feed() example of the Including and using Entry Meta with the Add-On Framework article we showed how a feed based add-on can store entry meta when processing the feed. In this case it was the contact id returned by the third-party service.

The example below shows how the contact id can be retrieved from the entry and displayed in the meta box. If the entry being displayed doesn’t have a contact id because it wasn’t processed by the add-on during form submission the function will display a button which can be used to initiate feed processing for the current entry by our add-on. When the button is clicked the page will reload, processing the feeds, and then display the contact id.

/**
 * The callback used to echo the content to the meta box.
 *
 * @param array $args An array containing the form and entry objects.
 */
public function add_details_meta_box( $args ) {

	$form  = $args['form'];
	$entry = $args['entry'];

	$html   = '';
	$action = $this->_slug . '_process_feeds';

	// Retrieve the contact id from the current entry, if available.
	$contact_id = rgar( $entry, 'simpleaddon_contact_id' );

	if ( empty( $contact_id ) && rgpost( 'action' ) == $action ) {
		check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );

		// Because the entry doesn't already have a contact id and the 'Process Feeds' button was clicked process the feeds.
		$entry = $this->maybe_process_feed( $entry, $form );

		// Retrieve the contact id from the updated entry.
		$contact_id = rgar( $entry, 'simpleaddon_contact_id' );

		$html .= esc_html__( 'Feeds Processed.', 'simplefeedaddon' ) . '</br></br>';
	}

	if ( empty( $contact_id ) ) {

		// Add the 'Process Feeds' button.
		$html .= sprintf( '<input type="submit" value="%s" class="button" onclick="jQuery(\'#action\').val(\'%s\');" />', esc_attr__( 'Process Feeds', 'simplefeedaddon' ), $action );

	} else {

		// Display the contact ID.
		$html .= esc_html__( 'Contact ID', 'simplefeedaddon' ) . ': ' . $contact_id;

		// You could include a link to the contact profile on the third-party site.
	}

	echo $html;
}