How to upload files to the server width media_handle_upload?

139 views Asked by At

I have a problem with creating posts, specifically with uploading post images. The idea is that an unauthorized user submits an application for a contest. After successful payment, I send the form data via ajax in Json format.

  1. payData for payment:
    function getPayData() {
    
        var payData = {};
    
        
        payData['gallery-parent-id'] = {};
        payData['gallery-parent-id']['value'] = form.dataset.parent;
        payData['form-id'] = {};
        payData['form-id']['value'] = form.dataset.id;
        
        // return payData
        return payData;
    }
  1. Ajax for payment:
$.ajax({
        url: url,
        type: 'POST',
        data: payData,
        success: function(response) {

            var response_end = JSON.parse(response);

            var confirmationToken = response_end.confirmation_token;
            var order_id = response_end.id;
            var amount = response_end.amount;
            if (confirmationToken) {
                const checkout = new window.YooMoneyCheckoutWidget({
                    customization: {
                        control_primary: '#81fdc5'
                    },
                    error_callback: function(error) {
                    }
                });

                checkout.on('success', () => {
                    formData.append('order id:', order_id);
                    formData.append('amount:', amount);
                    
                    const success_url = '/pay/success-pay-handler.php';

                    $.ajax({
                        url: success_url,
                        type: 'POST',
                        data: formData,
                        cache       : false,
                        dataType    : 'json',
                        processData : false,
                        contentType : false,
                        success: function(response) {

                            console.log(response);
                            //message.classList.add('show');
                        },
                        error: function(response) {
                            // Обработка ошибки
                            console.log(response);
                            console.error('Error data send.');
                        }
                    });
        
                    //del widget
                    checkout.destroy();
                });

        
                checkout.render('payment-form');
                setTimeout(function() {
                    //form.classList.add('in-process');
                }, 300);
            } else {
                console.log('No token')
            }
          


        },
        error: function() {
          // Error hand
          console.error('Errror data send.');
        }
    });
  1. formData:
    formData = new FormData();

    for (var i = 0; i < form.elements.length; i++) {
        var element = form.elements[i];
        if (element.type === 'text' || element.type === 'textarea' || element.type === 'number' || element.type === 'mail') {
                    
            var label = document.querySelector('label[for="' + element.name + '"]');

            var name = element.name;

            var title = label.textContent.trim();
            var value = element.value;

            var valueWithLabel = [title, value];

            formData.append(name, valueWithLabel);

        } else if (element.type === 'file') {

            var name = element.name;

            formData.append(name, element.files[0]);
        }
    }
  1. Ajax for formData
                    $.ajax({
                        url: success_url,
                        type: 'POST',
                        data: formData,
                        cache       : false,
                        dataType    : 'json',
                        processData : false,
                        contentType : false,
                        success: function(response) {
                            console.log(response);
                        },
                        error: function(response) {
                            console.log(response);
                            console.error('Error data send.');
                        }
                    });

I successfully receive the form data in the PHP Handler. First, I include the necessary files for the operation:

require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');

Then I retrieve the data from ajax, one with regular data - $formData, and the other with files - $formFiles.

    $formData = $_POST;
    $formFiles = $_FILES;

Next, I iterate through the form fields + ACF array. The posts are successfully created, so I won't send the entire code just yet. Then, the problems start when I try to upload an image for the post. I iterate through $_FILES, store the values in the $artFiles array.

    $artFiles = array();
    
    foreach ($formFiles as $key => $file) {
        if (strpos($key, "art-file-") === 0) {
            $artFileNumber = substr($key, strlen("art-file-"));
            $artFiles[$artFileNumber] = $file;
        }
    }

