Избегайте действий, вызванных дважды в woocommerce_thankyou hook

Я использую приведенное ниже действие woocommerce для вызова пользовательской функции, но по какой-то причине она вызывается дважды при каждом заказе. Кто-нибудь знает, почему это может быть или как это исправить, чтобы он звонил только один раз за заказ?

add_action( 'woocommerce_thankyou', 'parent_referral_for_all', 10, 1 );

function parent_referral_for_all( $order_id ) {
  ....
}

ОБНОВИТЬ

Я думал, что действие запускается дважды, но сейчас я не уверен. Я использую это действие, чтобы добавить еще одного реферала в плагин affiliatewp, который добавляется дважды, но мое эхо "Спасибо" появляется только один раз.

Все работает так, как задумано, за исключением того, что реферал (и связанная с ним заметка о заказе) добавляются дважды.

Любая помощь будет принята с благодарностью.

Это полная функция:

function parent_referral_for_all( $order_id ) {

//Direct referral
$existing = affiliate_wp()->referrals->get_by( 'reference', $order_id );
$affiliate_id = $existing->affiliate_id;

    //Total amount
    if( ! empty( $existing->products ) ) {
        $productsarr = maybe_unserialize( maybe_unserialize( $existing->products ) );
        foreach( $productsarr as $productarr ) {
            $bigamount = $productarr['price'];
        }
    }

    //Parent amount
    $parentamount = $bigamount * .1;
    $affiliate_id = $existing->affiliate_id;
    $user_info = get_userdata( affwp_get_affiliate_user_id( $existing->affiliate_id ) );
    $parentprovider = $user_info->referral;
    //Affiliate id by username
    $userparent = get_user_by('login',$parentprovider);
    $thisid = affwp_get_affiliate_id($userparent->ID);

            $args = array(
                'amount'       => $parentamount,
                'reference'    => $order_id,
                'description'  => $existing->description,
                'campaign'     => $existing->campaign,
                'affiliate_id' => $thisid,
                'visit_id'     => $existing->visit_id,
                'products'     => $existing->products,
                'status'       => 'unpaid',
                'context'      => $existing->context
            );

    $referral_id2 = affiliate_wp()->referrals->add( $args );
    echo "Thank you!";

         if($referral_id2){
                //Add the order note
                $order = apply_filters( 'affwp_get_woocommerce_order', new WC_Order( $order_id ) );
                $order->add_order_note( sprintf( __( 'Referral #%d for %s recorded for %s', 'affiliate-wp' ), $referral_id2, $parentamount, $parentamount ) );
         }

}
add_action( 'woocommerce_thankyou', 'parent_referral_for_all', 10, 1 );

2 ответа

Решение

Чтобы избежать этого повторения, вы можете добавить собственные метаданные публикации в текущий заказ, как только ваш "другой" реферал будет добавлен в первый раз.

Итак, ваш код будет:

function parent_referral_for_all( $order_id ) {

    ## HERE goes the condition to avoid the repetition
    $referral_done = get_post_meta( $order_id, '_referral_done', true );
    if( empty($referral_done) ) {

        //Direct referral
        $existing = affiliate_wp()->referrals->get_by( 'reference', $order_id );
        $affiliate_id = $existing->affiliate_id;

        //Total amount
        if( ! empty( $existing->products ) ) {
            $productsarr = maybe_unserialize( maybe_unserialize( $existing->products ) );
            foreach( $productsarr as $productarr ) {
                $bigamount = $productarr['price'];
            }
        }

        //Parent amount
        $parentamount = $bigamount * .1;
        $affiliate_id = $existing->affiliate_id;
        $user_info = get_userdata( affwp_get_affiliate_user_id( $existing->affiliate_id ) );
        $parentprovider = $user_info->referral;
        //Affiliate id by username
        $userparent = get_user_by('login',$parentprovider);
        $thisid = affwp_get_affiliate_id($userparent->ID);

        $args = array(
            'amount'       => $parentamount,
            'reference'    => $order_id,
            'description'  => $existing->description,
            'campaign'     => $existing->campaign,
            'affiliate_id' => $thisid,
            'visit_id'     => $existing->visit_id,
            'products'     => $existing->products,
            'status'       => 'unpaid',
            'context'      => $existing->context
        );

        $referral_id2 = affiliate_wp()->referrals->add( $args );
        echo "Thank you!";

        if($referral_id2){
            //Add the order note
            $order = apply_filters( 'affwp_get_woocommerce_order', new WC_Order( $order_id ) );
            $order->add_order_note( sprintf( __( 'Referral #%d for %s recorded for %s', 'affiliate-wp' ), $referral_id2, $parentamount, $parentamount ) );

            ## HERE you Create/update your custom post meta data to avoid repetition
            update_post_meta( $order_id, '_referral_done', 'yes' )
        }
    }
}
add_action( 'woocommerce_thankyou', 'parent_referral_for_all', 10, 1 );

Я надеюсь, это поможет.

Вы можете проверить наличие_thankyou_action_doneключ post_meta вот так:

      <?php
/**
 * Allow code execution only once when the hook is fired.
 *
 * @param int $order_id The Woocommerce order ID.
 * @return void
 */
function so41284646_trigger_thankyou_once( $order_id ) {
    
    if ( ! get_post_meta( $order_id, '_thankyou_action_done', true ) ) {
        // Your code here.
    }
}
add_action( 'woocommerce_thankyou', 'so41284646_trigger_thankyou_once', 10, 1 );
Другие вопросы по тегам