John Davidson

javascript - Access multiple files from multiple file inputs using $_FILES after using FormData (And add to ACF data on WP Backend)

0 comments
Message:


Using Wordpress, I'm attempting to access files from one out of two file inputs using $_FILES but running into some problems:


To outline - I'm using a front-end form that has two file fields, both of which accept multiple files:


<form id="form" action="" method="post">
<input type="text" name="my_name">
<input type="file" name="reference_images[]" multiple>
<input type="file" name="photo_of_area[]" multiple>
</form>

The file inputs will be taking images, and I need to upload images from "reference_images" to one repeater field, ad "photo_of_area" to another repeater field. This form is posted via AJAX using FormData - the functions for this are below:


function saveForm(varform) {
blockUI();
jQuery.ajax({
type: "POST",
url: window.ajaxObject.ajaxUrl,
dataType: "JSON",
data: varform,
processData: false,
contentType: false,
cache: false,
success: onSuccesPing(),
crossDomain:true,
});
}

jQuery('#form').submit(function(event) {
event.preventDefault(); // Prevent form submitting as normal
var formData = new FormData(jQuery('#form')[0]);
formData.append("action", "messaging_post");
saveForm(formData);
});

I then have a function handle the messaging_post action which is below, this creates a new post with the form data, and loops over the attached images and injects them to my ACF repeater:


add_action( 'wp_ajax_messaging_post', 'messaging_post' );
add_action('wp_ajax_nopriv_messaging_post', 'messaging_post');
function messaging_post(){
if(isset($_POST['my_name'])) {
$name = sanitize_text_field($_POST['my_name']);
$new_post = array(
'ID' => '',
'post_type' => 'quote_requests',
'post_status' => 'publish',
'post_title' => $title,
'post_content' => '',
);

$post_id = wp_insert_post($new_post);
$post = get_post($post_id);

update_field('name', $name, $post_id); // Updates the ACF text field 'name' for the inserted post


// Works, but uploads files from BOTH file inputs to the single ACF repeater:
foreach($_FILES as $value){
for ($i=0; $i <count($value['name']); $i++) {
$errors= array();
$file_name = $value['name'][$i];
$file_size = $value['size'][$i];
$file_tmp = $value['tmp_name'][$i];
$file_type = $value['type'][$i];
$file_ext=strtolower(end(explode('.',$value['name'][$i])));

if(empty($errors)==true) {
$wordpress_upload_dir = wp_upload_dir();
$profilepicture = $wordpress_upload_dir['path'].'/';
move_uploaded_file($file_tmp, $profilepicture.$file_name);
} else{
print_r($errors);
}
$file_name_and_location = $profilepicture.$file_name;
$file_title_for_media_library = $value['name'][$i];
$fildename = $value['name'][$i];
$arr_file_type = wp_check_filetype(basename($fildename));
$uploaded_file_type = $arr_file_type['type'];
$attachment = array(
'post_mime_type' => $uploaded_file_type,
'post_title' => addslashes($file_title_for_media_library),
'post_content' => $fildename,
'post_status' => 'inherit',
'post_parent' => 0,
'post_author' => get_current_user_id(),
);
wp_read_image_metadata( $file_name_and_location );
$attach_id = wp_insert_attachment( $attachment, $file_name_and_location,true,false);
$attach_data = wp_generate_attachment_metadata($attach_id,$file_name_and_location );
wp_update_attachment_metadata( $attach_id, $attach_data );
$images[]= array("image" => $attach_id);
}
}
update_field('photo_area', $images, $post_id);
}
}

The above works, and populates the created post with the name from the form, but this attaches files from BOTH the reference_images and photo_of_area to the photo_area ACF repeater.


When trying to access $_FILES using a function such as the following:


foreach($_FILES["photo_of_area"] as $value){
for ($i=0; $i <count($value['name']); $i++) {
$errors= array();
$file_name = $value['name'][$i];
$file_size = $value['size'][$i];
$file_tmp = $value['tmp_name'][$i];
$file_type = $value['type'][$i];
$file_ext=strtolower(end(explode('.',$value['name'][$i])));

if(empty($errors)==true) {
$wordpress_upload_dir = wp_upload_dir();
$profilepicture = $wordpress_upload_dir['path'].'/';
move_uploaded_file($file_tmp, $profilepicture.$file_name);
} else{
print_r($errors);
}
$file_name_and_location = $profilepicture.$file_name;
$file_title_for_media_library = $value['name'][$i];
$fildename = $value['name'][$i];
$arr_file_type = wp_check_filetype(basename($fildename));
$uploaded_file_type = $arr_file_type['type'];
$attachment = array(
'post_mime_type' => $uploaded_file_type,
'post_title' => addslashes($file_title_for_media_library),
'post_content' => $fildename,
'post_status' => 'inherit',
'post_parent' => 0,
'post_author' => get_current_user_id(),
);
wp_read_image_metadata( $file_name_and_location );
$attach_id = wp_insert_attachment( $attachment, $file_name_and_location,true,false);
$attach_data = wp_generate_attachment_metadata($attach_id,$file_name_and_location );
wp_update_attachment_metadata( $attach_id, $attach_data );
$images[]= array("image" => $attach_id);
}
}
update_field('photo_area', $images, $post);

This doesn't seem to work and returns nothing.


I'm assuming that after going through FormData(), the files are now not accessible on the normal $_FILES['name_of_input'], and should rather have something else done with them?


I've also tried just appending the images to the FormData, but seemed to be having the same issue.


Would anyone be able to shed some light on how I could access $_FILES["photo_of_area"], and also $_FILES["reference_images"] independently of each other after being passed through FormData()? Or any alternative ways that I should look at to achieve the desired behaviour.


Ideally, I need to access images from each file input respectively.


Thanks!



My Answer:
After using FormData to send files via AJAX, you can access the files in PHP using the $_FILES superglobal. However, since you are sending multiple files from multiple file inputs, the structure of the $_FILES array will be a bit different.

When you send multiple files from a single file input, the $_FILES array will have a structure like this:

$_FILES['file_input_name']['name'][0]
$_FILES['file_input_name']['name'][1]
...
$_FILES['file_input_name']['tmp_name'][0]
$_FILES['file_input_name']['tmp_name'][1]
...


When you send files from multiple file inputs, the structure will be like this:

$_FILES['file_input_name']['name'][0]
$_FILES['file_input_name']['name'][1]
...
$_FILES['file_input_name']['tmp_name'][0]
$_FILES['file_input_name']['tmp_name'][1]
...
$_FILES['file_input_name']['name'][0]
$_FILES['file_input_name']['name'][1]
...
$_FILES['file_input_name']['tmp_name'][0]
$_FILES['file_input_name']['tmp_name'][1]
...


To access files from each file input separately, you can loop through the $_FILES array and check the file input name. Here's an example of how you can do this in your PHP code:

php
foreach($_FILES as $file_input_name => $file_data){
if($file_input_name == 'photo_of_area'){
// Process files from the 'photo_of_area' file input
foreach($file_data['name'] as $key => $file_name){
$file_tmp = $file_data['tmp_name'][$key];
// Process the file as needed
}
} elseif($file_input_name == 'reference_images'){
// Process files from the 'reference_images' file input
foreach($file_data['name'] as $key => $file_name){
$file_tmp = $file_data['tmp_name'][$key];
// Process the file as needed
}
}
}


By checking the file input name in the loop, you can access files from each file input separately and process them accordingly.

Rate this post

4 of 5 based on 5335 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us