You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用acf/save_post同步自定义文章类型分类项问题排查

问题概述

我有两个自定义文章类型:

  • 产品独立设计(designs),对应专属分类法:design-library-tags(标签)、ratings(评分)
  • WooCommerce的product类型,已创建自定义分类法:ratings-products(产品评分)、product_tag(产品标签)

需求:在产品编辑页通过ACF关联字段关联designs后,保存时自动将designs的标签和评分同步到对应产品的分类法中。

调试情况:在子主题functions.php中编写了代码,通过Cookie调试发现,执行到wp_get_object_terms获取designs的ratings分类项时,后续的chris_vardump5 Cookie始终无法生成,无报错但无法遍历返回结果。因后台保存页面会刷新,无法使用echo/print_r输出调试,只能依赖Cookie排查,每次调试前会手动清除Cookie。

原代码:

//Custom ACF Save to set design themes/ratings when a relationship is established between a product and a design

// save post action
add_action('acf/save_post', 'set_design_themes_and_rating_on_save', 20);

/**
 * @param $post_id int|string
 */
function set_design_themes_and_rating_on_save($post_id) {

    // get our current post object
    $post = get_post($post_id);    
    $rating = '';
    $design_themes = array();
    
    //setcookie('chris_vardump1', 'stage 1 - '.serialize($post), time()+3600*24, '/', 'staging.burlybottomdesigns.com');

    // if post is object
    if(is_object($post)) {
        //setcookie('chris_vardump2', 'stage 2 if post object', time()+3600*24, '/', 'staging.burlybottomdesigns.com');

        // check we are on the projects custom type and post statuses are either publish or draft
        // change 'projects' post type to your post type name which has the relationship field
        if($post->post_type === 'product' && ($post->post_status === 'publish' || $post->post_status === 'draft')) {
            //setcookie('chris_vardump3', 'stage 3 post_type=product', time()+3600*24, '/', 'staging.burlybottomdesigns.com');

            // get relationship field employees
            // this example uses Post Object as the Return Format and is a multiple value
            // change get field param 'employees' to your relationship field name
            $designs = get_field('design_name');
            
            if($designs) {
                
                foreach($designs as $design) {
                    
                   setcookie('chris_vardump4', $design->ID, time()+3600*24, '/', 'staging.burlybottomdesigns.com'); 
                   
                   $rating = wp_get_object_terms($design->ID, 'ratings');
                   
                   if( empty($rating) )
                       setcookie('chris_vardump5', 'rating empty', time()+3600*24, '/', 'staging.burlybottomdesigns.com'); 
                    else if ( is_wp_error($rating) )
                       setcookie('chris_vardump5', $rating->get_error_message(), time()+3600*24, '/', 'staging.burlybottomdesigns.com'); 
                    else if( !empty($rating) && !is_wp_error($rating) )
                       setcookie('chris_vardump5', $rating->count, time()+3600*24, '/', 'staging.burlybottomdesigns.com');
                    else
                       setcookie('chris_vardump5', 'total failure', time()+3600*24, '/', 'staging.burlybottomdesigns.com');
                }
                
                
                
            }

            // remove the action
            remove_action('acf/save_post', 'acf_save_post');

        //Set the rating and product tags from the design once we manage to 
        //retrieve them
            //wp_set_object_terms($post_id, $new_rating, 'ratings-products', false);
            //wp_set_object_terms($post_id, $new_design_themes, 'product_tag', false);
            

            // re add the action
            add_action('acf/save_post', 'acf_save_post');

        }

    }

    // finally return
    return;

}
问题排查与修复方案

核心问题分析

  1. ACF字段返回值不兼容:代码默认get_field('design_name')返回Post Object数组,但如果ACF关联字段的返回格式设置为Post ID,$design会是数字ID而非对象,调用$design->ID会直接触发致命错误,导致后续代码完全无法执行,这就是chris_vardump5无法生成的根本原因。
  2. Cookie覆盖问题:如果关联多个designs,循环内的setcookie会覆盖之前的Cookie值,最终只能看到最后一个design的调试结果。
  3. 冗余的ACF动作操作:代码中remove_action和add_action完全没必要,反而可能引发未知的动作执行异常。

修复后的代码

// 关联产品与设计后,同步设计的标签和评分到产品分类法
add_action('acf/save_post', 'sync_design_taxonomies_to_product', 20);

/**
 * @param int|string $post_id
 */
function sync_design_taxonomies_to_product($post_id) {
    // 获取当前文章对象,非产品类型直接返回
    $post = get_post($post_id);
    if (!is_object($post) || $post->post_type !== 'product') {
        return;
    }

    // 仅处理发布/草稿状态的产品
    if (!in_array($post->post_status, ['publish', 'draft'])) {
        return;
    }

    // 获取ACF关联的设计,兼容Post Object和Post ID两种返回格式
    $designs = get_field('design_name');
    if (empty($designs)) {
        return;
    }

    // 统一转换为设计ID数组
    $design_ids = [];
    foreach ($designs as $design) {
        $design_ids[] = is_object($design) ? $design->ID : (int)$design;
    }

    // 收集所有设计的标签和评分(用slug避免名称重复问题)
    $all_tags = [];
    $all_ratings = [];
    foreach ($design_ids as $design_id) {
        // 获取设计的评分分类slug
        $ratings = wp_get_object_terms($design_id, 'ratings', ['fields' => 'slugs']);
        if (!is_wp_error($ratings) && !empty($ratings)) {
            $all_ratings = array_merge($all_ratings, $ratings);
        }

        // 获取设计的标签分类slug
        $tags = wp_get_object_terms($design_id, 'design-library-tags', ['fields' => 'slugs']);
        if (!is_wp_error($tags) && !empty($tags)) {
            $all_tags = array_merge($all_tags, $tags);
        }
    }

    // 去重后同步到产品对应分类法(false表示追加,true表示替换)
    if (!empty($all_ratings)) {
        wp_set_object_terms($post_id, array_unique($all_ratings), 'ratings-products', false);
    }
    if (!empty($all_tags)) {
        wp_set_object_terms($post_id, array_unique($all_tags), 'product_tag', false);
    }
}

调试优化建议

放弃Cookie调试,改用WordPress自带的error_log函数,不受页面刷新影响,调试信息更完整:

// 示例:替换Cookie的调试代码
error_log('当前处理的设计ID: ' . $design_id);
$ratings = wp_get_object_terms($design_id, 'ratings');
error_log('获取到的评分分类: ' . print_r($ratings, true));

调试信息会输出到服务器的PHP错误日志中(具体路径可咨询主机商或查看php.ini配置)。

内容的提问来源于stack exchange,提问作者atwookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:53:10