Encountering issues with multiple image and file uploads while working with Gravity Forms and the Post Creation Add-On in WordPress can be frustrating. These challenges often arise when dealing with custom post types (CPTs) and Advanced Custom Fields (ACF), where managing uploaded files or prepopulating form fields is critical. This guide provides a step-by-step solution to dynamically populate Gravity Form fields, handle file uploads, and save or update data in ACF fields, ensuring seamless integration and functionality.
Understanding the Problem
When using Gravity Forms to create or update posts, especially with custom post types (CPTs) and Advanced Custom Fields (ACF), handling file uploads (like images and PDFs) can be tricky. The issues often arise in two scenarios:
- Populating fields: Dynamically preloading values (e.g., images) into a Gravity Form for editing.
- Saving data: Ensuring uploaded files are correctly saved or updated in the custom post type’s ACF fields.
Solution Overview
We’ll address the following:
- Dynamically prepopulate Gravity Form fields with existing data (like images and files).
- Save or update the uploaded data back into the custom post type’s ACF fields.
Populating Form Fields
To dynamically populate fields with existing post data:
Add the Code to Your Theme’s Functions.php
Use the following code to fetch and populate the fields with pre-existing data:
add_filter('gform_pre_render_9', 'populate_all_fields_on_player_data_update_form'); add_filter('gform_pre_validation_9', 'populate_all_fields_on_player_data_update_form'); add_filter('gform_pre_submission_filter_9', 'populate_all_fields_on_player_data_update_form'); add_filter('gform_admin_pre_render_9', 'populate_all_fields_on_player_data_update_form'); function populate_all_fields_on_player_data_update_form($form) { if (isset($_GET['profile_id'])) { $profile_id = intval($_GET['profile_id']); foreach ($form['fields'] as &$field) { if ($field->type === 'hidden' && $field->id == 69) { $image_id = get_post_meta($profile_id, 'profile_photo', true); if ($image_id) { $image_url = wp_get_attachment_url($image_id); if ($image_url) { $field->defaultValue = $image_url; } } } if ($field->type === 'hidden' && $field->id == 70) { $card_image_id = get_post_meta($profile_id, 'player_card_photo', true); if ($card_image_id) { $card_image_url = wp_get_attachment_url($card_image_id); if ($card_image_url) { $field->defaultValue = $card_image_url; } } } if ($field->type === 'hidden' && $field->id == 71) { $school_transcript_id = get_post_meta($profile_id, 'school_transcript', true); if ($school_transcript_id) { $file_url = wp_get_attachment_url($school_transcript_id); if ($file_url) { $field->defaultValue = $file_url; } } } } } return $form; }
Explanation
- Filters Used: These hooks ensure that the form is pre-filled when it’s rendered or validated.
- Data Mapping: The meta keys (like profile_photo, player_card_photo) are mapped to ACF fields.
- Uploading Images and Files [h2]
- To handle image uploads via Base64 and files from a URL, use the following helper functions.
- Helper Function: Upload Base64 Image
function upload_base64_image_to_media($base64_image, $post_id) { if (preg_match('/^data:image\/(\w+);base64,/', $base64_image, $matches)) { $image_data = base64_decode(preg_replace('/^data:image\/\w+;base64,/', '', $base64_image)); if (!$image_data) { error_log("Base64 decode failed."); return false; } $upload_dir = wp_upload_dir(); $file_name = 'uploaded_image_' . time() . '.' . $matches[1]; $file_path = $upload_dir['path'] . '/' . $file_name; // Save image to disk if (file_put_contents($file_path, $image_data)) { $attachment = [ 'guid' => $upload_dir['url'] . '/' . $file_name, 'post_mime_type' => 'image/' . $matches[1], 'post_title' => basename($file_name, '.' . $matches[1]), 'post_content' => '', 'post_status' => 'inherit', ]; // Insert attachment into WordPress $attachment_id = wp_insert_attachment($attachment, $file_path, $post_id); if (is_wp_error($attachment_id)) { error_log("Failed to insert attachment: " . $attachment_id->get_error_message()); return false; } require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_data = wp_generate_attachment_metadata($attachment_id, $file_path); wp_update_attachment_metadata($attachment_id, $attachment_data); return $attachment_id; } else { error_log("Failed to write file to disk: " . $file_path); } } else { error_log("Invalid Base64 format."); } return false; } function upload_file_from_url_to_media($file_url, $post_id = 0) { if (empty($file_url)) { error_log("File URL is empty."); return false; } $upload_dir = wp_upload_dir(); // Extract the file name and path from the URL $file_name = basename(parse_url($file_url, PHP_URL_PATH)); $file_path = $upload_dir['path'] . '/' . $file_name; // Download the file to the uploads directory $file_data = file_get_contents($file_url); if ($file_data === false) { error_log("Failed to fetch file from URL: $file_url"); return false; } if (!file_put_contents($file_path, $file_data)) { error_log("Failed to save file to disk: $file_path"); return false; } // Determine the MIME type $file_type = wp_check_filetype($file_name); if (empty($file_type['type'])) { error_log("Failed to determine MIME type for file: $file_name"); return false; } // Prepare the attachment metadata $attachment = [ 'guid' => $upload_dir['url'] . '/' . $file_name, 'post_mime_type' => $file_type['type'], 'post_title' => sanitize_file_name($file_name), 'post_content' => '', 'post_status' => 'inherit', ]; // Insert the attachment into WordPress $attachment_id = wp_insert_attachment($attachment, $file_path, $post_id); if (is_wp_error($attachment_id)) { error_log("Failed to insert attachment: " . $attachment_id->get_error_message()); return false; } // Generate attachment metadata and update require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_data = wp_generate_attachment_metadata($attachment_id, $file_path); wp_update_attachment_metadata($attachment_id, $attachment_data); return $attachment_id; }
Saving the Data
Now that the form fields are populated and file uploads are handled, we can save or update the data in ACF fields.
Add This Code to Save the Data
add_action('gform_after_submission_9', 'update_player_profile', 10, 2); function update_player_profile($entry, $form) { if (isset($_GET['profile_id']) && is_user_logged_in()) { $profile_id = $_GET['profile_id']; $acf_field_key_33 = 'profile_photo'; $acf_field_key_34 = 'player_card_photo'; $acf_field_key_35 = 'school_transcript'; $gform_field_id_33 = '69'; $gform_field_id_34 = '70'; $gform_field_id_35 = '71'; $gform_data_33 = rgar($entry, $gform_field_id_33); $gform_data_34 = rgar($entry, $gform_field_id_34); $gform_data_35 = rgar($entry, $gform_field_id_35); if (!empty($gform_data_33)) { $attachment_id = upload_base64_image_to_media($gform_data_33, $profile_id); if ($attachment_id) { update_field($acf_field_key_33, $attachment_id, $profile_id); set_post_thumbnail($profile_id, $attachment_id); } } if (!empty($gform_data_34)) { $attachment_id = upload_base64_image_to_media($gform_data_34, $profile_id); if ($attachment_id) { update_field($acf_field_key_34, $attachment_id, $profile_id); } } if (!empty($gform_data_35)) { $attachment_id = upload_file_from_url_to_media($gform_data_35, $profile_id); if ($attachment_id) { update_field($acf_field_key_35, $attachment_id, $profile_id); } } } }
- Testing
- Populate the Form:
- Use the profile_id in the query string to test if fields are prepopulated correctly.
- Submit and Save:
- Upload images/files in the form and verify that they are saved to the correct ACF fields.
- Debugging:
- Use error_log statements to debug issues.
By following the outlined steps, you can effectively manage multiple images and file uploads in Gravity Forms, ensuring compatibility with custom post types and ACF fields. From dynamically prepopulating form fields to saving uploaded data, these solutions enable a streamlined process for creating and updating posts. With proper implementation and testing, you’ll overcome common challenges and enhance your WordPress functionality for a more efficient workflow.