【问题标题】:woocommerce_update_product action – fire only once for every product updatewoocommerce_update_product 操作 – 每次产品更新仅触发一次
【发布时间】:2020-04-19 00:38:59
【问题描述】:

有哪些解决方法可以让 woocommerce_update_product 操作只触发一次?

我读到它会触发两次,因为它需要在内部保存一次以检索图像/变体保存的 ID。

但从开发人员的经验来看,我猜这真的不是最需要的。

到目前为止,我发现的唯一解决方法是直接在钩子中添加操作并删除它:

add_action('woocommerce_update_product', 'my_product_update', 10, 2);
function my_product_update($product_id, $product){
    remove_action('woocommerce_update_product');
    // We'll get here only once!
}

但是,当尝试进行批量编辑时,这会中断,从而使钩子仅针对第一个产品触发(因为它随后会被删除!)。

还有什么其他方法可以解决这个问题?

谢谢!

【问题讨论】:

  • 如何在更新的产品中添加自定义元?更新所有产品后将其删除。
  • 我如何知道何时删除自定义元数据?

标签: wordpress woocommerce hook-woocommerce


【解决方案1】:

使用global variable 在内存中执行此操作,无需数据库条目:

add_action('woocommerce_update_product', 'my_product_update', 10, 2);
function my_product_update($product_id, $product){
    global $previous_product_id;
    if ($previous_product_id === $product_id){
        // We'll get here only once (per product)!
    }
    $previous_product_id = $product_id;
}

【讨论】:

    【解决方案2】:

    我遇到了同样的问题(实际上我的钩子发射了 5 次)。我找到了解决方案 在最后一条评论的下一页上:

    “https://www.forumming.com/question/21114/unable-to-prevent-function-using-save-post-firing-twice”

    $times = did_action('woocommerce_update_product');
    if( $times === 1){
        //  Do some stuff
    }
    

    【讨论】:

      【解决方案3】:

      一个更简单的解决方案是设置一个$_POST 变量并在函数开始时检查。

      add_action( 'woocommerce_update_product', 'my_action', 10, 1 );
      function my_action(){
         if( isset($_POST['action_performed']) ){
            //Prevent running the action twice
            return;
          }
         
         // do you stuff here
      
         $_POST['action_performed'] = true;
      }
      

      【讨论】:

        【解决方案4】:

        也许使用WordPress Transient 会有所帮助。

        add_action('woocommerce_update_product', 'my_product_update', 10, 2);
        function my_product_update($product_id, $product) {
        
            $updating_product_id = 'update_product_' . $product_id;
            if ( false === ( $updating_product = get_transient( $updating_product_id ) ) ) {
                // We'll get here only once! within 2 seconds for each product id;
                // run your code here!
                set_transient( $updating_product_id , $product_id, 2 ); // change 2 seconds if not enough
            }
        }
        

        【讨论】:

        • 感谢您的回答。我唯一担心的是实际更新的速度比指定时间快。
        • 这真的会发生吗?喜欢在 2 秒内多次更新单个产品?可以,但我认为实际上不会。
        • 是的,这很好。在那里它可以,但它可能不太可能(并且可能值得忽略)。感谢您提出这个问题!
        • 您甚至可以将其设置为 1 秒...如果您将 set_transient 放在运行的最后一行,它应该可以工作...就像现在一样...
        • 是的,我做到了。关于代码的另一个问题:为什么 if 语句不只是说:if (!get_transient($updating_product))?对我来说,这似乎工作正常。
        猜你喜欢
        • 1970-01-01
        • 2017-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-03
        • 2018-09-11
        • 1970-01-01
        • 2011-08-13
        相关资源
        最近更新 更多