0

Trying to upload multiple files in randomly generated folder in different path than usual uploads/year/month by using wp_upload_bits.

Here is my code:

$randomFolder = '';

function file_upload_callback() {
    global $wpdb;
    $table_name = 'wp_order_quotes_real';
    $_filter = true;
    add_filter( 'upload_dir', function( $arr ) use( &$_filter){
        if ( $_filter ) {
            if ($randomFolder == '') {
                $randomFolder = substr(str_shuffle("0123456789abcdefghijklmnopqrstvwxyz"), 0, 16);
            }
            $arr['path'] = $arr['basedir'].'/order-quotes/'.$randomFolder;
            return $arr;
        }
    });
    _filter = false;    

    for($i=0; $i < $countfiles; $i++) {
        $upload = wp_upload_bits($_FILES['file']['name'][$i], null, file_get_contents($_FILES['file']['tmp_name'][$i]));
        
    }
    $dataSubmission = $wpdb->insert( 
        $table_name, array( 
            'order_id' => $order_id,
            'user_id' =>  $user_id ?? 'NULL',
            'category' => $cart
        ),
        array(
          '%d', '%d'
        )
    );
    
    
    wp_die();
}
add_action( 'wp_ajax_file_upload', 'file_upload_callback' );

If I upload 3 files, it creates three folders with random names and upload single file in each folder. I want to upload all the files in single generated folder in /order-quotes/ folder

3
  • That $_filter is undefined in your function. Same goes with the $randomFolder - or it was defined but it's out of scope in your function. And (just wondering) how do you call the file_upload_callback() - is it hooked on wp_ajax_?
    – Sally CJ
    May 21, 2021 at 15:33
  • I've uploaded full code. Yes, that's the hook of wp_ajax_. Do you think I can upload multiple files with one same folder and get its folderName? May 23, 2021 at 0:28
  • Yes you can. See my answer and try the fixes in my code.
    – Sally CJ
    May 23, 2021 at 5:59

1 Answer 1

1

Apply the following fixes (those with the // Fix <number>: comment) and your code would work in that only one random folder that will be created for all the uploads in the current session: (Note: I presumed the $countfiles is properly defined in your actual code.)

function file_upload_callback() {
    global $wpdb;
    $table_name = 'wp_order_quotes_real';

    $_filter = true;
    $randomFolder = ''; // Fix 1: Define the variable.

    // Fix 2: Pass $randomFolder by reference to the closure below. That way, the
    // value won't be changed when the hook calls the closure the next time.
    add_filter( 'upload_dir', function( $arr ) use ( &$_filter, &$randomFolder ) {
        if ( $_filter ) {
            if ($randomFolder == '') {
                $randomFolder = ... your code;
            }
            $arr['path'] = $arr['basedir'].'/order-quotes/'.$randomFolder;
            // Note: I moved the `return` line to below.
        }
        return $arr; // Fix 3: ALWAYS return it!
    });
    //$_filter = false; // Fix 4: Don't disable it, yet.

    for($i=0; $i < $countfiles; $i++) {
        // Note: You should do this because the user may not necessariy upload the
        // files in sequence, i.e. file input two might be empty and the user only
        // selected a file for the first and third inputs..
        if ( empty( $_FILES['file']['tmp_name'][ $i ] ) ) {
            continue;
        }

        $upload = wp_upload_bits( ... your code here... );

    }
    $_filter = false; // Fix 5: Now you should disable the filter because all the
                      // uploads have completed.

    // ... the rest of your code here.
}

Additionally, instead of hardcoding the table name, you should do $table_name = $wpdb->prefix . 'order_quotes_real';. More importantly, please apply security measures like checking user capabilities and intent of the specific request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.