The first part of the question is HERE.
I need to get a list of items from a suborder that have received the status 'shipped' or 'readytocollect' inside $message_body = .
To do this, I was advised to use $order->get_items() in a foreach loop, as described HERE.
The problems are:
I only manage to receive 1 item from my order. If there are 2 or more items in an order, I still receive 1 item in the letter. those. I only get: gold ring, when to order: Gold ring, chain, glasses
How can I get each product's image?
Any help is really appreciated.
// Enable custom statuses for WooCommerce Orders
add_action('init', 'register_custom_order_statuses');
function register_custom_order_statuses() {
register_post_status('wc-shipped', array(
'label' => __( 'Shipped', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop('Shipped <span class="count">(%s)</span>', 'Shipped <span class="count">(%s)</span>')
));
register_post_status('wc-readytocollect', array(
'label' => __( 'Ready to collect', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop('Ready to collect <span class="count">(%s)</span>', 'Ready to collect <span class="count">(%s)</span>')
));
}
// Add a custom order status to list of WC Order statuses
add_filter('wc_order_statuses', 'add_custom_order_statuses');
function add_custom_order_statuses($order_statuses) {
$new_order_statuses = array();
// add new order status before processing
foreach ($order_statuses as $key => $status) {
$new_order_statuses[$key] = $status;
if ('wc-processing' === $key) {
$new_order_statuses['wc-shipped'] = __('Shipped', 'woocommerce' );
$new_order_statuses['wc-readytocollect'] = __('Ready to collect', 'woocommerce' );
}
}
return $new_order_statuses;
}
// Send custom email notifications to sub orders only
add_action( 'woocommerce_order_status_changed', 'custom_order_statuses_email_notifications', 10, 4 );
function custom_order_statuses_email_notifications ($order_id, $from_status, $to_status, $order) {
// Targeting sub-orders only
if ( ! $order->get_parent_id() ) return;
if ( $to_status === 'shipped' ) {
$status_label = __( 'shipped', 'woocommerce' );
$status_label_soobshenie = __( 'shipped', 'woocommerce' );
}
elseif ( $to_status === 'readytocollect' ) {
$status_label = __( 'readytocollect', 'woocommerce' );
$status_label_soobshenie = __( 'readytocollect', 'woocommerce' );
}
if ( isset($status_label) ) {
$mailer = WC()->mailer(); // load the mailer class.
$email_subject = sprintf( __( 'readytocollect %s %s' ), $order->get_order_number(), $status_label );
// get an instance of the WC_Order object
foreach( $order->get_items() as $item_id => $item ){
$product_name = $item['name']; // The product name
$item_qty = $item['quantity']; // The quantity
$line_total = $item['subtotal']; // or $item['line_subtotal']
$message_body = '<html>
<head></head>
<body>
<h1>'.$status_label.'</h1>
<p>'.$status_label_soobshenie.'</p>
<p></p>
<table class="td" cellspacing="0" cellpadding="4" style="width: 100%; color: #001a34; font-size: 14px; font-weight: normal;" border="0">
<thead>
<tr>
<th width="65%" class="td" style="text-align:left;" scope="col" >'.$product_name.'</th>
<th width="10%" class="td" style="text-align:right;" scope="col" >'.$item_qty.'</th>
<th width="25%" class="td" style="text-align:right;" scope="col" >'.$line_total.'</th>
</tr>
</table>
</body>
</html>'; }
$message = $mailer->wrap_message( $email_subject, $message_body );
$mailer->send( $order->get_billing_email(), $email_subject, $message ); // Send email
}
}
The following will show all suborder items (I have added the product image):
// Send custom email notifications to sub orders only
add_action( 'woocommerce_order_status_changed', 'custom_order_statuses_email_notifications', 10, 4 );
function custom_order_statuses_email_notifications ($order_id, $from_status, $to_status, $order) {
// Targeting sub-orders only
if ( ! $order->get_parent_id() ) return;
if ( $to_status === 'shipped' ) {
$status_label = __( 'shipped', 'woocommerce' );
$status_label_message = __( 'shipped', 'woocommerce' );
}
elseif ( $to_status === 'readytocollect' ) {
$status_label = __( 'readytocollect', 'woocommerce' );
$status_label_message = __( 'readytocollect', 'woocommerce' );
}
if ( isset($status_label) ) {
$mailer = WC()->mailer(); // load the mailer class.
$email_subject = sprintf( __( 'Order %s %s' ), $order->get_order_number(), $status_label );
$message_body = '<html><head></head>
<body>
<h1>'.$status_label.'</h1>
<p>'.$status_label_message.'</p>
<p></p>
<table class="td" cellspacing="0" cellpadding="4" style="width: 100%; color: #001a34; font-size: 14px; font-weight: normal;" border="0">
<thead>';
foreach( $order->get_items() as $item ){
$product = $item->get_product(); // Get product
$image = $product->get_image(array( 32, 32 )); // Get product image 32 x 32 px
$message_body .= '<tr>
<th width="65%" class="td" style="text-align:left;" scope="col" >'.$image.' '.$item->get_name().'</th>
<th width="10%" class="td" style="text-align:right;" scope="col" >'.$item->get_quantity().'</th>
<th width="25%" class="td" style="text-align:right;" scope="col" >'.$item->get_total().'</th>
</tr>';
}
$message_body .= '</thead></table>
</body></html>';
$message = $mailer->wrap_message( $email_subject, $message_body );
$mailer->send( $order->get_billing_email(), $email_subject, $message ); // Send email
}
}
It should work as expected.
Related: Get Order items and WC_Order_Item_Product in WooCommerce 3