Skip to content

Instantly share code, notes, and snippets.

@RadGH
Last active February 17, 2025 02:53
Show Gist options
  • Select an option

  • Save RadGH/2e419f7b67974f969e55fa3556f652fc to your computer and use it in GitHub Desktop.

Select an option

Save RadGH/2e419f7b67974f969e55fa3556f652fc to your computer and use it in GitHub Desktop.
Edit an existing gravityforms entry on the frontend
<?php
if ( !defined( 'ABSPATH' ) ) exit;
// How to use:
// 1. Create your own class that extends this one, such as: class Amazing_Quiz extends Editable_GF_Form {...}
// 2. Set the $form_id in your class (Amazing_Quiz). *Note: This code is designed for a single form per class but could easily be adapted to support any form.
// 3. Edit an entry by visiting your form normally but with ?entry_id=123 in the URL. If your user account created the entry, you can edit it.
// Requirements:
// 1. All fields must have a unique name set for "allow to be pre-populated".
// * This is a dumb restriction by GF as without a name, there is no filter to set the value.
// * File inputs do not need a name though (they don't support one anyway).
// 2. Advanced fields or fields with more than one option may need their own hook set up in add_gravityform_editable_hooks().
// * I added an example if statement for "type = text". Replace that with other field types and build your own hook to get the value.
// 3. This is only for the front-end. I don't know why GF doesn't let you edit entries on the backend.
abstract class Editable_GF_Form {
// Form ID that will allow editing entries
public $form_id = null;
public function __construct() {
// Certain functions needed when adding hooks are loaded elsewhere in the theme. Hook at init to fix this.
add_action( 'after_setup_theme', array(
$this,
'add_gravityform_editable_hooks'
) );
}
/**
* Add hooks so that this form can be modified
*/
public function add_gravityform_editable_hooks() {
// Form id must be specified
if ( $this->form_id === null ) return;
// Allow editing previous insurance entry, if reinstatement needed and admin reinstatement tracking allows for it
add_filter( "gform_entry_id_pre_save_lead_{$this->form_id}", array($this, 'change_saved_entry_id'), 50, 2 );
// Add saved files to edited entry when the form started to be rendered
add_filter( "gform_pre_render_{$this->form_id}", array($this, 'prepare_previously_uploaded_files'), 20, 3 );
// Fill in the value of all fields that have a name. The name must match the "autofill parameter name" in the field's settings.
$form = GFAPI::get_form( $this->form_id );
foreach( $form['fields'] as $i => $field ) {
if ( !($field instanceof GF_Field) ) continue;
$name = rgobj( $field, 'inputName' ); // "evaluation_id"
$type = rgobj( $field, 'type' ); // "hidden"
$hook = false;
if ( $type == 'text' ) {
$hook = 'fill_field_value_text'; // some other condition can be used here if text doesn't work
}else{
$hook = 'fill_field_value_text';
}
if ( $hook && $name ) {
add_filter( "gform_field_value_{$name}", array($this, $hook), 20, 3 );
}
}
}
/**
* Get the entry id that is being edited
*
* @return bool|int|mixed
*/
public function get_edited_entry_id() {
$entry_id = (int) rgar( $_GET, 'entry_id' );
if ( !$entry_id ) return false;
return $entry_id;
}
/**
* Return true if the given user is able to make edits to the entry.
*
* @param int $user_id
* @param array|int $entry
*
* @return bool
*/
public function can_user_edit_entry( $user_id, $entry ) {
if ( is_numeric($entry) ) $entry = GFAPI::get_entry( $entry );
if ( !$entry || is_wp_error( $entry ) ) return false;
// Must be an entry belonging to this renewal form
if ( $entry['form_id'] != $this->form_id ) return false;
// Check if user is owner of the entry
if ( (int) $entry['created_by'] != (int) $user_id ) return false;
// Check if status of entry is no longer "active". Only active entries can be edited
if ( $entry['status'] !== 'active' ) return false;
return true;
}
/**
* Set up "uploaded_files" using values from the previous entry. Allows you to keep your previous upload, or remove it and start over.
*
* @param $form
* @param $ajax
* @param $field_values
*
* @return mixed
*/
public function prepare_previously_uploaded_files( $form, $ajax, $field_values ) {
$user_id = get_current_user_id();
// Get the edited entry
$entry_id = $this->get_edited_entry_id();
if ( !$entry_id ) return $form;
if ( !$this->can_user_edit_entry( $user_id, $entry_id ) ) return $form;
// Check if any field is a file upload. If not, we can ignore this function
do {
foreach( $form['fields'] as $field ) {
if ( $field instanceof GF_Field_FileUpload ) {
// File upload found. Abort the do{} loop and proceed with the function
break 2;
}
}
// No file uploads found
return $form;
} while(false);
// Get the entry object
$entry = GFAPI::get_entry( $entry_id );
if ( !isset( GFFormsModel::$uploaded_files[ $form['id'] ] ) ) {
GFFormsModel::$uploaded_files[ $form['id'] ] = array();
}
// Loop through each file upload and put the basename as an uploaded file
foreach( $form['fields'] as $field ) {
if ( !$field instanceof GF_Field_FileUpload ) continue;
$value = rgar( $entry, $field->id );
GFFormsModel::$uploaded_files[ $form['id'] ]["input_{$field->id}"] = basename( $value );
}
return $form;
}
/**
* Allow editing previous form entry
*
* @param $entry_id
* @param $form
*
* @return mixed
*/
public function change_saved_entry_id( $entry_id, $form ) {
if ( $entry_id !== null ) return $entry_id;
$user_id = get_current_user_id();
// Get the entry being edited
$existing_entry_id = $this->get_edited_entry_id();
if ( !$existing_entry_id ) return $entry_id;
// Use the edited entry if the user is permitted to edit it
if ( $this->can_user_edit_entry( $user_id, $existing_entry_id ) ) {
return $existing_entry_id;
}
return $entry_id;
}
/**
* Fill text fields with the value of an existing entry
*
* @param null $value
* @param GF_Field|null $field
* @param null $name
*
* @return string
*/
public function fill_field_value_text( $value = null, GF_Field $field = null, $name = null ) {
if ( $field->formId != $this->form_id ) return $value;
$existing_entry_id = $this->get_edited_entry_id();
if ( $existing_entry_id ) {
$value = gform_get_meta( $existing_entry_id, $field['id'] );
}
return $value;
}
}
@RadGH
Copy link
Copy Markdown
Author

