spivurno
11/26/2014 - 3:34 AM

Gravity Wiz // Gravity Forms // Edit Entries on Frontend

Gravity Wiz // Gravity Forms // Edit Entries on Frontend — https://gravitywiz.com/edit-gravity-forms-entries-on-the-front-end/

<?php
/**
 * --------------------------------------------------------------------
 * STOP! There's a better way to do this now:
 * https://gravitywiz.com/edit-gravity-forms-entries-on-the-front-end/
 * --------------------------------------------------------------------
 * 
 * Gravity Wiz // Gravity Forms // Edit Entries
 *
 * Automatically populate a form with data based on an entry ID and update that entry on submission.
 *
 * @version	  1.0
 * @author    David Smith <david@gravitywiz.com>
 * @license   GPL-2.0+
 * @link      http://gravitywiz.com/...
 */
class GW_Edit_Entries {

	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_id'               => false
		) );

		// 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' ) );

	}

	function init() {

		// make sure we're running the required minimum version of Gravity Forms
		if( ! property_exists( 'GFCommon', 'version' ) || ! version_compare( GFCommon::$version, '1.8', '>=' ) ) {
			return;
		}

		// time for hooks
		add_filter( 'gform_form_args', array( $this, 'populate_form' ) );
		add_filter( 'gform_pre_render', array( $this, 'prepare_form' ) );
		add_filter( 'gform_form_tag', array( $this, 'add_eid_input' ), 10, 2 );

		add_filter( 'gform_entry_id_pre_save_lead', array( $this, 'set_populated_entry_id' ) );
		add_action( 'gform_pre_submission', array( $this, 'handle_existing_images_submission' ) );

		add_action( 'gform_entry_detail_sidebar_middle', array( $this, 'edit_entry_meta_box' ), 10, 2 );

	}

	function populate_form( $form_args ) {

		// only populate if form has not been submitted
		if( rgpost( 'gform_submit' ) ) {
			return $form_args;
		}

		$entry_id = $this->get_population_entry_id();
		if( ! $entry_id ) {
			return $form_args;
		}

		$entry = GFAPI::get_entry( $entry_id );
		if( is_wp_error( $entry ) || ! $this->is_applicable_form( $form_args['form_id'] ) || $entry['form_id'] != $this->_args['form_id'] ) {
			return $form_args;
		}

		$form = GFAPI::get_form( $entry['form_id'] );

		foreach( $entry as $input_id => $value ) {

			$field_id   = intval( $input_id );
			$field      = GFFormsModel::get_field( $form, $field_id );
			$input_type = GFFormsModel::get_input_type( $field );

			switch( $input_type ) {
				case 'checkbox':
					if( ! isset( $entry[ $field['id'] ] ) ) {

						$values = $this->get_field_values_from_entry( $field, $entry );

						if( is_array( $values ) ) {
							$value = implode( ',', array_filter( $values ) );
						} else {
							$value = $values;
						}

						$entry[ $field['id'] ] = $value;

					}
					break;
				case 'list':

					$value = maybe_unserialize( $value );

					if( is_array( $value ) ) {

						foreach( $value as &$values ) {
							if( ! is_array( $values ) ) {
								$values = array( $values );
							}
							$values = implode( '|', $values );
						}

						$value = implode( ',', $value );
						$entry[ $field['id'] ] = $value;

					}

					break;
				case 'fileupload':

					$path_info = pathinfo( $value );

					// check if file has been "deleted" via form UI
					$upload_files = json_decode( rgpost( 'gform_uploaded_files' ), ARRAY_A );
					$input_name = "input_{$field['id']}";
					if( is_array( $upload_files ) && array_key_exists( $input_name, $upload_files ) && !$upload_files[$input_name] ) {
						continue;
					}

					// if $uploaded_files array is not set for this form at all, init as array
					if( ! isset( GFFormsModel::$uploaded_files[$form['id']] ) ) {
						GFFormsModel::$uploaded_files[$form['id']] = array();
					}

					// check if this field's key has been set in the $uploaded_files array, if not add this file (otherwise, a new image may have been uploaded so don't overwrite)
					if( !isset( GFFormsModel::$uploaded_files[$form['id']]["input_{$field['id']}"] ) ) {
						GFFormsModel::$uploaded_files[$form['id']]["input_{$field['id']}"] = $path_info['basename'];
					}

					break;
				default:
					break;
			}

		}

		$form_args['field_values'] = $entry;

		return $form_args;
	}

	function prepare_form( $form ) {

		if ( ! $this->is_applicable_form( $form['id'] )) {
			return $form;
		}

		foreach( $form['fields'] as $field ) {

			$field['allowsPrepopulate'] = true;
			$field['inputName'] = $field['id'];

			if( isset( $field['inputs'] ) && is_array( $field['inputs'] ) ) {
				$inputs = $field['inputs'];
				foreach( $inputs as &$input ) {
					$input['name'] = (string) $input['id'];
				}
				$field['inputs'] = $inputs;
			}

		}

		return $form;
	}

	function get_field_values_from_entry( $field, $entry ) {

		$values = array();

		foreach( $entry as $input_id => $value ) {
			$fid = intval( $input_id );
			if( $fid == $field['id'] ) {
				$values[] = $value;
			}
		}

		return count( $values ) <= 1 ? $values[0] : $values;
	}

	function is_applicable_form( $form ) {

		$form_id = isset( $form['id'] ) ? $form['id'] : $form;

		return $form_id == $this->_args['form_id'];
	}

	function get_population_entry_id() {

		$entry_id           = false;
		$is_form_submission = rgpost( 'gform_submit' ) == true;
		$has_eid_query_arg  = rgget( 'eid' ) == true;

		if( $is_form_submission ) {
			$entry_id = rgpost( 'gwee_populated_eid' );
		} else if( $has_eid_query_arg ) {
			$entry_id = GFCommon::decrypt( rgget( 'eid' ) );
		}

		return $entry_id;
	}

	function add_eid_input( $form_tag, $form ) {

		$entry_id = $this->get_population_entry_id();

		if( ! $this->is_applicable_form( $form ) || ! $entry_id ) {
			return $form_tag;
		}

		$input = sprintf( '<input type="hidden" name="gwee_populated_eid" value="%s" />', $entry_id );

		return $form_tag . $input;
	}

	function set_populated_entry_id( $entry_id ) {

		$populated_entry_id = $this->get_population_entry_id();

		if( $populated_entry_id ) {
			gform_update_meta( $populated_entry_id, 'gwee_entry_last_modified', time() );
			$entry_id = $populated_entry_id;
		}

		return $populated_entry_id ? $populated_entry_id : $entry_id;
	}

	function edit_entry_meta_box( $form, $entry ) {

		if( ! $this->is_applicable_form( $form ) ) {
			return;
		}

		$last_updated = gform_get_meta( $entry['id'], 'gwee_entry_last_modified' ) - ( 60 * 60 * 24 );

		?>

		<!-- start GW Edit Entries: Population URL Meta Box -->
		<div class="postbox" id="">

			<h3 style="cursor:default;"><span><?php _e( 'Edit Entry URL' ); ?></span></h3>

			<div class="inside">

				<div>
					<input type="text" value="<?php echo add_query_arg( array( 'eid' => rawurlencode( GFCommon::encrypt( $entry['id'] ) ) ), rgar( $entry, 'source_url' ) ); ?>" style="width:100%;" onfocus="this.select();">
				</div>

				<?php if( $last_updated ): ?>
				<div style="margin-top:10px;overflow:hidden;">
					<span style="float:left;color:#999;"><?php printf( __( 'Last Updated' ) ); ?></span>
					<span style="float:right;"><?php echo GFCommon::format_date( date( 'Y-m-d H:i:s', $last_updated ), true, 'M j, Y' ); ?></span>
				</div>
				<?php endif; ?>

			</div>

		</div>
		<!-- / end GW Edit Entries: Population URL Meta Box -->

	<?php
	}

	function handle_existing_images_submission( $form ) {
		global $_gf_uploaded_files;

		// get all fileupload fields
		// loop through and see if the image has been:
		//  - resubmitted           populate the existing image data into the $_gf_uploaded_files
		//  - deleted               do nothing
		//  - new image submitted   do nothing

		$entry_id = $this->get_population_entry_id();
		if( ! $this->is_applicable_form( $form ) || ! $entry_id ) {
			return $form;
		}

		$entry = GFAPI::get_entry( $entry_id );
		if( is_wp_error( $entry ) ) {
			return $form;
		}

		if( empty( $_gf_uploaded_files ) ) {
			$_gf_uploaded_files = array();
		}

		foreach( $entry as $input_id => $value ) {

			$field = GFFormsModel::get_field( $form, $input_id );
			$input_name = "input_{$field['id']}";

			if( GFFormsModel::get_input_type( $field ) != 'fileupload' ) {
				continue;
			}

			if( self::is_prepopulated_file_upload( $form['id'], $input_name ) ) {
				$_gf_uploaded_files[ $input_name ] = $value;
			}

		}

	}

	function is_new_file_upload( $form_id, $input_name ) {

		$file_info     = GFFormsModel::get_temp_filename( $form_id, $input_name );
		$temp_filepath = GFFormsModel::get_upload_path( $form_id ) . "/tmp/" . $file_info["temp_filename"];

		// check if file has already been uploaded by previous step
		if( $file_info && file_exists( $temp_filepath ) ) {
			return true;
		}
		// check if file is uplaoded on current step
		else if ( ! empty( $_FILES[ $input_name ][ 'name' ] ) ) {
			return true;
		}

		return false;
	}

	function is_prepopulated_file_upload( $form_id, $input_name ) {

		// prepopulated files will be stored in the 'gform_uploaded_files' field
		$uploaded_files = json_decode( rgpost( 'gform_uploaded_files' ), ARRAY_A );

		// file is prepopulated if it is present in the 'gform_uploaded_files' field AND is not a new file upload
		$in_uploaded_files = is_array( $uploaded_files ) && array_key_exists( $input_name, $uploaded_files ) && ! empty( $uploaded_files[ $input_name ] );
		$is_prepopulated   = $in_uploaded_files && ! $this->is_new_file_upload( $form_id, $input_name );

		return $is_prepopulated;
	}

}

# Configuration

new GW_Edit_Entries( array(
	'form_id' => 677
) );