web-dev-qa-db-ja.com

注文ステータスがカスタム注文ステータスに変更されたときにWooCommerceからメールを送信する

WooCommerceのインストールでQuoteというカスタム注文ステータスを作成しました。

/* 
* Change order status on new orders depending on order contents:
*  If any product in the order is availble for quote, return 'quote' status. 
*  Otherwise the order status will be set to processing.
*/
add_filter ('woocommerce_payment_complete_order_status', 'change_status_to_quote_if_applicable', 10, 2);
function change_status_to_quote_if_applicable($order_status, $order_id) { 
    $order = new WC_Order($order_id);
    $items = $order->get_items();
    foreach ($items as $item) {
        $product = get_product($item['product_id']);
        if(product_available_for_quote($product)){
            return 'quote';
        }
    }
    return $order_status;
}

ステータス見積もりが与えられた注文を受け取るたびに、メールを受け取りたいと思います。この役立つ記事に基づいてプラグインを作成しました: http://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/

私のプラグインは基本的に記事からコピーされたもので、メールの内容を変更したばかりです。私が変更したかったのは、電子メールをトリガーするものです。

記事のプラグインにはこれがあります:

// Trigger on new paid orders
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_processing_notification',  array( $this, 'trigger' ) );

また、注文のステータスが「quote」になったときにメールがトリガーされるようにしたいと思います。これは私がしました:

// Trigger on new quote orders
add_action( 'woocommerce_order_status_pending_to_quote', array( $this, 'trigger' ) );

注文が「見積もり」ステータスになっても何も起こりません。 class-wc-order.php、特に関数update_statusを確認しました。これは、woocommerce_order_status_.$this->status._to_.$new_status->slugが実行される場所だからです。 error_logを実行して、woocommerce_order_status_pending_to_quoteアクションが存在することを確認しました。しかし、プラグインのトリガー関数は実行されません。

何か案は?さまざまなフックを試しましたが、トリガー関数を実行できないようです。

どうもありがとう!

10
Ella

カスタムフックは使えると思いますが、まずは登録が必要です。コアで検出したメールアクションをフィルタリングできるようにするために、WooThemesで保留中のプルリクエストがあります。しかし、それが受け入れられる場合/それが受け入れられるまで、これはそれが行われるべき方法です:

/**
 * Register the "woocommerce_order_status_pending_to_quote" hook which is necessary to
 * allow automatic email notifications when the order is changed to refunded.
 * 
 * @modified from http://stackoverflow.com/a/26413223/2078474 to remove anonymous function
 */
add_action( 'woocommerce_init', 'so_25353766_register_email' );
function so_25353766_register_email(){
    add_action( 'woocommerce_order_status_pending_to_quote', array( WC(), 'send_transactional_email' ), 10, 10 );
}

WooCommerce2.3.11 +のアップデート

これにより commit WooCommerceでは、メールアクションをフィルタリングできます。したがって、理論的には、次のようにアクションを電子メールトリガーとして登録できるはずです。

/**
 * Register "woocommerce_order_status_pending_to_quote" as an email trigger
 */
add_filter( 'woocommerce_email_actions', 'so_25353766_filter_actions' );
function so_25353766_filter_actions( $actions ){
    $actions[] = "woocommerce_order_status_pending_to_quote";
    return $actions;
}
7
helgatheviking

メールアクションはwoocommerce.phpinit関数で定義されていることがわかりました。

// Email Actions
$email_actions = array(
    'woocommerce_low_stock',
    'woocommerce_no_stock',
    'woocommerce_product_on_backorder',
    'woocommerce_order_status_pending_to_processing',
    'woocommerce_order_status_pending_to_completed',
    'woocommerce_order_status_pending_to_on-hold',
    'woocommerce_order_status_failed_to_processing',
    'woocommerce_order_status_failed_to_completed',
    'woocommerce_order_status_completed',
    'woocommerce_new_customer_note',
    'woocommerce_created_customer'
);

これが私のwoocommerce_order_status_pending_to_quoteアクションフックが機能しなかった理由です。

コアのwoocommerceファイルに変更を加えたくなかったので、結局woocommerce_order_status_pending_to_processing_notificationアクションを使用してトリガー関数をフックしました。また、注文が常に保留中のステータスを取得し、カスタムの「見積もり」ステータスの前に処理されるように、フィルターを変更しました。以前のソリューションでは、注文に「処理中」ではなく「見積もり」ステータスが与えられたため、それも変更する必要がありました。

add_filter ('woocommerce_order_status_pending_to_processing', 'change_status_to_quote_if_applicable', 10, 2);
function change_status_to_quote_if_applicable($order_id) { 
    $order = new WC_Order($order_id);
    $items = $order->get_items();
    foreach ($items as $item) {
        $product = get_product($item['product_id']);
        if(product_available_for_quote($product)){
            $order->update_status('quote');
        }
    }
}
4
Ella

@helgathevikingのおかげでフックができましたが、WC()-> mailer()への呼び出しも追加する必要がありました。そのため、上記のコードの一部が次のように変更されました。

if ( product_available_for_quote( $product ) ){
  $order->update_status('quote');
  // load email classes
  WC()->mailer();
  // send notification email
 do_action( 'woocommerce_order_status_pending_to_quote', $order_id );
  // no need to process any other products
  break;
 }
0
Gabriel Reguly