In Woocommerce, I have implemented the code below from this answer thread to one of my questions that allows the admin user to download standardized information of orders in bulk from the backend "shop orders list". To achieve that, the user either selects the period between two dates or selects the desired orders one by one; after which he runs a new 'download to file' action to process his request.
My code is divided in 4 hooked functions:
the first displays the html content, including the dates inputs and a new bulk action to allow the download action;
the second is where the main action takes place when the user clicks the apply action button: collects all the woocommerce info and writes it into a file in the server;
the third requests the user to download the file to his PC (I had to seggregate this one from the second part because the only way for my downloaded file not having a lot of HTML rubbish mixed was by adding the 'exit' function at the end; and
the fourth just displays a message to the user informing how many orders were processed and downloaded.
// 1st SUB-SNIPPET: Adding to admin order list bulk dropdown a custom action 'custom_downloads'
add_filter( 'bulk_actions-edit-shop_order', 'downloads_bulk_actions_edit_product', 100, 1 );
function downloads_bulk_actions_edit_product( $actions ) {
?><div class="alignleft actions custom">
<span>From: </span>
<input type="date" id="download_date_initial" name="download_date_initial" value="<?php echo date('Y-m-d'); ?>" class="input-date" />
<span> To: </span>
<input type="date" id="download_date_final" name="download_date_final" value="<?php echo date('Y-m-d'); ?>" class="input-date" />
</div><?php
$actions['write_downloads'] = __( 'Download orders', 'woocommerce' );
return $actions;
}
// 2nd SUB-SNIPPET: Make the action from selected orders
add_filter( 'handle_bulk_actions-edit-shop_order', 'downloads_handle_bulk_action_edit_shop_order', 10, 3 );
function downloads_handle_bulk_action_edit_shop_order( $redirect_to, $action, $post_ids ) {
global $attach_download_dir, $attach_download_file;
global $countries_list, $countries_obj;
if ( $action !== 'write_downloads' ) return $redirect_to; // Exit
$processed_ids = array();
// Opens file
$myfile = fopen($attach_download_dir . '/' . $attach_download_file, "w") or die("Unable to open file!");
$date_initial = $_REQUEST['download_date_initial'];
$date_final = $_REQUEST['download_date_final'];
if ( isset($date_initial) && isset($date_final) ) $args_ = array( 'date_created' => $date_initial . '...' . $date_final );
if ( isset($date_initial) && empty($date_final) ) $args_ = array( 'date_created' => '>=' . $date_initial );
if ( empty($date_initial) && isset($date_final) ) $args_ = array( 'date_created' => '<=' . $date_final );
if ( empty($date_initial) && empty($date_final) ) $args_ = [];
if ( isset($post_ids) && empty($args_)) $array = $post_ids; else {
$orders = wc_get_orders( $args_ );
$array=[]; if (isset($orders)) foreach ($orders as $order) array_push($array, $order->get_id());
}
// Goes through each selected order
foreach ( $array as $key => $post_id ) {
$order = wc_get_order( $post_id );
$order_data = $order->get_data();
// Fills in woocommerce orders info as required ...
fwrite($myfile, XXX);
$processed_ids[] = $post_id;
}
// Closes file
fclose($myfile);
// Returns info to be used elsewhere, namely displaying message
return $redirect_to = add_query_arg( array( 'write_downloads' => '1', 'processed_count' => count( $processed_ids ), ), $redirect_to );
}
// 3rd SUB-SNIPPET: requests admin user to download file to his PC
add_filter( 'handle_bulk_actions-edit-shop_order', 'downloads_handle_bulk_action_edit_shop_order_2', 20, 3 );
function downloads_handle_bulk_action_edit_shop_order_2( $redirect_to, $action, $post_ids ) {
global $attach_download_dir, $attach_download_file;
global $root_page;
// Saves in pc
$file_url = $root_page . 'wp-admin/' . $attach_download_dir . '/' . $attach_download_file;
header('Content-Description: File Transfer');
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename=' . basename($file_url));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
ob_clean();
flush();
readfile($file_url);
exit;
}
// 4th SUB-SNIPPET: The results notice from bulk action on orders
add_action( 'admin_notices', 'downloads_bulk_action_admin_notice', 10 );
function downloads_bulk_action_admin_notice() {
if ( empty( $_REQUEST['write_downloads'] ) ) return; // Exit
$count = intval( $_REQUEST['processed_count'] );
printf( '<div id="message" class="updated fade"><p>' . _n( 'Processed %s order for downloads.', 'Processed %s orders for downloads.', $count, 'write_downloads' ) . '</p></div>', $count );
}
However I have 3 problems here:
If I have the "download to PC part", ie the 3rd sub-snippet in place, the message ceases to be displayed in the back-end. If I take it out, I can see the message but the user is no longer requested to download the file to his PC. I tried several alternatives, all without success.
If one wants to download orders selected one by one, there is no issue. But if one wants to select all orders between two dates, the admin user is forced to also select at least one order for the bulk action to run. Otherwise, it won't process the 'handle_bulk_actions-edit-shop_order' hook. This is annoying and serves no purpose for the user, as that order is only selected to make the system go through that hook, eventhough only the 2 dates are, in this case, relevant to determine which orders are to be downloaded.
I would like for the 'download' action to be chosen by default in the action button, without the user having to select it. I tried doing this namely with Javascript but to no avail ...
Any ideas?