In Woocommerce backend (admin), I have a function that allows the shop-manager to download all orders between two dates with a specific bunch of required data:
function write_to_file($date_initial, $date_final) {
global $attach_download_dir, $attach_download_file;
// Opens/creates file
$myfile = fopen($attach_download_dir . '/' . $attach_download_file, "w") or die("Unable to open file!");
// Populates first line
fwrite($myfile, 'Date; Parent Order ID; Order ID' . PHP_EOL);
// Retrieves orders data
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 = array( );
$orders = wc_get_orders( $args );
// Populates file with orders data
foreach ($orders as $order) {
$order_data = $order->get_data();
fwrite($myfile,
// Date of order creation
$order_data['date_created']->date('d/M/Y') . '; ' .
// Parent Order ID
'#' . ( ( $order->get_type() === 'shop_order' ) ? $order->get_id() : $order->get_parent_id() ) . '; ' .
// Order ID
'#' . $order->get_id()
)
}
}
This function is triggered on a button click…
I would like To enable something similar from admin orders list bulk selection functionality. So the selected orders by shop manager on admin orders list (see the screenshot below) will be sent to a similar custom script and then downloaded.
In that case, the selected orders would override the specified dates, if any, in the orders retrieval.
However, I can't find a variable to access that tells me which orders are selected at that moment by the admin user.
Any help will be appreciated…
First, to create a field, go to WooCommerce > Custom Order Fields. Click “Add Field” and begin creating your order field. The “label” is the field name, and will be displayed in the order details. The “description” will be displayed to the user upon hovering over the “?” symbol.
Adding a custom bulk action in the dropdown Here's a complete overview of possible options for screen: bulk_actions-edit-post : Post type 'post' edit screen. bulk_actions-edit-page : Post type 'page' edit screen. bulk_actions-edit-<post-type-name> : Custom post type edit screen.
If you need to clean up your WooCommerce order history, bulk deleting orders is a quick and easy way to do it. Simply navigate to the Orders page, select the orders you want to delete, and then click on the Bulk Actions > Delete menu item.
Go to WooCommerce > Settings > Order Statuses, and set up new statuses or email triggers. Edit your email content if needed. That's it! Sit back and enjoy custom WooCommerce order statuses and automatic emails!
Here is the complete way to make your functionality work on bulk order list action selection, instead of date range:
// Adding to admin order list bulk dropdown a custom action 'custom_downloads'
add_filter( 'bulk_actions-edit-shop_order', 'downloads_bulk_actions_edit_product', 20, 1 );
function downloads_bulk_actions_edit_product( $actions ) {
$actions['write_downloads'] = __( 'Download orders', 'woocommerce' );
return $actions;
}
// 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 ) {
if ( $action !== 'write_downloads' )
return $redirect_to; // Exit
global $attach_download_dir, $attach_download_file; // ???
$processed_ids = array();
foreach ( $post_ids as $post_id ) {
$order = wc_get_order( $post_id );
$order_data = $order->get_data();
// Your code to be executed on each selected order
fwrite($myfile,
$order_data['date_created']->date('d/M/Y') . '; ' .
'#' . ( ( $order->get_type() === 'shop_order' ) ? $order->get_id() : $order->get_parent_id() ) . '; ' .
'#' . $order->get_id()
);
$processed_ids[] = $post_id;
}
return $redirect_to = add_query_arg( array(
'write_downloads' => '1',
'processed_count' => count( $processed_ids ),
'processed_ids' => implode( ',', $processed_ids ),
), $redirect_to );
}
// The results notice from bulk action on orders
add_action( 'admin_notices', 'downloads_bulk_action_admin_notice' );
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 );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
In the returned url I have something like (for 2 selected / processed orders):
wp-admin/edit.php?post_type=shop_order&paged=1&write_downloads=1&processed_count=2&processed_ids=847%2C846
I can't test your included script but it's the way to do it on Woocommerce Orders Admin list.
VARIABLES:
The available variables are set by add_query_arg()
function as you will see. When the action is triggered, you get those variables in the URL through GET method…
You can set any variable yourself too…
In this example you can use $_GET
or $_REQUEST
with:
$_GET['write_downloads']
(the name action: true
or false
)
$_GET['processed_count']
(the number of selected orders)
$_GET['processed_ids']
(the Order Ids separated by an url-encoded coma %2C
)
So you can either execute your script:
- inside my code function (like in my code) … or …
- outside it, using the available variables once the action is triggered…
For example we want to remove "On hold" status change:
add_filter( 'bulk_actions-edit-shop_order', 'remove_a_bulk_order_action', 20, 1 );
function remove_a_bulk_order_action( $actions ) {
unset($actions['mark_on-hold']);
return $actions;
}
All statuses change keys start with
mark_
+ the status slug (withoutwc-
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With