skip to Main Content

I’ve successfully built a form that allows users to input their order ID, expense amount, and a reason for the expense. When the user submits the form, the expense and reason for expense are added to the metadata of the submitted order ID.

Here’s the entire code:

<form id="expense_form" class="expense_form" action="" method="post">
    <label for="order-id">Order ID:</label>
    <input class="exp_order_no" id="exp_order_no" type="text" pattern="[0-9]*" placeholder="Enter the Order Number" required>
    
    <label for="expense">Expense:</label>
    <input class="expense_amt" id="expense_amt" type="text"  pattern="[0-9]*" placeholder="Enter the expense amount" required>
    
    <label for="reason">Reason for Expense:</label>
    <textarea class="expense_reason" id="expense_reason" id="reason" name="reason" rows="4" placeholder="Enter Message" required></textarea>

    <input type="submit" class="exp_but" id="exp_but" value="Submit">
</form> 
<script>
    jQuery(document).ready(function($) {
            $('#expense_form').on('submit', function(e) {
                e.preventDefault();
                var orderid  = $('#exp_order_no').val();
                var expense  = $('#expense_amt').val();
                var expense_reason  = $('#expense_reason').val();
                    //  console.log (orderid);
                    //  console.log (expense);
                    //  console.log (expense_reason);
             $.ajax({
                    url: '<?php echo admin_url('admin-ajax.php'); ?>',
                    type: 'POST',
                    data: {
                        action:'update_custom_field_order_expense_php',
                        orderid: orderid,
                        expense: expense,
                        expense_reason:expense_reason
                    },
                    success: function( response ) {
                        console.log( 'Custom field updated successfully.' );
                        alert('Expense Submitted Successfully !!');
                        location.reload();
                    },
                    error: function( response ) {
                        console.log( 'Failed to Submit Expense.' );
                        alert('Failed to Submit Expense. Contact Online Team.');
                        location.reload();
                    }
                });
             });
        });         
</script>

<?php

add_action( 'wp_ajax_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php' );
add_action('wp_ajax_nopriv_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php');

function update_custom_field_order_expense_php() {
    $order_id = $_POST['orderid'];
    $order_expense = $_POST['expense'];
    $order_expense_reason = $_POST['expense_reason'];
    $order = wc_get_order( $order_id );
    if ( is_user_logged_in()) {
        $current_user = wp_get_current_user();
        $current_user_id = $current_user->ID;
    
        $driver_id = get_post_meta($order_id, 'lddfw_driverid', true);
        //$current_date = date_i18n( 'j F, Y', strtotime( $current_date_time ) );
        foreach ( $order->get_meta_data() as $meta ) {
                            if ( $meta->key === 'Driver Expense') {
                $expense_exist=$meta->value;
                }
        }
         if (($current_user_id == $driver_id) && (empty($expense_exist)))  {
            $order->update_meta_data('Driver Expense', $order_expense);
            $order->update_meta_data('Driver Expense Reason', $order_expense_reason);
            $order->save();
            wp_send_json_success();
        } else {
            http_response_code(403);
            wp_send_json(array('error' => 'Access denied'));
        }
    } else {
        http_response_code(401); 
        wp_send_json(array('error' => 'Authentication required'));
    }
    exit;
}
    ?>

However, I’m now facing a challenge in adding an important functionality: image upload for proof of expense.

Image Upload for Proof of Expense: I want users to be able to upload images as proof of their expenses. This is crucial for verification purposes and record-keeping. Ideally, users should be able to attach one or more images related to their expense.

I’m not sure where to start with implementing this functionality. If anyone has experience or suggestions on how to achieve this, I would greatly appreciate your guidance and insights.

Here are some specific questions I have:

How can I enable image uploads within my form?

What is the best way to store these uploaded images and link them to the respective order ID?

I’ve created a directory /wp-content/uploads/2023/Expense_images and want all the images to be stored in here.

Any help or code examples related to this functionality would be highly valuable. Thank you in advance for your assistance!

2

