有条件地删除 Woocommerce 中的特定购物车项目
Conditionally remove specific cart items in Woocommerce
我正在开发一个 WooCommerce 插件,用于从日历(如每周列表)中为特定日期订购食物。
订单有时间限制,您可以在14:00之前每天订购明天的订单。它在您可以订购商品的页面上运行(如果达到限制,添加到购物车按钮将不会显示),但是如果您的购物车中已经有一个商品将不可用,您可以在 14:00.
我在某处读到有一个用于此类操作的操作挂钩,所以我试图自己弄明白但卡住了。
简单介绍一下它的工作原理。当您单击添加到购物车按钮时,将在购物车中创建带有自定义元标记的项目,其中包含我需要的信息,格式如下:MenuCode-Year-WeekOfYear-DayOfWeek。
函数名是wc_minimum_order_amount
,因为里面还有一段代码,如果订单金额小于wc_notice指定数额。这部分已从以下代码中删除,因为它与问题无关,并且有效。
这是我使用的钩子和代码:
add_action('woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action('woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$cart = WC()->cart->get_cart();
foreach($cart as $item => $values) {
$co = explode('-', $values['_custom_options']);
$year = $co[1];
$week = $co[2];
$day = $co[3];
$hour = date('H');
if($year < date('Y')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week < date('W')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week == date('W') && $day < date('w')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week == date('W') && $day == date('w') && $hour >= 14) {
WC()->cart->remove_cart_item($item);
}
}
}
但它并没有像我预期的那样从购物车中移除商品。
我怎样才能让它发挥作用?
谢谢
这里我只使用了 woocommerce_before_calculate_totals
动作挂钩,应该可以在任何地方使用。
我对你的代码做了一些小改动:
add_action('woocommerce_before_calculate_totals', 'wc_minimum_order_amount', 10, 1 );
function wc_minimum_order_amount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Set here the time offset (in hours)
$hours_offset = 14;
$now_year = date('Y');
$now_year_week = date('W');
$now_day_week = date('w');
$now_hour = date('H');
foreach($cart->get_cart() as $cart_item_key => $cart_item ) {
if( isset($cart_item['_custom_options']) && ! empty($cart_item['_custom_options']) ){
$date = explode('-', $cart_item['_custom_options']);
$date_year = $date[1];
$date_year_week = $date[2];
$date_day_week = $date[3];
if( $date_year < $now_year ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE1', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week < $now_year_week ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE2', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week == $now_year_week && $date_day_week < $now_day_week ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE3', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week == $now_year_week && $date_day_week == $now_day_week && $now_hour >= $hours_offset ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE4', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
else {
$remove_cart_item = false;
wc_add_notice( __( 'CASE0', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
if($remove_cart_item) {
$cart->remove_cart_item($cart_item_key);
}
}
}
}
代码在您的活动子主题(或主题)的 function.php 文件或任何插件文件中。
我无法测试它,因为它非常具体,但这应该可以。
我正在开发一个 WooCommerce 插件,用于从日历(如每周列表)中为特定日期订购食物。
订单有时间限制,您可以在14:00之前每天订购明天的订单。它在您可以订购商品的页面上运行(如果达到限制,添加到购物车按钮将不会显示),但是如果您的购物车中已经有一个商品将不可用,您可以在 14:00.
我在某处读到有一个用于此类操作的操作挂钩,所以我试图自己弄明白但卡住了。
简单介绍一下它的工作原理。当您单击添加到购物车按钮时,将在购物车中创建带有自定义元标记的项目,其中包含我需要的信息,格式如下:MenuCode-Year-WeekOfYear-DayOfWeek。
函数名是wc_minimum_order_amount
,因为里面还有一段代码,如果订单金额小于wc_notice指定数额。这部分已从以下代码中删除,因为它与问题无关,并且有效。
这是我使用的钩子和代码:
add_action('woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action('woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
$cart = WC()->cart->get_cart();
foreach($cart as $item => $values) {
$co = explode('-', $values['_custom_options']);
$year = $co[1];
$week = $co[2];
$day = $co[3];
$hour = date('H');
if($year < date('Y')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week < date('W')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week == date('W') && $day < date('w')) {
WC()->cart->remove_cart_item($item);
}
else if($year == date('Y') && $week == date('W') && $day == date('w') && $hour >= 14) {
WC()->cart->remove_cart_item($item);
}
}
}
但它并没有像我预期的那样从购物车中移除商品。
我怎样才能让它发挥作用?
谢谢
这里我只使用了 woocommerce_before_calculate_totals
动作挂钩,应该可以在任何地方使用。
我对你的代码做了一些小改动:
add_action('woocommerce_before_calculate_totals', 'wc_minimum_order_amount', 10, 1 );
function wc_minimum_order_amount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Set here the time offset (in hours)
$hours_offset = 14;
$now_year = date('Y');
$now_year_week = date('W');
$now_day_week = date('w');
$now_hour = date('H');
foreach($cart->get_cart() as $cart_item_key => $cart_item ) {
if( isset($cart_item['_custom_options']) && ! empty($cart_item['_custom_options']) ){
$date = explode('-', $cart_item['_custom_options']);
$date_year = $date[1];
$date_year_week = $date[2];
$date_day_week = $date[3];
if( $date_year < $now_year ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE1', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week < $now_year_week ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE2', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week == $now_year_week && $date_day_week < $now_day_week ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE3', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
elseif( $date_year == $now_year && $date_year_week == $now_year_week && $date_day_week == $now_day_week && $now_hour >= $hours_offset ) {
$remove_cart_item = true;
wc_add_notice( __( 'CASE4', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
else {
$remove_cart_item = false;
wc_add_notice( __( 'CASE0', 'woocommerce' ), 'notice' ); // Just for testing (to be removed)
}
if($remove_cart_item) {
$cart->remove_cart_item($cart_item_key);
}
}
}
}
代码在您的活动子主题(或主题)的 function.php 文件或任何插件文件中。
我无法测试它,因为它非常具体,但这应该可以。