My $artNames foreach:


    foreach ($formData as $key => $value) {
        if (strpos($key, "art-name-") === 0) {
            // Разбиваем строку значения по запятой
            $parts = explode(',', $value);
    
            // Проверяем, что в массиве $parts есть второй элемент
            if (isset($parts[1])) {
                $artNameNumber = str_replace("art-name-", "", $key);
                $artName = trim($parts[1]);
    
                // Добавляем значения в соответствующие массивы
                $artNames[$artNameNumber] = $artName;
            }
    }

Create posts:

foreach ($artNames as $artNameNumber => $artName) {
        $artHeight = isset($artHeights[$artNameNumber]) ? $artHeights[$artNameNumber] : '';
        $artWidth = isset($artWidths[$artNameNumber]) ? $artWidths[$artNameNumber] : '';
        $artMaterial = isset($artMaterials[$artNameNumber]) ? $artMaterials[$artNameNumber] : '';
        $artDescr = isset($artDescrs[$artNameNumber]) ? $artDescrs[$artNameNumber] : '';
        $artFile = isset($artFiles[$artNameNumber]) ? $artFiles[$artNameNumber] : '';

        $artFileInfo = $artFile['name'] . ' : ' . $artFile['tmp_name'] . ' : ' . $artFile['size']; // OK, it's work!
        $post_data = array(
            'post_type' => 'gallery',
            'post_status' => 'draft',
            'post_parent' => $parent_page_id,
            'post_title'     => $artName,
            'post_content' => $artFileInfo // For tests, it's OK: food-cat-image-2.jpg : /tmp/phpos4nzn : 2937708
        );


        $post_id = wp_insert_post($post_data);
    
        update_post_meta($post_id, '_wp_page_template', 'single-cat-gallery.php');


        // Upload File

        $attachment_id = media_handle_upload( $artFile, $post_id ); // Not work
        

        if ( is_wp_error( $attachment_id ) ) {
            $error_message = $attachment_id->get_error_message();
            echo json_encode( array( 'error' => $error_message ) );
        } else {
            echo json_encode( array( 'success' => 'File Upload Complete! ID:' . $attachment_id ) );
        }

        update_post_meta( $post_id, '_thumbnail_id', $attachment_id ); // OK, it's work!

        //
    
        if( is_wp_error($post_id) ){    

        } else {
            if (function_exists('update_field')) {

                // Acf fields
                
            }
        }
    
    }

String

$artFileInfo = $artFile['name'] . ' : ' . $artFile['tmp_name'] . ' : ' . $artFile['size']

=

cat-image-2.jpg : /tmp/phpos4nzn : 2937708

I have tried many different options, but none of them have helped.

Perhaps this information can help: I added a check for is_wp_error and got the following message:

responseText : 
"{\"error\":\"Specified file failed upload test.\"}{\"error\":\"Specified file failed upload test.\"}"
status : 200
statusText : "parsererror"

And more:

var_dump($_FILES):

array(2) {
  ["art-file-1"]=>
  array(5) {
    ["name"]=>
    string(18) "food-cat-image.jpg"
    ["type"]=>
    string(10) "image/jpeg"
    ["tmp_name"]=>
    string(14) "/tmp/php3xJrf3"
    ["error"]=>
    int(0)
    ["size"]=>
    int(272437)
  }
  ["art-file-2"]=>
  array(5) {
    ["name"]=>
    string(17) "video-preview.jpg"
    ["type"]=>
    string(10) "image/jpeg"
    ["tmp_name"]=>
    string(14) "/tmp/phpGsRXSE"
    ["error"]=>
    int(0)
    ["size"]=>
    int(100533)
  }
}

I have re-read a lot of similar topics and no solution has helped me. Please save me.

I tried adding in my PHP handler:

require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );

require_once(ABSPATH . 'wp-admin/includes/image.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');

I've tried iterating over $_FILES in different ways

Used different functions for upload

I tried to specify different values inside the media_handle_upload function:

$attachment_id = media_handle_upload( $artFile['name']/$artFile['tmp_name']/$_FILES['art-file-1']..., $post_id );

All php.info settings is OK.

UPD:

Thank you so much for your attention @CBroe!

our $artFile appears to be an array - one of the entries of the $_FILES array; but media_handle_upload wants a string $file_id as first parameter, the key of the file in the $_FILES array. The value you should be calling this with to process your first uploaded file there, is art-file-1

For my example all problems this:

$attachment_id = media_handle_upload( $artFile, $post_id );

The correct option

$attachment_id = media_handle_upload( 'art-file-' . $artNameNumber, $post_id );
1

There are 1 answers

0
ayoob zare On

I use this code hope help you

 // it allows us to use wp_handle_upload() function
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    require_once(ABSPATH . 'wp-admin/includes/file.php');
    require_once(ABSPATH . 'wp-admin/includes/media.php');

    $upload = wp_handle_upload(
        $_FILES['uploaded'],
        array('test_form' => false)
    );

    if (!empty($upload['error'])) {
        wp_send_json( 'error in upload' );
    }

    // it is time to add our uploaded image into WordPress media library
    $attachment_id = wp_insert_attachment(
        array(
            'guid'           => $upload['url'],
            'post_mime_type' => $upload['type'],
            'post_title'     => basename($upload['file']),
            'post_content'   => '',
            'post_status'    => 'inherit',
        ),
        $upload['file'],
        $postId //when i create post by wp_insert_post postId return;
    );

    if (is_wp_error($attachment_id) || !$attachment_id) {
        wp_send_json( 'error in upload' );
    }

    set_post_thumbnail($postId, $attachment_id);