Drupal 10.3.6中如何在hook_views_query_alter()中使用JOIN?
Drupal 10.3.6 视图JOIN与角色权限筛选解决方案
问题根源
你遇到的报错是因为Drupal 10已移除Sql类中的innerJoin()/leftJoin()/join()等快捷方法,同时直接调用condition()不符合当前Sql查询对象的API规范;若未在正确钩子中操作或未验证查询实例类型,也会触发未定义方法错误。
正确实现步骤
1. 使用hook_views_query_alter钩子
这是修改视图SQL查询的标准钩子,确保在查询构建完成后操作:
/** * Implements hook_views_query_alter(). */ function YOUR_MODULE_NAME_views_query_alter(ViewExecutable $view, QueryPluginBase $query) { // 仅针对/admin/content对应的默认视图(ID为'content') if ($view->id() !== 'content' || !($query instanceof \Drupal\views\Plugin\views\query\Sql)) { return; } // 1. 添加INNER JOIN关联node__field_itbs表 $query->addJoin( 'INNER', // JOIN类型:INNER/LEFT等 'node__field_itbs', // 要关联的表名 'field_itbs', // 表别名 'node_field_data.nid = field_itbs.entity_id' // JOIN条件 ); // 2. 根据用户角色获取对应的术语ID(示例逻辑) $current_user = \Drupal::currentUser(); $role_term_mapping = [ 'editor' => [1, 2, 3], // 编辑角色对应的术语ID数组 'manager' => [4, 5], // 管理员角色对应的术语ID数组 ]; $business_line_term_ids = []; foreach ($current_user->getRoles() as $role) { if (isset($role_term_mapping[$role])) { $business_line_term_ids = array_merge($business_line_term_ids, $role_term_mapping[$role]); } } $business_line_term_ids = array_unique($business_line_term_ids); // 3. 添加筛选条件 if (!empty($business_line_term_ids)) { $query->addWhere( 0, // 条件组ID,0代表AND组 'field_itbs.field_itbs_target_id', $business_line_term_ids, 'IN' ); } }
2. 关键API说明
addJoin():Drupal 10中唯一支持的JOIN方法,需明确指定JOIN类型、表名、别名和关联条件。addWhere():替代旧的condition()方法,用于向查询添加WHERE条件,支持AND/OR条件组。- 实例验证:必须确保
$query是Sql类实例,避免对非SQL视图执行无效操作。
注意事项
- 替换代码中的
YOUR_MODULE_NAME为你的自定义模块名称。 - 根据实际业务调整
role_term_mapping中的角色与术语ID对应关系。 - 若视图ID不是默认的
content,可通过视图编辑页面的「高级」选项查看正确ID。
内容的提问来源于stack exchange,提问作者NipunRathore
相关产品推荐
相关产品推荐

