Created
August 28, 2025 14:21
-
-
Save saifsultanc/5588b827a0e7afe071d3640e2e6e9f00 to your computer and use it in GitHub Desktop.
GW_Rename_Uploaded_Files.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class GW_Rename_Uploaded_Files { | |
| public $_args; | |
| 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, | |
| 'field_id' => false, | |
| 'template' => '', | |
| 'ignore_extension' => 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' ) ); | |
| } | |
| public function init() { | |
| // make sure we're running the required minimum version of Gravity Forms | |
| if ( ! is_callable( array( 'GFFormsModel', 'get_physical_file_path' ) ) ) { | |
| return; | |
| } | |
| add_filter( 'gform_entry_post_save', array( $this, 'rename_uploaded_files' ), 9, 2 ); | |
| add_filter( 'gform_entry_post_save', array( $this, 'stash_uploaded_files' ), 99, 2 ); | |
| add_action( 'gform_after_update_entry', array( $this, 'rename_uploaded_files_after_update' ), 9, 2 ); | |
| add_action( 'gform_after_update_entry', array( $this, 'stash_uploaded_files_after_update' ), 99, 2 ); | |
| } | |
| function rename_uploaded_files( $entry, $form ) { | |
| if ( ! $this->is_applicable_form( $form ) ) { | |
| return $entry; | |
| } | |
| foreach ( $form['fields'] as &$field ) { | |
| if ( ! $this->is_applicable_field( $field ) ) { | |
| continue; | |
| } | |
| $uploaded_files = rgar( $entry, $field->id ); | |
| if ( empty( $uploaded_files ) ) { | |
| continue; | |
| } | |
| $uploaded_files = $this->parse_files( $uploaded_files, $field ); | |
| $stashed_files = $this->parse_files( gform_get_meta( $entry['id'], 'gprf_stashed_files' ), $field ); | |
| $renamed_files = array(); | |
| foreach ( $uploaded_files as $_file ) { | |
| // Don't rename the same files twice. | |
| if ( in_array( $_file, $stashed_files ) ) { | |
| $renamed_files[] = $_file; | |
| continue; | |
| } | |
| $dir = wp_upload_dir(); | |
| $dir = $this->get_upload_dir( $form['id'] ); | |
| $file = str_replace( $dir['url'], $dir['path'], $_file ); | |
| if ( ! file_exists( $file ) ) { | |
| continue; | |
| } | |
| $renamed_file = $this->rename_file( $file, $entry ); | |
| if ( ! is_dir( dirname( $renamed_file ) ) ) { | |
| wp_mkdir_p( dirname( $renamed_file ) ); | |
| } | |
| $result = rename( $file, $renamed_file ); | |
| $renamed_files[] = $this->get_url_by_path( $renamed_file, $form['id'] ); | |
| } | |
| // In cases where 3rd party add-ons offload the image to a remote location, no images can be renamed. | |
| if ( empty( $renamed_files ) ) { | |
| continue; | |
| } | |
| if ( $field->get_input_type() == 'post_image' ) { | |
| $value = str_replace( $uploaded_files[0], $renamed_files[0], rgar( $entry, $field->id ) ); | |
| } elseif ( $field->multipleFiles ) { | |
| $value = json_encode( $renamed_files ); | |
| } else { | |
| $value = $renamed_files[0]; | |
| } | |
| $entry[ $field->id ] = $value; | |
| } | |
| return $entry; | |
| } | |
| function get_upload_dir( $form_id ) { | |
| $dir = GFFormsModel::get_file_upload_path( $form_id, 'PLACEHOLDER' ); | |
| $dir['path'] = dirname( $dir['path'] ); | |
| $dir['url'] = dirname( $dir['url'] ); | |
| return $dir; | |
| } | |
| function rename_uploaded_files_after_update( $form, $entry_id ) { | |
| $entry = GFAPI::get_entry( $entry_id ); | |
| $this->rename_uploaded_files( $entry, $form ); | |
| } | |
| /** | |
| * Stash the "final" version of the files after other add-ons have had a chance to interact with them. | |
| * | |
| * @param $entry | |
| * @param $form | |
| */ | |
| function stash_uploaded_files( $entry, $form ) { | |
| foreach ( $form['fields'] as &$field ) { | |
| if ( ! $this->is_applicable_field( $field ) ) { | |
| continue; | |
| } | |
| $uploaded_files = rgar( $entry, $field->id ); | |
| $existing_stashed_files = gform_get_meta( $entry['id'], 'gprf_stashed_files' ); | |
| if ( $this->is_json( $uploaded_files ) ) { | |
| $uploaded_files = json_decode( $uploaded_files, ARRAY_A ); | |
| } | |
| if ( $this->is_json( $existing_stashed_files ) ) { | |
| $existing_stashed_files = json_decode( $existing_stashed_files, ARRAY_A ); | |
| } | |
| /* Convert single files to array of files. */ | |
| if ( ! is_array( $existing_stashed_files ) ) { | |
| $existing_stashed_files = $existing_stashed_files ? array( $existing_stashed_files ) : array(); | |
| } | |
| if ( ! is_array( $uploaded_files ) ) { | |
| $uploaded_files = $uploaded_files ? array( $uploaded_files ) : array(); | |
| } | |
| if ( ! empty( $existing_stashed_files ) ) { | |
| $uploaded_files = array_merge( $existing_stashed_files, $uploaded_files ); | |
| } | |
| gform_update_meta( $entry['id'], 'gprf_stashed_files', json_encode( $uploaded_files ) ); | |
| } | |
| return $entry; | |
| } | |
| /** | |
| * Check whether a string is JSON or not. | |
| * | |
| * @param $string string String to test. | |
| * | |
| * @return bool Whether the string is JSON. | |
| */ | |
| function is_json( $string ) { | |
| if ( method_exists( 'GFCommon', 'is_json' ) ) { | |
| return GFCommon::is_json( $string ); | |
| } | |
| // Duplicate contents of GFCommon::is_json() here to supports versions of GF older than GF 2.5. | |
| // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict | |
| if ( is_string( $string ) && in_array( substr( $string, 0, 1 ), array( '{', '[' ) ) && is_array( json_decode( $string, ARRAY_A ) ) ) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| function stash_uploaded_files_after_update( $form, $entry_id ) { | |
| $entry = GFAPI::get_entry( $entry_id ); | |
| $this->stash_uploaded_files( $entry, $form ); | |
| } | |
| function rename_file( $file, $entry ) { | |
| $new_file = $this->get_renamed_filepath( $this->_args['template'], $file, $entry ); | |
| $new_file = $this->increment_file( $new_file ); | |
| return $new_file; | |
| } | |
| function increment_file( $file ) { | |
| $file_path = GFFormsModel::get_physical_file_path( $file ); | |
| $pathinfo = pathinfo( $file_path ); | |
| $counter = 1; | |
| if ( $this->_args['ignore_extension'] ) { | |
| while ( glob( str_replace( ".{$pathinfo['extension']}", '.*', $file_path ) ) ) { | |
| $file_path = str_replace( ".{$pathinfo['extension']}", "{$counter}.{$pathinfo['extension']}", GFFormsModel::get_physical_file_path( $file ) ); | |
| $counter ++; | |
| } | |
| } else { | |
| // increment the filename if it already exists (i.e. balloons.jpg, balloons1.jpg, balloons2.jpg) | |
| while ( file_exists( $file_path ) ) { | |
| $file_path = str_replace( ".{$pathinfo['extension']}", "{$counter}.{$pathinfo['extension']}", GFFormsModel::get_physical_file_path( $file ) ); | |
| $counter ++; | |
| } | |
| } | |
| $file = str_replace( basename( $file ), basename( $file_path ), $file ); | |
| return $file; | |
| } | |
| function is_path( $filename ) { | |
| return strpos( $filename, '/' ) !== false; | |
| } | |
| function get_renamed_filepath( $template, $file, $entry ) { | |
| $info = pathinfo( $file ); | |
| // replace our custom "{filename}" psuedo-merge-tag | |
| $filename = str_replace( '{filename}', $info['filename'], $template ); | |
| // replace merge tags | |
| $form = GFAPI::get_form( $entry['form_id'] ); | |
| $filename = GFCommon::replace_variables( $filename, $form, $entry, false, true, false, 'text' ); | |
| // make sure filename is "clean". This includes removing any user inputted items such as "../", "/usr/bin" etc | |
| $filename = $this->clean( $filename ); | |
| if ( strpos( $template, '/' ) === 0 ) { | |
| $dir = wp_upload_dir(); | |
| $filepath = $dir['basedir']; | |
| } else { | |
| $filepath = $info['dirname'] . '/'; | |
| } | |
| $filepath .= $filename . '.' . $info['extension']; | |
| return $filepath; | |
| } | |
| function is_applicable_form( $form ) { | |
| $form_id = isset( $form['id'] ) ? $form['id'] : $form; | |
| return $form_id == $this->_args['form_id']; | |
| } | |
| function is_applicable_field( $field ) { | |
| $is_file_upload_field = in_array( GFFormsModel::get_input_type( $field ), array( 'fileupload', 'post_image' ) ); | |
| $is_applicable_field_id = $this->_args['field_id'] ? $field['id'] == $this->_args['field_id'] : true; | |
| return $is_file_upload_field && $is_applicable_field_id; | |
| } | |
| function clean( $str ) { | |
| return sanitize_file_name( $str ); | |
| } | |
| function get_url_by_path( $file, $form_id ) { | |
| $dir = $this->get_upload_dir( $form_id ); | |
| $url = str_replace( $dir['path'], $dir['url'], $file ); | |
| return $url; | |
| } | |
| function parse_files( $files, $field ) { | |
| if ( empty( $files ) ) { | |
| return array(); | |
| } | |
| if ( $this->is_json( $files ) ) { | |
| $files = json_decode( $files ); | |
| } elseif ( $field->get_input_type() === 'post_image' ) { | |
| $file_bits = explode( '|:|', $files ); | |
| $files = array( $file_bits[0] ); | |
| } else { | |
| $files = array( $files ); | |
| } | |
| return $files; | |
| } | |
| } | |
| # Configuration | |
| new GW_Rename_Uploaded_Files( array( | |
| 'form_id' => 68, | |
| 'field_id' => 3, | |
| // most merge tags are supported, original file extension is preserved | |
| 'template' => '{:2}-1', | |
| // Ignore extension when renaming files and keep them in sequence (e.g. a.jpg, a1.png, a2.pdf etc.) | |
| 'ignore_extension' => false, | |
| ) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment