实现WooCommerce新品15天后自动移出新品分类并保留其他分类可见
解决WooCommerce商品15天后自动从「New Arrival」分类移除的问题
需求回顾
- 商品加入「New Arrival」分类后,发布满15天自动从该分类移除
- 商品若属于其他分类,需在对应分类正常显示
- 首页「New Arrival」板块仅展示该分类下的商品
原代码问题分析
- 钩子选择错误:
woocommerce_new_product仅在商品首次创建时触发,无法覆盖手动添加到「New Arrival」分类的场景 - 逻辑偏离需求:使用
exclude-from-catalog会让商品从所有分类目录消失,不符合「仅从New Arrival隐藏」的要求 - 语法错误:存在中文引号、转义错误的引号,导致代码无法正常解析
- 定时任务管理缺失:未处理商品提前移出「New Arrival」时的任务取消逻辑
- 分类ID处理错误:直接使用字符串占位符,未替换为实际分类ID
修正后的完整代码
// 替换为你的「New Arrival」分类实际ID(可在分类编辑页URL的tag_ID参数中获取) define('NEW_ARRIVAL_CAT_ID', 123); /** * 当商品被添加到「New Arrival」分类时,创建定时移除任务 */ add_action('set_object_terms', 'schedule_remove_from_new_arrival', 10, 6); function schedule_remove_from_new_arrival($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids) { // 仅处理商品分类,且确认添加了「New Arrival」分类 if ($taxonomy !== 'product_cat' || !in_array(NEW_ARRIVAL_CAT_ID, $terms)) { return; } // 清除已存在的同名任务,避免重复创建 wp_clear_scheduled_hook('auto_remove_from_new_arrival', array($object_id)); // 15天后执行移除操作 wp_schedule_single_event(time() + 15 * DAY_IN_SECONDS, 'auto_remove_from_new_arrival', array($object_id)); } /** * 当商品被移除出「New Arrival」分类时,取消定时任务 */ add_action('delete_object_term_relationships', 'cancel_remove_from_new_arrival', 10, 3); function cancel_remove_from_new_arrival($object_id, $tt_ids, $taxonomy) { if ($taxonomy !== 'product_cat') { return; } // 检查商品是否已不在「New Arrival」分类中 $product_cats = wp_get_post_terms($object_id, 'product_cat', array('fields' => 'ids')); if (!in_array(NEW_ARRIVAL_CAT_ID, $product_cats)) { wp_clear_scheduled_hook('auto_remove_from_new_arrival', array($object_id)); } } /** * 定时任务回调:仅移除「New Arrival」分类,保留其他分类 */ add_action('auto_remove_from_new_arrival', 'auto_remove_from_new_arrival_callback'); function auto_remove_from_new_arrival_callback($product_id) { // 获取商品当前所有分类ID $current_cats = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'ids')); // 仅当商品仍在「New Arrival」分类中时执行移除 if (in_array(NEW_ARRIVAL_CAT_ID, $current_cats)) { // 过滤掉「New Arrival」分类,保留其余分类 $updated_cats = array_diff($current_cats, array(NEW_ARRIVAL_CAT_ID)); wp_set_object_terms($product_id, $updated_cats, 'product_cat'); } } /** * 兼容商品发布/更新场景:若已在「New Arrival」分类则创建定时任务 */ add_action('save_post_product', 'check_new_arrival_on_save', 10, 2); function check_new_arrival_on_save($post_id, $post) { // 跳过自动保存、草稿和修订版 if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id) || $post->post_status !== 'publish') { return; } $product_cats = wp_get_post_terms($post_id, 'product_cat', array('fields' => 'ids')); if (in_array(NEW_ARRIVAL_CAT_ID, $product_cats)) { // 重置定时任务,以当前保存时间为起点计算15天 wp_clear_scheduled_hook('auto_remove_from_new_arrival', array($post_id)); wp_schedule_single_event(time() + 15 * DAY_IN_SECONDS, 'auto_remove_from_new_arrival', array($post_id)); } }
代码关键说明
- 常量管理:将分类ID定义为常量,方便后续修改维护
- 全场景覆盖:使用
set_object_terms和delete_object_term_relationships监听分类添加/移除事件,覆盖手动添加、批量编辑等所有场景 - 定时任务管控:添加分类时创建任务,移除分类时取消任务,避免无效任务堆积
- 精准逻辑实现:仅移除「New Arrival」分类,完全保留商品的其他分类关联,符合需求
- 兼容保存场景:处理商品发布/更新时的分类状态,确保定时任务以最新时间为起点计算
注意事项
- 必须替换
NEW_ARRIVAL_CAT_ID为你的「New Arrival」分类实际数字ID - 确保WordPress的WP Cron正常运行,若站点禁用WP Cron,需配置服务器定时任务触发
wp-cron.php - 测试时可将
15 * DAY_IN_SECONDS改为60(1分钟),快速验证定时任务是否生效
内容的提问来源于stack exchange,提问作者AJAY PATIDAR
相关产品推荐
相关产品推荐

