返回

WordPress自定义角色实现文章访问控制指南

php

WordPress 自定义角色与文章访问控制

在 WordPress 中,控制不同角色的用户访问不同文章是一个常见的需求。本文将探讨如何根据自定义角色和文章标签实现精细的文章访问控制。 假设您已创建自定义角色 role1role2role3,以及对应的文章标签 role1role2role3。 目标是只有拥有相应角色的用户才能查看带有对应标签的文章。

解决方案一:使用 pre_get_posts 钩子

pre_get_posts 钩子允许修改主查询,在获取文章列表之前进行筛选。 这是实现此功能最常用的方法。

function restrict_posts_by_role( $query ) {
  if ( is_admin() || ! $query->is_main_query() ) {
    return;
  }

  if ( ! is_user_logged_in() ) { 
    return;
  }

  $user = wp_get_current_user();
  $roles = $user->roles;

  if ( empty($roles) ) {
      // 处理没有角色的用户,例如禁止访问所有文章
      $query->set('post__in', array(0)); // 不显示任何文章
      return;
  }


  $allowed_post_ids = array();
  foreach( $roles as $role ) {
      $posts = get_posts( array(
          'tag' => $role,
          'fields' => 'ids',
          'posts_per_page' => -1 // 获取所有匹配的文章
      ) );

     $allowed_post_ids = array_merge($allowed_post_ids, $posts);
  }

   // 仅显示允许的文章
  if (!empty($allowed_post_ids)) {
      $query->set( 'post__in', $allowed_post_ids );
  } else {
    // 如果用户没有匹配标签的role,则不显示文章
      $query->set('post__in', array(0)); // 或者可以重定向用户到其他页面
  }
}
add_action( 'pre_get_posts', 'restrict_posts_by_role' );

操作步骤:

  1. 将以上代码添加到主题的 functions.php 文件或自定义插件中。
  2. 确保自定义角色和标签已正确创建。

原理: 这段代码首先检查是否为管理员或非主查询,如果是则不进行处理。 然后,获取当前用户的角色。 遍历用户拥有的每个角色,查找带有对应标签的文章,并将文章 ID 添加到 $allowed_post_ids 数组中。最后,使用 post__in 参数将主查询限制为仅显示这些允许的文章。 代码还考虑了未登录用户和没有角色用户的处理逻辑。

解决方案二:使用 the_posts 钩子

the_posts 钩子可以在 WordPress 获取文章列表后,对文章列表进行修改。 这提供了一个额外的处理点。

function filter_posts_by_role( $posts ) {
  if ( is_admin() || ! is_main_query() ) {
    return $posts;
  }

 if ( ! is_user_logged_in() ) { 
    return $posts; // 或根据需要修改
  }

 $user = wp_get_current_user();
  $roles = $user->roles;

  if ( empty($roles) ) {
      // 处理没有角色的用户
      return array();
  }

  $filtered_posts = array();
  foreach ( $posts as $post ) {
    $post_tags = get_the_tags( $post->ID );
    if ( $post_tags ) {
      foreach ( $post_tags as $tag ) {
          if ( in_array( $tag->name, $roles )) {
            $filtered_posts[] = $post;
            break; // 一旦找到匹配的标签,就添加到数组并跳出内循环
          }
      }
    }
  }

  return $filtered_posts;
}
add_action( 'the_posts', 'filter_posts_by_role' );

操作步骤:

  1. 将以上代码添加到主题的 functions.php 文件或自定义插件中。
  2. 确保自定义角色和标签已正确创建。

原理: the_posts 钩子接收文章列表作为参数。 代码遍历每篇文章,获取文章的标签。 如果用户的角色与文章标签匹配,则将该文章添加到 $filtered_posts 数组中。最终返回过滤后的文章列表。

安全建议:

  • 最小权限原则: 确保自定义角色仅拥有必要的权限,避免赋予过多权限。
  • 数据验证: 对用户输入和数据进行验证,防止恶意代码注入。
  • 定期更新: 保持 WordPress 版本、主题和插件的更新,以修复潜在的安全漏洞.

这两个方案都提供了一种有效的途径来根据用户角色和文章标签控制文章的访问。 选择哪个方案取决于具体需求和性能考虑。 pre_get_posts 钩子通过修改数据库查询更有效率,the_posts 钩子则在获取文章之后进行过滤,可能更灵活。