Answers


  1. Chosen as BEST ANSWER

    UPDATE:

    I tried debugging the code and fix and possible issues but I'm unable to activate the PHP code via code snippet plugin as It's giving me error status 400. I'm giving the whole code bellow, please let me know how I can solve this.

    
    <form id="expense_form" class="expense_form" action="" method="post" enctype="multipart/form-data">
       <label for="order-id">Order ID:</label>
       <input class="exp_order_no" id="exp_order_no" type="text" pattern="[0-9]*" placeholder="Enter the Order Number" required>
    
       <label for="expense">Expense:</label>
       <input class="expense_amt" id="expense_amt" type="text" pattern="[0-9]*" placeholder="Enter the expense amount" required>
    
       <label for="reason">Reason for Expense:</label>
       <textarea class="expense_reason" id="expense_reason" name="reason" rows="4" placeholder="Enter Message" required></textarea>
    
       <label for="my_image_upload">Upload Image:</label>
       <input type="file" name="my_image_upload[]" id="my_image_upload" accept="image/*" required multiple>
    
       <input type="submit" class="exp_but" id="exp_but" value="Submit">
    </form>
    
    <script>
    jQuery(document).ready(function($) {
       $('#expense_form').on('submit', function(e) {
           e.preventDefault();
           var orderid = $('#exp_order_no').val();
           var expense = $('#expense_amt').val();
           var expense_reason = $('#expense_reason').val();
           var formData = new FormData(this);
    
           // Debugging: Output form data to console
           console.log('Order ID:', orderid);
           console.log('Expense:', expense);
           console.log('Expense Reason:', expense_reason);
           console.log('Form Data:', formData);
    
           $.ajax({
               url: '<?php echo admin_url('admin-ajax.php'); ?>',
               type: 'POST',
               data: formData, // Use formData to send all form data
               processData: false,
               contentType: false,
               enctype: 'multipart/form-data', // Specify enctype for file uploads
               success: function(response) {
                   // Handle success
                   console.log('Custom field updated successfully.');
                   alert('Expense Submitted Successfully !!');
                   location.reload();
               },
               error: function(response) {
                   // Handle error
                   console.log('Failed to Submit Expense.');
                   alert('Failed to Submit Expense. Contact Online Team.');
                   location.reload();
               }
           });
       });
    });
    </script>
    
    add_action('wp_ajax_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php');
    add_action('wp_ajax_nopriv_update_custom_field_order_expense_php', 'update_custom_field_order_expense_php');
    
    function update_custom_field_order_expense_php() {
       $order_id = sanitize_text_field($_POST['orderid']);
       $order_expense = sanitize_text_field($_POST['expense']);
       $order_expense_reason = sanitize_text_field($_POST['expense_reason']);
       $order = wc_get_order($order_id);
    
       if (!empty($_FILES['my_image_upload']['name'])) {
           $upload_dir = wp_upload_dir();
           $target_dir = $upload_dir['basedir'] . '/2023/Expense_images/';
    
           if (!file_exists($target_dir)) {
               wp_mkdir_p($target_dir);
           }
    
           $file_count = count($_FILES['my_image_upload']['name']);
    
           for ($i = 0; $i < $file_count; $i++) {
               $file_name = $_FILES['my_image_upload']['name'][$i];
               $file_tmp_name = $_FILES['my_image_upload']['tmp_name'][$i];
    
               $unique_filename = wp_unique_filename($target_dir, $file_name);
    
               $target_file = $target_dir . $unique_filename;
    
               if (move_uploaded_file($file_tmp_name, $target_file)) {
                   $order->update_meta_data('Expense Proof Image ' . ($i + 1), $target_file);
               }
           }
       }
    
       $order->update_meta_data('Driver Expense', $order_expense);
       $order->update_meta_data('Driver Expense Reason', $order_expense_reason);
       $order->save();
    
       // Debugging: Send a JSON response
       wp_send_json_success('Expense submitted successfully.');
    }
    
    

  2. Update you form to include the new unput fields:

    <label for="proof_images">Proof of Expense (Image):</label>
    <input type="file" id="proof_images" name="proof_images[]" accept="image/*" multiple>
    

    Modify your JavaScript code to handle file uploads along with the other form data. You will need to use the FormData object to send the file(s) to the server using the AJAX request.

    jQuery(document).ready(function($) {
        $('#expense_form').on('submit', function(e) {
            e.preventDefault();
            var orderid = $('#exp_order_no').val();
            var expense = $('#expense_amt').val();
            var expense_reason = $('#expense_reason').val();
            var formData = new FormData(this);
    
            $.ajax({
                url: '<?php echo admin_url('admin-ajax.php'); ?>',
                type: 'POST',
                data: {
                    action: 'update_custom_field_order_expense_php',
                    orderid: orderid,
                    expense: expense,
                    expense_reason: expense_reason,
                },
                processData: false, // Prevent jQuery from processing the data
                contentType: false, // Prevent jQuery from setting content type
                data: formData, // Use the FormData object
                success: function(response) {
                    // Handle success
                    console.log('Custom field updated successfully.');
                    alert('Expense Submitted Successfully !!');
                    location.reload();
                },
                error: function(response) {
                    // Handle error
                    console.log('Failed to Submit Expense.');
                    alert('Failed to Submit Expense. Contact Online Team.');
                    location.reload();
                }
            });
        });
    });
    

    Then update your update_custom_field_order_expense_php function to handle file uploads and save them to the desired directory:

    function update_custom_field_order_expense_php() {
        // ... Your existing code ...
    
        // Handle file uploads
        if (!empty($_FILES['proof_images']['name'])) {
            $upload_dir = wp_upload_dir();
            $target_dir = $upload_dir['basedir'] . '/2023/Expense_images/';
    
            // Create the target directory if it doesn't exist
            if (!file_exists($target_dir)) {
                wp_mkdir_p($target_dir);
            }
    
            $file_count = count($_FILES['proof_images']['name']);
    
            for ($i = 0; $i < $file_count; $i++) {
                $file_name = $_FILES['proof_images']['name'][$i];
                $file_tmp_name = $_FILES['proof_images']['tmp_name'][$i];
    
                // Generate a unique file name to prevent overwriting
                $unique_filename = wp_unique_filename($target_dir, $file_name);
    
                $target_file = $target_dir . $unique_filename;
    
                // Move the uploaded file to the target directory
                if (move_uploaded_file($file_tmp_name, $target_file)) {
                    // You can store the file paths or URLs in your order's metadata
                    // Example: $order->update_meta_data('Expense Proof Image ' . ($i + 1), $target_file);
                }
            }
        }
    
        // ... Your existing code ...
    }
    

    This code will handle multiple file uploads and store them in the /wp-content/uploads/2023/Expense_images/ directory with unique filenames. You can then choose how you want to associate these file paths or URLs with the respective order ID in your order’s metadata, as shown in the comments within the code.

    This is a basic example. However, when implementing file uploads, it’s crucial that you prioritize security to prevent various forms of attacks and vulnerabilities. So make sure to check stuff like file types, sizes etc:

    $allowed_mime_types = array('image/jpeg', 'image/png', 'image/gif');
    if (!in_array($_FILES['proof_images']['type'][$i], $allowed_mime_types)) {
        // Handle invalid file type
    }
    
    $max_file_size = 5 * 1024 * 1024; // 5 MB
    if ($_FILES['proof_images']['size'][$i] > $max_file_size) {
        // Handle oversized file
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search