skip to Main Content

I want to add a button to the WooCommerce admin page which allows for me to upload a file (e.g. .pdf, .jpg, .png, etc.) to a custom folder which is located in the "Uploads" folder in the directory. The function just keeps reloading to the same page while not uploading the file.

I even tested it out on another WordPress installation, but it strangely redirected to all posts. I’m sure I’m missing something. I’m using Local by Flywheel, locally hosted and everything is up to date. Please help. Thank you in advance.

What I was expecting was to have the ability to upload a document to a custom folder within the uploads folder which I could call/pull documents as need to attach or send to specific users. I have tried the following solutions:

add_action( 'woocommerce_after_order_itemmeta', 'uploaddocs', 10, 1);
function uploaddocs(){
?>

<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submittheform">
</form>

<?php
global $wp_filesystem;
WP_Filesystem();

$content_directory = $wp_filesystem->wp_content_dir() . 'uploads/';
$wp_filesystem->mkdir( $content_directory . 'CustomDocuments' );

$target_dir_location = $content_directory . 'CustomDocuments/';
  
if(isset($_POST["submittheform"])){ //&& isset($_FILES['fileToUpload'])) {
 
$name_file = $_FILES['fileToUpload']['name'];
$tmp_name = $_FILES['fileToUpload']['tmp_name'];
 
if( move_uploaded_file( $tmp_name, $target_dir_location.$name_file ) ) {
    echo "File was successfully uploaded";
} else {
    echo "The file was not uploaded";
}
 
}
} 

Strangely the code works if I place the html form twice.

add_action( 'woocommerce_after_order_itemmeta', 'uploaddocs', 10, 1);
function uploaddocs(){
?>
    
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submittheform">
</form>

<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload Image" name="submittheform">
</form>

 <?php
global $wp_filesystem;
WP_Filesystem();

$content_directory = $wp_filesystem->wp_content_dir() . 'uploads/';
$wp_filesystem->mkdir( $content_directory . 'CustomDocuments' );

$target_dir_location = $content_directory . 'CustomDocuments/';
 
if(isset($_POST["submittheform"])){ //&& isset($_FILES['fileToUpload'])) {
 
$name_file = $_FILES['fileToUpload']['name'];
$tmp_name = $_FILES['fileToUpload']['tmp_name'];
 
if( move_uploaded_file( $tmp_name, $target_dir_location.$name_file ) ) {
    echo "File was successfully uploaded";
} else {
    echo "The file was not uploaded";
}
 
}
}

I even asked ChapGPT for help and I ran into the same issue. The AI code solution is this:

add_action( 'woocommerce_after_order_itemmeta', 'custom_file_upload_form', 10, 3 );
function custom_file_upload_form( $item_id, $item, $product ) {
// Output the form only for line items
if ( $item->get_type() !== 'line_item' ) return;

// Output the form
echo '<form action="" method="post" enctype="multipart/form-data">';
echo '<input type="file" name="custom_document" id="custom_document_' . esc_attr( $item_id )            . '">';
echo '<input type="hidden" name="action" value="upload_custom_document">';
echo '<input type="hidden" name="order_item_id" value="' . esc_attr( $item_id ) . '">';
echo '<input type="submit" value="Upload Document">';
echo '</form>';


}

add_action( 'init', 'handle_custom_document_upload' );
function handle_custom_document_upload() {
// Debugging: Check if the function is triggered
error_log('Form submitted.');

if ( isset( $_POST['action'] ) && $_POST['action'] == 'upload_custom_document' ) {
    error_log('Custom document upload action triggered.');

    if ( isset( $_FILES['custom_document'] ) ) {
        error_log('File detected: ' . print_r($_FILES['custom_document'], true));

        $file = $_FILES['custom_document'];

        // Handle the file upload
   $upload = wp_upload_bits( $file['name'], null, file_get_contents( $file['tmp_name'] )   );

        if ( ! $upload['error'] ) {
            error_log('File upload successful.');

            $upload_dir = wp_upload_dir();
            $custom_dir = $upload_dir['basedir'] . '/CustomDocuments';

            if ( ! file_exists( $custom_dir ) ) {
                wp_mkdir_p( $custom_dir );
            }

            $new_file = $custom_dir . '/' . basename( $upload['file'] );

            if ( move_uploaded_file( $file['tmp_name'], $new_file ) ) {
                error_log('File moved to CustomDocuments folder.');
            } else {
                error_log('Error moving file.');
            }
        } else {
            error_log('Error in file upload: ' . $upload['error']);
        }
    } else {
        error_log('No file detected.');
    }
}
}

