【问题标题】:WooCommerce automated regular price changes based on a static date within a custom field for simple and variable productsWooCommerce 根据自定义字段中的静态日期自动定期更改简单和可变产品的价格
【发布时间】:2023-04-10 23:25:01
【问题描述】:

我的问题基于另一个问题“Set Product sale price conditionally based on custom fields in Woocommerce”的答案(LoicTheAztecXandl)中提供的代码。虽然基础代码是基于该问题的答案,但我对其进行了进一步开发以满足稍微复杂的要求。

问题:如何根据自定义字段中的静态日期自动定期更改简单和可变产品的价格?

给出更多的解释;我正在尝试根据在自定义字段“wooct_time_start”中输入的静态日期创建自动降价到 WooCommerce 产品的正常价格。

下面的代码 sn-p 适用于简单的产品,当前设置为将价格更改为“wooct_time_start”日期/时间之前的“$remaining_days”数,但我似乎无法获得代码的后半部分使用可变产品,这就是我需要帮助的地方?

add_filter('woocommerce_product_get_price', 'conditional_product_sale_price', 20, 6);
add_filter('woocommerce_product_get_sale_price', 'conditional_product_sale_price', 20, 6);
add_filter('woocommerce_product_variation_get_price', 'conditional_product_sale_price', 20, 6);
add_filter('woocommerce_product_variation_get_sale_price', 'conditional_product_sale_price', 20, 6);
add_filter('woocommerce_variation_prices_price', 'conditional_product_sale_price', 20, 6);
add_filter('woocommerce_variation_prices_sale_price', 'conditional_product_sale_price', 20, 6);

function conditional_product_sale_price($price, $product){
    
    if($product->is_type('simple')){

        $date = get_post_meta($product->get_id(), 'wooct_time_start', true);

        if(!empty($date)){
            $date_time = (int) strtotime($date);
            $now_time = (int) strtotime("now");
            $remaining_days = floor(($date_time - $now_time) / 86400);
    
            if($remaining_days <= 30){
                $price = $remaining_days;
            }elseif($remaining_days >= 31 && $remaining_days <= 60){
                $price = $remaining_days;
            }elseif($remaining_days >= 61 && $remaining_days <= 90){
                $price = $remaining_days;
            }elseif($remaining_days >= 91 && $remaining_days <= 120){
                $price = $remaining_days;
            }elseif($remaining_days >= 121 && $remaining_days <= 150){
                $price = $remaining_days;
            }elseif($remaining_days > 150){
                $price = $remaining_days;
            }
        }
        
        return $price;
            
    }if($product->is_type('variable')){

            $children_ids = $product->get_children();
            $date = get_post_meta($product->get_id(), 'wooct_time_start', true);
            
            foreach( $children_ids as $child_id ){

                $variation = wc_get_product($child_id);
                $var_price = $variation->get_price();
                
                if(!empty($date)){
                    $date_time = (int) strtotime($date);
                    $now_time = (int) strtotime("now");
                    $remaining_days = floor(($date_time - $now_time) / 86400);
                    
                    if($remaining_days <= 30){
                        $var_price = $remaining_days;
                    }elseif($remaining_days >= 31 && $remaining_days <= 60){
                        $var_price = $remaining_days;
                    }elseif($remaining_days >= 61 && $remaining_days <= 90){
                        $var_price = $remaining_days;
                    }elseif($remaining_days >= 91 && $remaining_days <= 120){
                        $var_price = $remaining_days;
                    }elseif($remaining_days >= 121 && $remaining_days <= 150){
                        $var_price = $remaining_days;
                    }elseif($remaining_days > 150){
                        $var_price = $remaining_days;
                    }
                }
                
                return $price;
                
            }
    }   
}

我尝试了对代码的各种迭代,但没有成功:

  • 更改行的位置$date = get_post_meta($product-&gt;get_id(), 'wooct_time_start', true);
  • 将行 $var_price = $variation-&gt;get_price(); 更改为 $var_price = $product-&gt;get_price();
  • 由于存储了瞬态,我已经使用了与 woocommerce_get_variation_prices_hash 相关的代码,但我仍然不知道它与我的代码有什么直接关系,尽管在线研究了几个小时。

更新:

我已经能够使用文章“Change product prices via a hook in WooCommerce 3+”中提供的答案创建以下更新代码。

这个新代码还有一个问题 - 它似乎没有成功更新任何“变体”的价格。但是,它适用于“简单”和“可变”产品!

如果有人能够让这个新代码也与“变体”一起使用,那么这将回答这个问题。

function product_life_cycle_main_function($price, $product){

        $date = get_post_meta($product->get_id(), 'wooct_time_start', true);

        if(!empty($date)){
            $date_time = (int) strtotime($date);
            $now_time = (int) strtotime("now");
            $remaining_days = floor(($date_time - $now_time) / 86400);
    
            if($remaining_days <= 30){
                $price = $remaining_days;
            }elseif($remaining_days >= 31 && $remaining_days <= 60){
                $price = $remaining_days;
            }elseif($remaining_days >= 61 && $remaining_days <= 90){
                $price = $remaining_days;
            }elseif($remaining_days >= 91 && $remaining_days <= 120){
                $price = $remaining_days;
            }elseif($remaining_days >= 121 && $remaining_days <= 150){
                $price = $remaining_days;
            }elseif($remaining_days > 150){
                $price = $remaining_days;
            }
        }
        return $price;
}

add_filter('woocommerce_product_get_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_get_regular_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_variation_get_regular_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_variation_get_price', 'product_life_cycle_custom_price', 99, 2);
    function product_life_cycle_custom_price($price, $product) {
        return product_life_cycle_main_function($price, $product);
    }

add_filter('woocommerce_variation_prices_price', 'product_life_cycle_custom_variable_price', 99, 3);
add_filter('woocommerce_variation_prices_regular_price', 'product_life_cycle_custom_variable_price', 99, 3);
    function product_life_cycle_custom_variable_price($price, $variation, $product) {
        wc_delete_product_transients($variation->get_id());
        return product_life_cycle_main_function($price, $product);
    }

add_filter('woocommerce_get_variation_prices_hash', 'product_life_cycle_variation_prices_hash', 99, 3);
    function product_life_cycle_variation_prices_hash($price_hash, $product, $for_display) {
        $price_hash[] = product_life_cycle_main_function($price, $product);
        return $price_hash;
    }

【问题讨论】:

  • 变体是否针对它们存储了wooct_time_start 元数据,还是针对父产品存储了它?在第二种情况下,您必须致电 get_post_meta($product-&gt;get_parent_id(), 'wooct_time_start', true); 了解变化。
  • 这是第二个 - 它们存储在父级中,但是根据当时更新的价格,最终代码中需要两次迭代。我已将其全部包含在已接受的答案中。谢谢!
  • 太好了,很高兴您设法解决了这个问题。 :)

标签: php wordpress woocommerce filter variations


【解决方案1】:

我建议重写获取数据的逻辑,使其更加健壮。如果产品不是简单的、可变的或变化的,则接受的答案中描述的检查失败,但可以使其更通用。以下是如何做到这一点的示例:

function product_life_cycle_main_function($price, $product){
    // Determine the product ID to use
    // - Parent product ID for variations
    // - Product ID for all other products
    $meta_product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();

    // The above can also be simplified as follows:
    // - If the product has a parent, take the meta from the parent
    // - If the product doesn't have a parent, take the meta from the product
    //
    // This check would also work with other product types, such as bundled products, subscriptions, etc
    //$meta_product_id = ($product->get_parent_id() > 0) ? $product->get_parent_id() : $product->get_id();

    $date = get_post_meta($meta_product_id, 'wooct_time_start', true);

    // Rest of the code...

    return $price;
}

【讨论】:

  • 这是对代码的一个很好的补充。我现在已将其添加到接受的答案中。谢谢@Diego!
【解决方案2】:

使用Diego 提供的建议,我能够添加以下内容以使代码正常工作:

function product_life_cycle_main_function($price, $product){
    
    $product_id = ($product->get_parent_id() > 0) ? $product->get_parent_id() : $product->get_id();
    
    $date = get_post_meta($product_id, 'wooct_time_start', true);

        if(!empty($date)){
            $date_time = (int) strtotime($date);
            $now_time = (int) strtotime("now");
            $remaining_days = floor(($date_time - $now_time) / 86400);
    
            if($remaining_days <= 30){
                $price = $remaining_days;
            }elseif($remaining_days >= 31 && $remaining_days <= 60){
                $price = $remaining_days;
            }elseif($remaining_days >= 61 && $remaining_days <= 90){
                $price = $remaining_days;
            }elseif($remaining_days >= 91 && $remaining_days <= 120){
                $price = $remaining_days;
            }elseif($remaining_days >= 121 && $remaining_days <= 150){
                $price = $remaining_days;
            }elseif($remaining_days > 150){
                $price = $remaining_days;
            }
        }
        
        return $price;
        
}

add_filter('woocommerce_product_get_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_get_regular_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_variation_get_regular_price', 'product_life_cycle_custom_price', 99, 2);
add_filter('woocommerce_product_variation_get_price', 'product_life_cycle_custom_price', 99, 2);
    function product_life_cycle_custom_price($price, $product) {
        return product_life_cycle_main_function($price, $product);
    }

add_filter('woocommerce_variation_prices_price', 'product_life_cycle_custom_variable_price', 99, 3);
add_filter('woocommerce_variation_prices_regular_price', 'product_life_cycle_custom_variable_price', 99, 3);
    function product_life_cycle_custom_variable_price($price, $variation, $product) {
        wc_delete_product_transients($variation->get_id());
        return product_life_cycle_main_function($price, $product);
    }

add_filter('woocommerce_get_variation_prices_hash', 'product_life_cycle_variation_prices_hash', 99, 3);
    function product_life_cycle_variation_prices_hash($price_hash, $product, $for_display) {
        global $price;
        $price_hash[] = product_life_cycle_main_function($price, $product);
        return $price_hash;
    }

【讨论】:

  • 为什么要使用多个 if/elseif 条件?而在每种情况下$price = $remaining_days;。这没有意义
  • @7uc1f3r - 这是因为这里的核心问题是“更改(基于静态日期)” - 而不是“更改”。复数。出于演示目的,$price 设置为显示相同的值,是的,但是任何想要使用代码的人都可以轻松更改 - 重要的是 if/elseif 条件允许基于多个价格中断在不同的日期范围 - 如前所述 - 正是我在原始问题中所要求的。
猜你喜欢
  • 2019-04-24
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2019-04-25
  • 2021-05-06
  • 2021-04-16
  • 2019-05-09
  • 1970-01-01
相关资源
最近更新 更多