为什么这可以在插件的钩子之外工作,而不是在内部?

问题描述

请帮帮我。我在这里错过了什么?

我创建了一个插件,用于创建带有订单的优惠券。通过以下内容,我想将优惠券代码附加到电子邮件中。优惠券存储在自定义 postMeta 字段 _associated_coupons 中的数组中。

现在,当我在 $associated_coupons(在 #ref2)上执行 vardump 时,它给了我 string(0)

但是当我将代码放在钩子或插件之外(非常简单,没有面向对象编程)并使用手动 order_id(在钩子内也可以使用)时,这会完美地返回一个关联优惠券 ID 的数组。

add_action( 'woocommerce_email_before_order_table','add_coupons_to_email',10,4 );
  
function add_coupons_to_email( $order,$sent_to_admin,$plain_text,$email ) {

    if ( $email->id == 'customer_completed_order' ) {

        //#ref1

        // get order ID
        $order_id = $order->get_id();

        // Check order for associated Coupons
        if ( Metadata_exists( 'post',$order_id,'_associated_coupons' ) ) {

            $associated_coupons = get_post_meta( $order_id,'_associated_coupons',true );

            // #ref2

            // Check if 
            if ( count( $associated_coupons ) > 0 ) {
                // #ref3
                // get coupon data etc.
                // echo stuff;
            }
        }
    }
}

钩子本身可以工作,我可以将内容放入电子邮件中(例如,在#ref1。只是 postMeta 无法通过,而我无法访问 #ref3。

我可能错过了一些非常基本的东西。

请帮忙!

更新

根据要求,这是插件的其余部分,一个创建带有订单的优惠券的钩子:

add_action ( 'woocommerce_order_status_completed','create_coupon',31,1 );
 
function create_coupon( $order_id ) {

    if ( ! $order_id ) return;

    // Allow code execution only once 
    if ( ! get_post_meta( $order_id,'_created_coupon_on_completion',true ) ) {

        // Get an instance of the WC_Order object
        $order = wc_get_order( $order_id );

        $code = random_bytes(8);

        $coupon_ids = array();

        // Create a coupon with the properties you need
        $data = array(
            'discount_type'              => 'percent_product',// Type: fixed_cart,percent,fixed_product,percent_product
            'coupon_amount'              => 100,// value
            'individual_use'             => 'no','product_ids'                => array(999),'exclude_product_ids'        => array(),'usage_limit'                => '1','usage_limit_per_user'       => '','limit_usage_to_x_items'     => '1','usage_count'                => '','expiry_date'                => date( 'Y-m-d',strtotime( '+3 years' ) ),// YYYY-MM-DD
            'free_shipping'              => 'no','product_categories'         => array(),'exclude_product_categories' => array(),'exclude_sale_items'         => 'no','minimum_amount'             => '','maximum_amount'             => '','customer_email'             => array(),'order_id'                   => $order_id
        );

        // Save the coupon in the database
        $coupon = array(
            'post_title' => $code,'post_content' => '','post_status' => 'publish','post_author' => 1,'post_type' => 'shop_coupon'
        );

        $new_coupon_id = wp_insert_post( $coupon );
                    
        // Write the $data values into postMeta table
        foreach ($data as $key => $value) {
            update_post_Meta( $new_coupon_id,$key,$value );
        }

        $coupon_ids[] = $new_coupon_id;

        // Coupon IDs to order
        $order->update_Meta_data( '_associated_coupons',$coupon_ids );
        
        // Flag the action as done (to avoid repetitions on reload for example)
        $order->update_Meta_data( '_created_coupon_on_completion',true );
        $order->save();
    }
}

数据库中的原始值例如:a:1:{i:0;i:12345;}

问题是否与调用钩子的优先级或顺序有关?

更新 2

按照建议,我尝试对 $order_id 进行硬编码,结果成功。

然后我尝试了另一种动态获取ID的方法

if ( $email->id == 'customer_completed_order' ) {

        $order = $email->object;

        $order_id = $order->get_id();

        var_dump($order_id);

        $associated_coupons = get_post_meta( $order_id,true );

        var_dump($associated_coupons);

这导致 int(12345) string(0) ""(12345 是正确的 order_id)

在表格中有任何内容之前,可能会发送电子邮件吗?查看get_post_meta(分别为get_postMeta)的文档:

如果元字段不存在,则结果取决于 get_Metadata_default()。认情况下,如果 $single 为真则返回一个空字符串,如果为假则返回一个空数组。

解决方法

好的,这是优先事项。将两者都设置为 10,现在可以使用了。