I unfortunately had the same issues. If I repeat the html form twice then the functions work. However on the new installation it doesn’t work. Here’s the code repeating:

add_action( 'woocommerce_after_order_itemmeta', 'custom_file_upload_form', 10, 3 );
function custom_file_upload_form( $item_id, $item, $product ) {
// Output the form only for line items
if ( $item->get_type() !== 'line_item' ) return;

// Output the form
echo '<form action="" method="post" enctype="multipart/form-data">';
echo '<input type="file" name="custom_document" id="custom_document_' . esc_attr( $item_id )     . '">';
echo '<input type="hidden" name="action" value="upload_custom_document">';
echo '<input type="hidden" name="order_item_id" value="' . esc_attr( $item_id ) . '">';
echo '<input type="submit" value="Upload Document">';
echo '</form>';

    // Output the form
echo '<form action="" method="post" enctype="multipart/form-data">';
echo '<input type="file" name="custom_document" id="custom_document_' . esc_attr( $item_id ) . '">';
echo '<input type="hidden" name="action" value="upload_custom_document">';
echo '<input type="hidden" name="order_item_id" value="' . esc_attr( $item_id ) . '">';
echo '<input type="submit" value="Upload Document">';
echo '</form>';
}

add_action( 'init', 'handle_custom_document_upload' );
function handle_custom_document_upload() {
// Debugging: Check if the function is triggered
error_log('Form submitted.');

if ( isset( $_POST['action'] ) && $_POST['action'] == 'upload_custom_document' ) {
    error_log('Custom document upload action triggered.');

    if ( isset( $_FILES['custom_document'] ) ) {
        error_log('File detected: ' . print_r($_FILES['custom_document'], true));

        $file = $_FILES['custom_document'];

        // Handle the file upload
        $upload = wp_upload_bits( $file['name'], null, file_get_contents( $file['tmp_name'] )    );

        if ( ! $upload['error'] ) {
            error_log('File upload successful.');

            $upload_dir = wp_upload_dir();
            $custom_dir = $upload_dir['basedir'] . '/CustomDocuments';

            if ( ! file_exists( $custom_dir ) ) {
                wp_mkdir_p( $custom_dir );
            }

            $new_file = $custom_dir . '/' . basename( $upload['file'] );

            if ( move_uploaded_file( $file['tmp_name'], $new_file ) ) {
                error_log('File moved to CustomDocuments folder.');
            } else {
                error_log('Error moving file.');
            }
        } else {
            error_log('Error in file upload: ' . $upload['error']);
        }
    } else {
        error_log('No file detected.');
    }
}
}

2

