WordPress中post.php执行前获取文章ID的钩子及权限过滤问题
解决方案
1. 可以通过过滤 current_user_can() 实现需求
WordPress 提供的 user_has_cap 钩子是 current_user_can() 函数的底层过滤入口,能直接修改用户的权限判断结果。结合从请求中提取文章ID的逻辑,就能满足你的需求。
2. 具体实现步骤
步骤1:在load-post.php钩子中提前获取文章ID
load-post.php虽无直接参数,但访问编辑页的URL格式为wp-admin/post.php?post=ID&action=edit,可从$_GET变量中提取目标文章ID,提前存储供后续使用。
步骤2:用user_has_cap过滤权限判断
当系统检查用户编辑权限时,通过user_has_cap钩子介入,调用你的verify_provider_against_client()函数验证用户是否为该客户的合法提供者,若验证通过则赋予编辑权限。
完整代码示例
// 挂载到load-post.php钩子,提前获取并存储目标文章ID add_action('load-post.php', 'preload_client_post_info'); function preload_client_post_info() { // 仅处理你的客户数据表自定义文章类型(替换为实际slug) $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; if (!$post_id) return; $post_type = get_post_type($post_id); if ($post_type !== 'your_client_cpt') { // 替换成你的自定义文章类型标识 return; } // 将文章ID存入全局变量,供权限过滤函数调用 global $target_client_post_id; $target_client_post_id = $post_id; } // 过滤用户权限,覆盖默认编辑权限判断 add_filter('user_has_cap', 'adjust_client_post_edit_permission', 10, 3); function adjust_client_post_edit_permission($allcaps, $capabilities, $args) { global $target_client_post_id; // 仅处理编辑文章的权限检查,且是目标自定义文章类型 if ($capabilities[0] !== 'edit_post' || !$target_client_post_id) { return $allcaps; } $check_post_id = $args[2]; if ($check_post_id !== $target_client_post_id) { return $allcaps; } // 调用你的验证函数,判断用户是否有权限访问该客户数据 if (verify_provider_against_client($target_client_post_id)) { // 赋予用户编辑该文章的权限 $allcaps['edit_post'] = true; } return $allcaps; } // 你的自定义验证函数(示例逻辑,需替换为实际业务代码) function verify_provider_against_client($post_id) { $current_user_id = get_current_user_id(); // 示例:从文章元数据中获取原服务提供者ID并验证 $original_provider = get_post_meta($post_id, 'original_service_provider_id', true); return $current_user_id == $original_provider; }
3. 方案优势
load-post.php钩子触发时机早于post.php中的权限检查代码,能提前获取文章ID并完成准备工作。user_has_cap钩子直接作用于权限判断逻辑,可精准覆盖默认权限规则,避免触发wp_die()的无权限提示。
内容的提问来源于stack exchange,提问作者Elkrat
相关产品推荐
相关产品推荐

