如何在插件触发WordPress save_post钩子时保存ACF自定义字段数据
解决WordPress爬取插件触发save_post时保存ACF自定义字段的问题
问题说明
我有一款爬取类插件,创建文章时会触发WordPress的save_post钩子。目前通过acf/load_field钩子实现了从howtoapply字段解析数据,格式化后存入ACF字段application_email的逻辑,但存在以下问题:
- 不借助
save_post钩子时,application_email的数据无法自动存入postmeta表 - 只有打开文章编辑页面(刷新)时,无需点击更新按钮数据才会自动保存
- 需要让这段解析逻辑在爬取插件触发
save_post钩子时同步运行,确保自定义字段数据和爬取数据一同保存
解决方案
原代码依赖acf/load_field钩子(仅在字段加载时触发),无法在插件创建文章的save_post阶段执行。需要将解析逻辑迁移到save_post钩子中,直接在文章保存时处理并写入字段:
修改后的代码
// 定义Cloudflare邮箱解码函数,放在全局范围避免重复定义 function cfDecodeEmail( $encodedString ) { $k = hexdec( substr( $encodedString, 0, 2 ) ); $email = ''; for ( $i = 2; $i < strlen( $encodedString ) - 1; $i += 2 ) { $email .= chr( hexdec( substr( $encodedString, $i, 2 ) ) ^ $k ); } return $email; } // 绑定save_post钩子处理字段保存 add_action( 'save_post', 'sync_application_email_on_save', 10, 2 ); function sync_application_email_on_save( $post_id, $post ) { // 跳过自动保存、修订版本和非目标文章类型(按需调整post_type) if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) || $post->post_type !== 'post' ) { return; } // 获取howtoapply字段值 $howtoapply = get_field( 'howtoapply', $post_id ); if ( empty( $howtoapply ) ) { return; } // 解析HTML提取带data-cfemail的链接 libxml_use_internal_errors( true ); $dom = new DOMDocument(); @$dom->loadHTML( $howtoapply ); $email = ''; foreach ( $dom->getElementsByTagName( 'a' ) as $a ) { $cf_email = $a->getAttribute( 'data-cfemail' ); if ( ! empty( $cf_email ) ) { $email = cfDecodeEmail( $cf_email ); break; // 取第一个匹配的邮箱 } } // 如果解析到邮箱,更新ACF字段 if ( ! empty( $email ) ) { // 使用ACF的update_field确保字段正确同步到postmeta update_field( 'field_123456', $email, $post_id ); // 也可以直接更新postmeta(二选一即可,update_field更适配ACF) // update_post_meta( $post_id, 'application_email', $email ); } }
关键修改说明
- 钩子替换:将原
acf/load_field改为save_post钩子,确保在插件创建文章触发保存时执行 - 函数全局化:把
cfDecodeEmail函数移到回调外,避免重复定义导致的PHP错误 - 安全校验:增加自动保存、修订版本、文章类型的判断,避免不必要的执行
- 明确传参:调用
get_field和update_field时传入$post_id,确保针对当前操作的文章 - 逻辑优化:移除原代码中重复的
$dom->loadHTML调用,解析时增加data-cfemail非空判断,提升效率
注意事项
- 替换代码中的
'post'为你实际的文章类型(如自定义文章类型slug) - 确保
field_123456是application_email字段对应的ACF字段键(可在ACF字段编辑页面查看) - 如果爬取插件的
save_post触发优先级不同,可调整add_action的第三个参数(优先级数值越小越先执行)
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

