通过自定义批量操作处理程序进行更新时,将订单状态更改为已确认但未发送确认电子邮件

时间:2019-06-05 07:08:14

标签: php wordpress woocommerce

需要对订单进行批量状态更新,以将其从“保留”更改为“已完成”,但不发送确认电子邮件。但是,仍然需要保留电子邮件功能。除了将标准WooCommerce批量操作更新为“已完成”(仍将发送确认电子邮件)之外,这还将是一个新的自定义批量操作。我添加了没有问题的额外选项,但是找不到能排除电子邮件通知的方法或暂时禁用电子邮件通知的方法(无论如何这听起来似乎不是一个好方法)。

到目前为止,代码如下。一切正常,除了$ order-> update_status('completed')触发确认电子邮件。

已尝试使用set_status(),但产生的结果相同(update_status调用set_status)。

/*
 * Custom bulk action in dropdown - Change status to completed without sending Confirmation Email
 */
add_filter( 'bulk_actions-edit-shop_order', 'register_bulk_action' ); // edit-shop_order is the screen ID of the orders page

function register_bulk_action( $bulk_actions ) {

    $bulk_actions['complete_with_no_email'] = 'Change status to completed (no confirmation emails)'; 
    return $bulk_actions;

}

/*
 * Bulk action handler
 */
add_action( 'admin_action_complete_with_no_email', 'bulk_process_custom_status' ); // admin_action_{action name}

function bulk_process_custom_status() {

    // if an array with order IDs is not presented, exit the function
    if( !isset( $_REQUEST['post'] ) && !is_array( $_REQUEST['post'] ) )
        return;

    // New order emails
    foreach( $_REQUEST['post'] as $order_id ) {

        $order = new WC_Order( $order_id );
        $order_note = 'Changed Status to Completed via bulk edit (no confirmation email)';
        $order->update_status('completed', $order_note); //STILL SENDS EMAIL
    }

    // of course using add_query_arg() is not required, you can build your URL inline
    $location = add_query_arg( array(
        'post_type' => 'shop_order',
        'changed' => count( $_REQUEST['post'] ), // number of changed orders
        'ids' => join( $_REQUEST['post'], ',' ),
        'marked_fulfilled_no_emails' => 1,
        'post_status' => 'all'
    ), 'edit.php' );

    wp_redirect( admin_url( $location ) );
    exit;

}

/*
 * Notices for Bulk Action 
 */
add_action('admin_notices', 'custom_order_status_notices');

function custom_order_status_notices() {

    global $pagenow, $typenow;

    if( $typenow == 'shop_order' 
     && $pagenow == 'edit.php'
     && isset( $_REQUEST['marked_fulfilled_no_emails'] )
     && $_REQUEST['marked_fulfilled_no_emails'] == 1
     && isset( $_REQUEST['changed'] ) ) {

        $message = sprintf( _n( 'Order status changed.', '%s order statuses changed.', $_REQUEST['changed'] ), number_format_i18n( $_REQUEST['changed'] ) );
        echo "<div class=\"updated\"><p>{$message}</p></div>";

    }

}

希望避免在使用订单中的自定义批量修改选项时触发确认电子邮件。

1 个答案:

答案 0 :(得分:0)

我发现解决此问题的最佳方法是在遍历选定的订单时使用update_post_meta添加一个标志,以使其绕过电子邮件确认,这与钩住woocommerce_email_recipient_customer_completed_order的函数不返回任何已存在的内容有关标记并同时删除该标记,以便所有其他功能此后仍能正常触发电子邮件确认。这里的相关功能:

添加挂钩以添加用于批量修改的新选项:

/*
 * Custom bulk action in dropdown - Change status to completed without sending Confirmation Email
 */
add_filter( 'bulk_actions-edit-shop_order', 'register_bulk_action' ); // edit-shop_order is the screen ID of the orders page

function register_bulk_action( $bulk_actions ) {

    $bulk_actions['complete_with_no_email'] = 'Change status to completed (no confirmation emails)'; 
    return $bulk_actions;

}

在此处处理此新选项,请确保使用update_user_meta标记每个选定的帖子,这样我们就可以避免通过电子邮件发送

/*
 * Bulk action handler
 * admin_action_{action name}
 */
add_action( 'admin_action_complete_with_no_email', 'bulk_process_complete_no_email' );  
function bulk_process_complete_no_email() {

    // if an array with order IDs is not presented, exit the function
    if( !isset( $_REQUEST['post'] ) && !is_array( $_REQUEST['post'] ) )
        return;

    // Loop through selected posts 
    foreach( $_REQUEST['post'] as $order_id ) {

        // Use this flag later to avoid sending emails via hook woocommerce_email_recipient_customer_completed_order
        update_post_meta($order_id, 'bypass_email_confirmation', true);

        $order = new WC_Order( $order_id );
        $order_note = 'Changed Status to Completed via bulk edit (no confirmation email)';
        $order->update_status('completed', $order_note);
    }       

    // of course using add_query_arg() is not required, you can build your URL inline
    $location = add_query_arg( array(
        'post_type' => 'shop_order',
        'changed' => count( $_REQUEST['post'] ), // number of changed orders
        'ids' => join( $_REQUEST['post'], ',' ),
        'marked_fulfilled_no_emails' => 1,
        'post_status' => 'all'
    ), 'edit.php' );

    wp_redirect( admin_url( $location ) );
    exit;

}

这只是在批量操作完成后添加一个通知

/*
 * Notices for the Bulk Action 
 * This just adds the notice after action has completed
 */
add_action('admin_notices', 'custom_order_status_notices');

function custom_order_status_notices() {

    global $pagenow, $typenow;

    if( $typenow == 'shop_order' 
     && $pagenow == 'edit.php'
     && isset( $_REQUEST['marked_fulfilled_no_emails'] )
     && $_REQUEST['marked_fulfilled_no_emails'] == 1
     && isset( $_REQUEST['changed'] ) ) {

        $message = sprintf( _n( 'Order status changed.', '%s order statuses changed.', $_REQUEST['changed'] ), number_format_i18n( $_REQUEST['changed'] ) );
        echo "<div class=\"updated\"><p>{$message}</p></div>";

    }

}

最后,请在每次要发送确认电子邮件的站点上挂入钩子,并在出现此标志时阻止发送确认电子邮件。重要的是,也请在此处删除该标记,这样只有我们上面的批量操作才能阻止确认电子邮件。

/* 
* Hook into every time the site is going to email customer and stop it if the flag is present
*/
add_filter('woocommerce_email_recipient_customer_completed_order','handle_email_recipient_completed_order', 10, 2);

function handle_email_recipient_completed_order($recipient, $order) {
    //if notifications are disabled (e.g. by bulk_process_complete_no_email)
    $notifications_disabled = get_post_meta($order->get_id(), 'bypass_email_confirmation', true);
    if ($notifications_disabled) {
        update_post_meta($order->get_id(), 'bypass_email_confirmation', false);
        return '';
    } else {
        return $recipient;
    }
}

希望这对某人有帮助,我花了相当长的时间试图找到这个特定问题的答案,却找不到其他地方。