首页 > 解决方案 > 为什么这在插件的钩子之外起作用,但在内部不起作用?

问题描述

请帮我。我在这里想念什么?

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

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

但是当我将代码放在钩子或插件之外(这很简单,没有 OOP)并使用手动 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, '_associated_coupons', true );

        var_dump($associated_coupons);

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

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

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

标签: wordpresswoocommercehookhook-woocommercepost-meta

解决方案


好吧,这是优先事项。将两者都设置为 10,现在它可以工作了。


推荐阅读