Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spivurno/c48bcf30eb70093c99fd26fe41945795 to your computer and use it in GitHub Desktop.
Save spivurno/c48bcf30eb70093c99fd26fe41945795 to your computer and use it in GitHub Desktop.
Gravity Wiz // Gravity Forms // Automatic Save & Continue
<?php
/**
* Gravity Wiz // Gravity Forms // Automatic Save & Continue
*
* Automatically save
* load previously saved data (via Gravity Forms' Save & Continue functionality) when a logged-in user views a form.
*
* @version 0.4
* @author David Smith <david@gravitywiz.com>
* @license GPL-2.0+
* @link http://gravitywiz.com/...
*
* Plugin Name: Save & Continue Auto Load for Gravity Forms
* Plugin URI: http://gravitywiz.com/...
* Description: Automatically load previously saved data (via Gravity Forms' Save & Continue functionality) when a logged-in user views a form.
* Author: Gravity Wiz
* Version: 0.4
* Author URI: http://gravitywiz.com
*/
class GW_Save_Continue_Auto_Load {
public function __construct( $args = array() ) {
// set our default arguments, parse against the provided arguments, and store for use throughout the class
$this->_args = wp_parse_args( $args, array(
'form_ids' => array(),
'enable_inline_confirmation' => false,
'auto_save' => true,
) );
// do version check in the init to make sure if GF is going to be loaded, it is already loaded
add_action( 'init', array( $this, 'init' ) );
}
public function init() {
// load token on load
add_action( 'gform_form_args', array( $this, 'maybe_resume' ) );
// save token on submission - or - delete token on successful submission
add_action( 'gform_post_process', array( $this, 'handle_token_storage' ), 10, 2 );
// display inline confirmation
add_filter( 'gform_form_args', array( $this, 'maybe_display_inline_confirmation' ), 10, 2 );
}
public function maybe_resume( $args ) {
$is_submitting = rgpost( "is_submit_{$args['form_id']}" );
if( ! $this->is_applicable_form( $args['form_id'] ) || ! is_user_logged_in() || $is_submitting ) {
return $args;
}
$token = $this->get_resume_token( get_current_user_id(), $args['form_id'] );
if( empty( $token ) ) {
return $args;
}
// A bit of a hack... but it makes things much cleaner/easier to just let GF handle loading the data.
$_GET['gf_token'] = $token;
return $args;
}
public function handle_token_storage( $form, $page_number ) {
if( ! is_user_logged_in() ) {
return;
}
$submission = GFFormDisplay::$submission[ $form['id'] ];
$is_successful_submission = $page_number == 0 && $submission['is_valid'];
if( $is_successful_submission ) {
$this->delete_resume_token( get_current_user_id(), $form['id'] );
} else if( rgar( $submission, 'saved_for_later' ) ) {
$this->save_resume_token( get_current_user_id(), $form['id'], $submission['resume_token'] );
} else if( $this->_args['auto_save'] ) {
$resume_token = $this->auto_save( $form, $page_number );
$this->save_resume_token( get_current_user_id(), $form['id'], $resume_token );
}
}
public function auto_save( $form, $page_number ) {
$entry = GFFormsModel::get_current_lead();
$form_unique_id = GFFormsModel::get_form_unique_id( $form['id'] );
$ip = rgars( $form, 'personalData/preventIP' ) ? '' : GFFormsModel::get_ip();
$source_url = GFFormsModel::get_current_page_url();
$source_url = esc_url_raw( $source_url );
$resume_token = GFFormsModel::save_draft_submission( $form, $entry, rgpost( 'gform_field_values' ), $page_number, rgar( GFFormsModel::$uploaded_files, $form['id'] ), $form_unique_id, $ip, $source_url, sanitize_key( rgpost( 'gform_resume_token' ) ) );
return $resume_token;
}
public function save_resume_token( $user_id, $form_id, $token ) {
return update_user_meta( $user_id, sprintf( '_gform-resume-token-%d', $form_id ), $token );
}
public function get_resume_token( $user_id, $form_id ) {
return get_user_meta( $user_id, sprintf( '_gform-resume-token-%d', $form_id ), true );
}
public function delete_resume_token( $user_id, $form_id ) {
return delete_user_meta( $user_id, sprintf( '_gform-resume-token-%d', $form_id ) );
}
public function maybe_display_inline_confirmation( $args ) {
if( $this->_args['enable_inline_confirmation'] && rgars( GFFormDisplay::$submission, "{$args['form_id']}/saved_for_later" ) ) {
unset( GFFormDisplay::$submission[ $args['form_id'] ] );
add_filter( 'gform_get_form_filter_' . $args['form_id'], array( $this, 'prepend_inline_confirmation' ), 10, 2 );
}
return $args;
}
public function prepend_inline_confirmation( $markup, $form ) {
return $this->get_confirmation_message( $form ) . $markup;
}
public function get_confirmation_message( $form ) {
$confirmation = wp_filter_object_list( $form['confirmations'], array( 'event' => 'form_saved' ) );
$confirmation = reset( $confirmation );
$resume_token = $this->get_resume_token( get_current_user_id(), $form['id'] );
$message = GFCommon::maybe_sanitize_confirmation_message( $confirmation['message'] );
$message = GFFormDisplay::replace_save_variables( $message, $form, $resume_token, null );
$message = GFCommon::gform_do_shortcode( $message );
$message = sprintf( "<div class='gf_browser_chrome gform_wrapper'><div class='form_saved_message'><span>%s</span></div></div>", $message );
return $message;
}
public function is_applicable_form( $form ) {
$form_id = isset( $form['id'] ) ? $form['id'] : $form;
return empty( $this->_args['form_ids'] ) || in_array( $form_id, $this->_args['form_ids'] );
}
}
# Configuration
new GW_Save_Continue_Auto_Load();
@pandglobal
Copy link

Is there a way to generate new Auth token each time a save and continue button is clicked, because I work with a multi page form and when a user clicks the save and continue a token is generated or a link with token is generated, but that one token is used to complete the entire form even if the user click on save and continue many times and in different page section of the form.
But what i want is one brand new token or link url generated every time the save and continue is clicked, not one generated token for any entry.

@spivurno
Copy link
Author

@tfeige91
Copy link

tfeige91 commented Apr 20, 2021

Hi,
first of all thanks for the great snipped!
I found one issue that occurs when there are more than one form on a page. I build three forms into a tab-navigation.
When you fill in the form (different ID) on tab two the one you already filled in on tab1 is "erased". I tried by adding anchors to the tabs to manipulate the URL by adding #tab1 or #tab2 but this didn't work.
Do you have an Idea on how to solve this?

Thanks in advance and kind regards :)
Tim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment