-
-
Save RadGH/2e419f7b67974f969e55fa3556f652fc to your computer and use it in GitHub Desktop.
| <?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 ) { | |
| 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; | |
| } | |
| } |
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
Updated:
-
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".
-
A working example is provided, see QUICK TEST INSTRUCTIONS and import this form: https://gist.github.com/RadGH/afb032d642515aedbb068f6b5990b668
-
Files handled better. If you do not remove or replace a file, it will now be preserved
-
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.
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..
HI RadGH
Is there way we can show the uploaded file when file is multi File upload input Field?
Thanks
Hi,
please someone find solutions for multi files upload issue?
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;
}`
Updated so you do not need to manually type in all the field names and IDs. Hooray!