RadGH commented Jun 25, 2020

Updated so you do not need to manually type in all the field names and IDs. Hooray!

@RadGH
Copy link
Copy Markdown
Author

RadGH commented Jul 14, 2020

Updated:

  • Added support for Checkbox fields which has one name and multiple values (array). Add others to the "$compound_field_types" array.
  • Added support for "compound" fields like the Name and Address field, with multiple sub-inputs that each have a name and value.
  • Continued support for "date" field which, although it acts like a compound field, only returns a single value.
  • Fixed hooks running every page load, which would get the form data even if the form was never used on a page.

PS: Gravity forms is ridiculously inconsistent

@RadGH
Copy link
Copy Markdown
Author

RadGH commented May 16, 2022

Updated:

  1. Major change: You no longer need to manually enable auto populate on every field. Fields are made to prepopulate automatically based on "add_form_prepopulate_names".

  2. A working example is provided, see QUICK TEST INSTRUCTIONS and import this form: https://gist.github.com/RadGH/afb032d642515aedbb068f6b5990b668

  3. Files handled better. If you do not remove or replace a file, it will now be preserved

  4. The class "GF_Form_12" is an example you should copy and customize. The class "Editable_GF_Form" you generally shouldn't need to touch.

@Antonio78
Copy link
Copy Markdown

Hi, how can I prevent confirmation emails from being sent when the form is in edit mode?
I have tried adding a remove filter, and also changing the email sending filter but to no avail..

@ashish200025
Copy link
Copy Markdown

HI RadGH

Is there way we can show the uploaded file when file is multi File upload input Field?

Thanks

@LoreGre
Copy link
Copy Markdown

LoreGre commented Nov 22, 2024

Hi,
please someone find solutions for multi files upload issue?

@LoreGre
Copy link
Copy Markdown

LoreGre commented Nov 22, 2024

I edit row 425 like this. But the filename not work. Please let me know if someone solve it. regards

`$value = rgar( $entry, $field->id );

	if( !str_contains($value, '[') ){
		GFFormsModel::$uploaded_files[ $form['id'] ]["input_{$field->id}"] = basename($value);
	} else {
		$values = json_decode($value);
		$urls = array();
		foreach($values as $url){
			$urls[] = basename($url);
		}
		GFFormsModel::$uploaded_files[ $form['id'] ]["input_{$field->id}"] = $urls;
	}`

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