为什么这在插件的钩子之外起作用,而不是在里面?

Why does this work outside a plugin's hook, but not inside?

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

我创建了一个插件,可以创建带有订单的优惠券。接下来,我想将优惠券代码附加到电子邮件中。优惠券存储在自定义后元字段 _associated_coupons.

的数组中

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

但是当我将代码放在钩子或插件之外(这非常简单,没有 OOP)并使用手册 order_id(在钩子内部也有效)时,这完美 returns 关联优惠券 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, '_associated_coupons', true );

        var_dump($associated_coupons);

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

是否可以在 table 中有任何内容之前发送电子邮件?查看get_post_meta(分别为get_postmeta)的文档:

If the meta field does not exist, the result depends on get_metadata_default(). By default, an empty string is returned if $single is true, or an empty array if it’s false.

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