WordPress REST API FormData: Form Not Submitted When No Files Attached
-
I am writing a plugin to show a custom form in front-end. The form contains various input fields (mostly text) and one input multiple files.
The submit sends data via an ajax call to a rest api endpoint. Everything is ok until I upload the files: form is submitted and the endpoint callback function saves data in MyQSql. However if I try to submit the form without upload any file (the field is not mandatory) I have an error message “There was an error submitting your form” (it is printed if the ajax call doesn’t work).
What am I doing wrong?
Here is my code
<form id= "idp_sight_form" action="" method="post" enctype="multipart/form-data"> <?php wp_nonce_field('wp_rest'); ?> <div class="form-body"> <div class="full-field"> <input type="text" id="first_name" name="first_name" placeholder="First Name" > </div> <div class="full-field"> <input type="text" id="last_name" name="last_name" placeholder="Last Name" > </div> <div class="full-field"> <label for="imageUpload">Choose a maximum of 3 images to upload (jpg, png - size < 5MB):</label><br/> <div id="drop-area"> <span class="drop-text">Drag and drop files here or click to browse</span> <input type="file" id="file-input" name='file-input[]' accept=".jpg, .png" multiple style="display: none;"> </div> <div id="file-list"></div> <span id="fileError" style="color: red;"></span><br/> </div> </div> <div class="form-footer"> <input id="submit-form" type="submit" name="submit" value="Submit"> </div><!--closes form-footer--> </form> <script> //Function to send form to rest_api jQuery(document).ready(function($) { $("#idp_sight_form").submit(function(event) { event.preventDefault(); var form = $(this); formParam = form.serialize(); var ajaxFiles = new FormData(this); // Listen for file selection change event $('#file-input').on('change', function() { handleFiles($(this)[0].files); }); // Get the drop area element var dropArea = document.getElementById('drop-area'); // Prevent default behavior when files are dragged over the drop area dropArea.addEventListener('dragover', function(e) { e.preventDefault(); }, false); // Handle dropped files dropArea.addEventListener('drop', function(e) { e.preventDefault(); }, false); // Function to handle files function handleFiles(files) { // Loop through files for (var i = 0; i < files.length; i++) { var file = files[i]; ajaxFiles.append('file-input[]', file); // Append each file to FormData } } // Append form data to FormData ajaxFiles.append('form_data', formParam); // Check if any files are uploaded var filesUploaded = false; for (var pair of ajaxFiles.entries()) { if (pair[0] === 'file-input[]' && pair[1].name) { filesUploaded = true; break; } } // Check if any files are uploaded if (filesUploaded) { $.ajax({ url:"<?php echo get_rest_url(null, 'sight-form-tethys/v1/register_data'); ?>", type: "POST", data: ajaxFiles, processData: false, contentType: false, success: function(res) { //grabbing the response as res uses the WP_Rest_Response written in the handler of the rest api form.hide(); $("#form-success").html(res).fadeIn(); }, error: function() { form.hide(); $("#form-error").html("There was an error submitting your form").fadeIn(); } }) } else { // If no files are uploaded, submit the form without files $.ajax({ url: "<?php echo get_rest_url(null, 'sight-form-tethys/v1/register_data'); ?>", type: "POST", data: formParam, success: function(res) { form.hide(); $("#form-success").html(res).fadeIn(); }, error: function() { form.hide(); $("#form-error").html("There was an error submitting your form").fadeIn(); } }); } }) }); </script>
and the following is the callback function registered in the endpoint
<?php //endpoint function register_data_function($data){ // Handle file uploads $params = $data->get_params(); $wp_nonce = $params['_wpnonce']; if($params['form_data']) { parse_str($params['form_data'], $form_data_array); $files_data = $data->get_file_params(); $wp_nonce = $form_data_array['_wpnonce']; } if(!wp_verify_nonce($wp_nonce, 'wp_rest')){ return new WP_Rest_Response(array('message' => 'Form not submitted'), 401); } //check for a folder where to store images global $wp_filesystem; // It is a WordPress core file, that's why we manually include it require_once ( ABSPATH . '/wp-admin/includes/file.php' ); //Just instantiate as follows WP_Filesystem(); $files_folder = WP_CONTENT_DIR .'/sighting-form-images'; if(!file_exists($files_folder)){ mkdir($files_folder, 0755, true); } $uploaded_files = []; // Check if there are any files uploaded if (!empty($files_data)) { // Iterate over each file input field foreach ($files_data as $file_input) { // Iterate over each file in the input field foreach ($file_input['tmp_name'] as $index => $tmp_name) { // Validate file type (ensure it's an image) $mime_type = mime_content_type($tmp_name); $file_type = sanitize_mime_type($mime_type); if (strpos($file_type, 'image') === false) { // If the file is not an image, skip it and return an error response return new WP_Rest_Response(array('message' => 'Only image files are allowed'), 400); } // Construct unique file path (append index to filename if necessary) $file_name = sanitize_file_name($file_input['name'][$index]); $file_extension = pathinfo($file_name, PATHINFO_EXTENSION); $file_base_name = pathinfo($file_name, PATHINFO_FILENAME); $counter = 0; $new_file_name = $file_name; while (file_exists($files_folder . '/' . $new_file_name)) { $counter++; $new_file_name = $file_base_name . '_' . $counter . '.' . $file_extension; } $file_path = $files_folder . '/' . $new_file_name; // Move the uploaded file to the destination folder if (move_uploaded_file($tmp_name, $file_path)) { // File moved successfully $file_url = site_url('/wp-content/sighting-form-images/') . $new_file_name; //$uploaded_files[] = $file_path; $uploaded_files[] = $file_url; } else { // Error handling if file move fails return new WP_Rest_Response(array('message' => 'Failed to move file'), 500); } } } $fileUrl = implode(';', $uploaded_files); } else { // Handle if no files are uploaded return new WP_Rest_Response(array('message' => 'No files uploaded'), 400); } //I unset the parameters I don't need in the response unset($form_data_array['_wpnonce']); unset($form_data_array['_wp_http_referer']); global $wpdb; $table_name = $wpdb->prefix . 'sight_form_data'; $data_array = array( 'first_name' => sanitize_text_field($form_data_array['first_name']), 'last_name' => sanitize_text_field($form_data_array['last_name']), 'fileUrl' => sanitize_text_field($fileUrl) ); //file_put_contents($files_folder. '/somefile.txt', print_r($data_array, true), FILE_APPEND); $result = $wpdb->insert($table_name, $data_array); //file_put_contents($files_folder. '/somefile.txt', print_r($result, true), FILE_APPEND); // Check for errors if ($result === false) { // There was an error inserting data, print out the error for debugging return new WP_Rest_Response(array('Error saving data'), 200); } return new WP_Rest_Response(array('Your form has been submitted succesfully'), 200); } ?>
Viewing 8 replies - 1 through 8 (of 8 total)
Viewing 8 replies - 1 through 8 (of 8 total)
- The topic ‘WordPress REST API FormData: Form Not Submitted When No Files Attached’ is closed to new replies.