Answers


  1. WordPress uploads require JavaScript / Ajax to avoid the issue you are facing. Try the following code replacement:

    // Add file upload to Admin order items
    add_action( 'woocommerce_after_order_itemmeta', 'admin_order_itemmeta_upload_docs', 10, 2);
    function admin_order_itemmeta_upload_docs( $item_id, $item ){
        // Only for "line item" order items
        if( ! $item->is_type('line_item') ) return;
    
        echo '<div class="upload-'.$item_id.'"><p class="file_uploaded">';
    
        // Display the uploaded file (if any)
        if ( $upload = $item->get_meta('_file_upload') ) {
            echo 'File: <a class="button" href="'.$upload['url'].'" target="_blank">'.$upload['name'].'</a>';
        }
        echo '</p>';
        
        $other_tags  = 'accept=".png,.jpg,.doc,.docx,.rtf,.txt,.pdf" '; // <==  Accepted file types extensions
        $other_tags .= 'data-order_id="'.$item->get_order_id().'" data-item_id="'.$item_id.'"';
        // Display the file upload field
        ?>
        <p class="form-row validate-required" id="file_field" >
            <label for="file"><?php _e("Upload File") . ': '; ?>
                <input type="file" name="file" <?php echo $other_tags; ?> />
            </label>
        </p></div>
        <?php
    }
    
    // jQuery Ajax sender
    add_action('admin_footer', 'wc_order_admin_footer_script', 10);
    function wc_order_admin_footer_script() {
        ?>
        <script>
        jQuery(function($){
            $(document.body).on( 'change', 'input[name=file]', function() {
                const files    = $(this).prop('files'),
                      order_id = $(this).data('order_id'),
                      item_id  = $(this).data('item_id');
    
                if ( files.length ) {
                    const file = files[0],
                          itemID = $(this).data('item_id'),
                          formData = new FormData(),
                          trItem   = $('tr.item[data-order_item_id="'+itemID+'"]');
                          
                    formData.append( 'uploads', file );
                    formData.append( 'order_id', $(this).data('order_id') );
                    formData.append( 'item_id', itemID );
    
                    trItem.block({message: null, overlayCSS:{background:"#fff",opacity: .6}});
    
                    $.ajax({
                        url: '<?php echo admin_url('admin-ajax.php?action=order_item_upload&security='.wp_create_nonce('order_item_upload') ); ?>',
                        type: 'POST',
                        data: formData,
                        contentType: false,
                        enctype: 'multipart/form-data',
                        processData: false,
                        success: function ( response ) {
                            trItem.unblock();
                            $('div.upload-'+itemID).append(response);
                            $('#woocommerce-order-items').trigger('wc_order_items_reload');
                        },
                        error: function ( error ) {
                            trItem.unblock();
                            $('div.upload-'+itemID).append('<span style="color:red">Error: The upload failed.</span>');
                            $('#woocommerce-order-items').trigger('wc_order_items_reload');
                        }
                    });
                }
            });
        });
        </script>
        <?php
    }
    
    // PHP Ajax responder
    add_action( 'wp_ajax_order_item_upload', 'checkout_ajax_order_item_upload' );
    function checkout_ajax_order_item_upload(){
        check_ajax_referer('order_item_upload', 'security'); 
    
        if ( isset($_FILES['uploads']) ) {
            $upload_dir    = wp_upload_dir();
            $upload_path   = '/custom-documents/'; // <== HERE set your file path
            $upload_folder = $upload_dir['basedir']  . $upload_path;
            $upload_url    = $upload_dir['baseurl']  . $upload_path;
    
            if ( ! is_dir( $upload_folder ) ) {
                wp_mkdir_p( $upload_folder );
                chmod( $upload_folder, 0777 );
            }
            $file_path = $upload_folder . '/' . basename($_FILES['uploads']['name']);
            $file_url  = $upload_url . '/' . basename( $_FILES['uploads']['name']);
    
            if ( ! isset($_POST['order_id']) || ! isset($_POST['item_id']) ) {
                echo '<span style="color:red">' . __('Error: The upload process has been stopped.') . '</span>';
                wp_die();
            }
    
            if( move_uploaded_file($_FILES['uploads']['tmp_name'], $file_path)) {
                $order       = wc_get_order(intval($_POST['order_id']));
                $order_items = $order->get_items();
                $order_item  = $order_items[intval($_POST['item_id'])];
    
                $order_item->update_meta_data('_file_upload', array(
                    'url' => $file_url,
                    'name' => esc_attr($_FILES['uploads']['name']),
                ));
                $order_item->save();
    
                echo '<span style="color:green">' . __('Upload completed', 'woocommerce') . '</span><br>';
            } else {
                echo '<span style="color:red">' . __('Error: The upload failed.') . '</span>';
            }
        }
        wp_die();
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

    enter image description here

    Related:

    Login or Signup to reply.
  2. I test your code it is work!! but if i want to add a multiple file can?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search