The question:
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
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0