实现向ACF用户字段新增用户发送邮件的技术求助
问题分析与解决方案
方案1的核心问题
- 时机错误:
acf/save_post默认优先级为10,此时get_field()已经返回更新后的值,导致新旧值对比完全失效。 - 类型不匹配:ACF用户字段若设置为返回用户对象,
get_field()得到的是对象数组,而$_POST['pds_project_manager']是用户ID数组,array_diff()无法正确计算两者差异。 - 用户数据获取错误:
$newly_added_pds_project_managers里的元素是用户ID,直接取$user['user_email']会触发PHP错误,需通过ID获取完整用户对象。
方案2的核心问题
- 空判断无效:
empty('pds_project_manager')判断的是字符串本身,永远不为空,无法正确拦截无字段值的情况。 - 数组对比逻辑错误:
in_array($user_id, $project_managers)用用户ID和用户对象数组对比,永远返回false,导致所有用户都被错误加入邮件列表。 - 优先级导致重复触发:优先级5的钩子会在ACF保存前后多次触发,进而造成重复发送邮件。
正确实现代码
add_action('acf/save_post', 'send_email_to_new_project_managers', 20); function send_email_to_new_project_managers($post_id) { // 跳过自动保存和修订版本,避免无效触发 if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) { return; } // 获取更新前的旧用户ID列表(直接读取数据库原始元数据) $old_user_ids = get_post_meta($post_id, 'pds_project_manager', true); // 兼容单选/多选字段,统一转为数组格式 $old_user_ids = is_array($old_user_ids) ? $old_user_ids : ($old_user_ids ? [$old_user_ids] : []); // 获取提交的新用户ID列表 $new_user_ids = isset($_POST['pds_project_manager']) ? $_POST['pds_project_manager'] : []; $new_user_ids = is_array($new_user_ids) ? $new_user_ids : [$new_user_ids]; // 计算新增的用户ID $added_user_ids = array_diff($new_user_ids, $old_user_ids); // 遍历新增用户发送邮件 foreach ($added_user_ids as $user_id) { $user = get_userdata(intval($user_id)); if ($user && $user->user_email) { wp_mail( $user->user_email, '你已被添加至项目', '现在你可以从仪表盘访问该项目。' ); } } }
关键说明
- 钩子优先级:设置为20,确保在ACF完全保存字段值后执行,避免新旧值混淆。
- 旧值获取:直接用
get_post_meta()读取数据库原始值,确保拿到的是更新前的用户ID列表。 - 数组兼容:处理单选和多选用户字段的情况,统一转为数组格式,避免
array_diff()报错。 - 安全校验:跳过自动保存和修订版本,验证用户邮箱有效性,防止无效邮件发送。
内容的提问来源于stack exchange,提问作者Webbb
相关产品推荐
相关产品推荐

