Skip to content

Instantly share code, notes, and snippets.

@mathetos
Last active February 24, 2026 08:41
Show Gist options
  • Select an option

  • Save mathetos/c1393e75ff4ba303e76fc077614f8eae to your computer and use it in GitHub Desktop.

Select an option

Save mathetos/c1393e75ff4ba303e76fc077614f8eae to your computer and use it in GitHub Desktop.
Add Gravity Forms File upload to Media Library
<?php
/**
* Gravity Forms: Register File Upload field files in the WP Media Library.
*
* - Works with standard GF File Upload fields (type: fileupload)
* - Supports single + multi-file uploads
* - Registers the existing uploaded file as an attachment (does not re-download or move it)
*/
add_action( 'gform_after_submission', 'gf_register_uploads_in_media_library', 10, 2 );
function gf_register_uploads_in_media_library( $entry, $form ) {
// Optional: limit to a specific form ID.
// if ( (int) rgar( $form, 'id' ) !== 3 ) { return; }
$uploads = wp_upload_dir();
foreach ( rgar( $form, 'fields', [] ) as $field ) {
if ( rgar( $field, 'type' ) !== 'fileupload' ) {
continue;
}
$field_id = (string) rgar( $field, 'id' );
$value = rgar( $entry, $field_id );
if ( empty( $value ) ) {
continue;
}
$urls = gf_normalize_fileupload_value_to_urls( $value );
foreach ( $urls as $file_url ) {
$file_url = esc_url_raw( trim( (string) $file_url ) );
if ( empty( $file_url ) ) {
continue;
}
// Skip if already registered in the Media Library.
if ( attachment_url_to_postid( $file_url ) ) {
continue;
}
$file_path = gf_upload_url_to_path( $file_url, $uploads );
if ( ! $file_path || ! file_exists( $file_path ) || ! is_readable( $file_path ) ) {
continue;
}
gf_insert_attachment_for_existing_file( $file_path, $file_url, 0 );
}
}
}
function gf_normalize_fileupload_value_to_urls( $value ) {
$value = trim( (string) $value );
if ( $value === '' ) {
return [];
}
// Multi-file upload is stored as JSON array.
if ( function_exists( 'str_starts_with' ) && str_starts_with( $value, '[' ) ) {
$decoded = json_decode( $value, true );
if ( is_array( $decoded ) ) {
return array_values( array_filter( $decoded ) );
}
} elseif ( substr( $value, 0, 1 ) === '[' ) {
$decoded = json_decode( $value, true );
if ( is_array( $decoded ) ) {
return array_values( array_filter( $decoded ) );
}
}
return [ $value ];
}
/**
* Convert an uploads URL to a local filesystem path, safely.
* This does not care about GF’s hashed folder names; it just maps within wp_upload_dir().
*/
function gf_upload_url_to_path( $file_url, $uploads ) {
$parsed = wp_parse_url( $file_url );
if ( empty( $parsed['path'] ) ) {
return '';
}
$baseurl = wp_parse_url( $uploads['baseurl'] );
$basepath = $baseurl['path'] ?? '';
// Ensure the URL points inside the uploads base URL path.
// Example: /wp-content/uploads/...
if ( $basepath && strpos( $parsed['path'], $basepath ) !== 0 ) {
return '';
}
$relative = ltrim( substr( $parsed['path'], strlen( $basepath ) ), '/' );
if ( $relative === '' ) {
return '';
}
$path = trailingslashit( $uploads['basedir'] ) . $relative;
return wp_normalize_path( $path );
}
function gf_insert_attachment_for_existing_file( $file_path, $file_url, $parent_post_id = 0 ) {
$filename = wp_basename( $file_path );
$filetype = wp_check_filetype( $filename, null );
$attachment = [
'guid' => $file_url,
'post_mime_type' => $filetype['type'] ?? '',
'post_title' => preg_replace( '/\.[^.]+$/', '', $filename ),
'post_content' => '',
'post_status' => 'inherit',
];
$attachment_id = wp_insert_attachment( $attachment, $file_path, (int) $parent_post_id );
if ( is_wp_error( $attachment_id ) || ! $attachment_id ) {
return 0;
}
// Needed on the frontend to generate image sizes/metadata.
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once ABSPATH . 'wp-admin/includes/image.php';
}
$meta = wp_generate_attachment_metadata( $attachment_id, $file_path );
if ( is_array( $meta ) ) {
wp_update_attachment_metadata( $attachment_id, $meta );
}
return (int) $attachment_id;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment