WooCommerce 按到期日期和时间验证优惠券

问题描述

我正在使用 woocommerce,我想不仅通过默认的内置到期日期检查来验证优惠券,还想验证到期时间。

我为优惠券添加了一个自定义字段,允许设置到期时间。

我编写了以下代码片段以覆盖类 WC_Discounts 中的默认方法 validate_coupon_expiry_date

  class WC_My_plugin_Discounts extends WC_Discounts
  {
    // override validate_coupon_expiry_date to include expiry time:
    protected function validate_coupon_expiry_date($coupon)
    {
      $expiry_date = date('Y-m-d',$coupon->get_date_expires()->getTimestamp());
      // I add a custom field `expiry_time` in postmeta table:
      $expiry_time = $coupon->get_meta('expiry_time');

      $dateTime = new DateTime($expiry_date . $expiry_time);

      if ($coupon->get_date_expires() && apply_filters('woocommerce_coupon_validate_expiry_date',time() > $dateTime,$coupon,$this)) {
        throw new Exception(__('This coupon has expired.','woocommerce'),107);
      }

      return true;
    }
   }

然后,我尝试使用以下代码段验证优惠券:

add_filter('woocommerce_coupon_is_valid',array($this,'validate_coupon'),15,2);
function validate_coupon($valid,$coupon)
{
   $cart = WC()->cart;
   $discounts = new WC_My_plugin_Discounts($cart);

   // is_coupon_valid is a public method in class WC_Discounts; and this method will run the protected 
   // method validate_coupon_expiry_date:
   $valid = $discounts->is_coupon_valid($coupon);
   
   return $valid;
}

问题:

当我通过在前端购物车页面中应用优惠券来测试我的代码,并尝试使用调试器检查我的上述代码时,我注意到回调 validate_coupon 实际上没有运行;是不是我使用了错误的过滤器钩子,以至于没有触发任何事件?我是否写错了代码?任何人都可以就此分享任何想法吗?非常感谢。

解决方法

这可以通过更简单有效的方式实现。您可以改用以下内容:

add_filter( 'woocommerce_coupon_validate_expiry_date','filter_coupon_validate_expiry_date',10,3 );
function validate_coupon( $valid,$coupon,$discount ) {
    $expiry_date     = $coupon->get_date_expires();
    $expiry_time     = $coupon->get_meta('expiry_time'); // Coupon custom field 

    if ( $expiry_date && ! empty($expiry_time) ) {
        $timezone        = $coupon->get_date_expires()->getTimezone(); // get timezone
        $expiry_datetime = new WC_DateTime( $expiry_date->date('Y-m-d') . ' ' . $expiry_time );
        $now_datetime    = new WC_DateTime();
    
        $expiry_datetime->setTimezone( $timezone ); // set time zone
        $now_datetime->setTimezone( $timezone ); // set time zone 
        
        $valid = $now_datetime->getTimestamp() > $expiry_datetime->getTimestamp();
    }
    return $valid;   
}

代码位于活动子主题(或活动主题)的functions.php 文件中。经测试有效。

对于使用带有方法和函数的类的插件,您将替换:

add_filter( 'woocommerce_coupon_validate_expiry_date',3 );

与:

add_filter( 'woocommerce_coupon_validate_expiry_date',array($this,'filter_coupon_validate_expiry_date'),3 );

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...