duanqianruan8448 2016-01-28 14:19
浏览 56
已采纳

会话数据在Woocommerce ajax调用中丢失

I'm working on a Woocommerce plugin that add some vars in session on "add to cart" action, and use those vars later when order is completed and for the order confirmation email.

Basically the workflow is the following:

  1. On woocommerce_add_to_cart action, set those session vars.

    add_filter('woocommerce_add_to_cart', array(&$this->wc, 'add_to_cart'), 10, 1);
    
    public function add_to_cart($cart_item_key) {
        if(!isset($_SESSION['tickets'])) {
            $_SESSION['tickets'] = array();
        }
        $_SESSION['tickets'][$cart_item_key] = array();
        foreach($_POST as $key => $value) {
            if(preg_match('#^ticket_#', $key)) {
                $_SESSION['tickets'][$cart_item_key][$key] = $value;
            }
        }
    }
    
  2. On woocommerce_email_after_order_table, use those vars to add informations into the confirmation email.

    add_action('woocommerce_email_after_order_table', array(&$this->wc, 'email_after_order_table'), 10, 1);
    
    public function email_after_order_table($order) {
        if(isset($_SESSION['tickets']) && !empty($_SESSION['tickets'])) {
            $output = '';
            foreach($_SESSION['tickets'] as $cart_item) {
                if(is_array($cart_item) && !empty($cart_item)) {
                    foreach($cart_item as $ticket_id) {
                        $ticket = get_post($ticket_id);
                        $room = get_the_term_list($ticket_id, 'product_tag');
                        $output .= $ticket->post_title . ' (' . $room . ')<br />';
                    }
                }
            }
            if(!empty($output)) {
                echo '<h4>' . __('Tickets', 'my-context') . '</h4><p>' . $output . '</p>';
            }
        }
    }
    

    Please note that this action is executed by Woocommerce on the ?wc-ajax=checkout ajax call.

  3. On woocommerce_order_status_completed or woocommerce_order_status_on-hold, update some CPT using those vars, then delete the session vars.

The problem I have is that when hooking on woocommerce_email_after_order_table $_SESSION is empty. If I look on $_COOKIE['PHPSESSID'], it is set and as the same value as in the context where those session vars are set. And if I try to query the CPT, they aren't updated yet, so the woocommerce_order_status_completed hook (which is working and have no issue accessing the session vars) isn't yet executed.

I tried using WC_Session instead of $_SESSION, it didn't changed anything (step 1 and 3 were working but not step 2).

Does anyone know why the woocommerce_email_after_order_table action isn't in the same context as woocommerce_order_status_completed? Is there any way to pass custom data in that hook?

  • 写回答

1条回答 默认 最新

  • douluoyou9876 2016-01-28 16:11
    关注

    Allright I found out what was going on by tracking the hooks execution time, and figured that the woocommerce_order_status_complete was executed slightly before the email hooks. It seems Woocommerce doesn't provide any hook in fact that is executed after all order actions have been processed.

    woocommerce_order_status_complete           0.15321100 1453995747
    woocommerce_email_after_order_table         0.40655700 1453995747
    

    So considering I was deleting the session vars on woocommerce_order_status_complete, they were of course not accessible for the email templates. Changing my email_after_order_table to use the updated CPT instead of the session vars solved the problem:

    public function email_after_order_table($order) {
        $tickets = get_posts(array(
            'post_type' => 'tickets',
            'numberposts' => -1,
            'meta_query'    => array(array(
                'key'           => 'tickets_reservation',
                'value'         => $order->id
            ))
        ));
        if($tickets) {
            $output = '';
            foreach($tickets as $ticket) {
                $room = strip_tags(get_the_term_list($ticket->ID, 'product_tag'));
                $output .= $ticket->post_title . ' (' . $room . ')<br />';
            }
            if(!empty($output)) {
                echo '<h4>' . __('Tickets', 'my-context') . '</h4><p>' . $output . '</p>';
            }
        }
    }
    

    The reason why I failed to query the CPT before was pretty trivial: I used $order->ID instead of $order->id...

    I would have like if Woocommerce provided more info about the hooks execution order.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。