使用hook_form_alter按用户角色隐藏字段失效问题求助
解决Drupal hook_form_alter移除字段后仍显示的问题
我帮你梳理下这个常见的Drupal开发坑,你遇到的问题大概率是几个细节没处理对,咱们一步步来解决:
1. 最关键的:参数要按引用传递
Drupal的hook_form_alter默认是按值传递$form参数的,也就是说你在函数里修改的只是原表单数组的副本,根本没影响到实际渲染的表单!
把你的函数签名改成这样,给$form加上引用符号&:
function mymodule_form_alter(&$form, $form_state, $form_id) { // 你的原有逻辑... }
2. 确认表单ID是否正确
你写的$form_id == 'my_content_type'大概率是错的!Drupal中内容类型的添加/编辑表单ID格式是[内容类型机器名]_node_form,比如内容类型机器名是article的话,表单ID是article_node_form。可以用Devel模块的dpm($form_id)打印确认实际的表单ID。
3. 用更稳妥的字段隐藏方式替代unset
与其直接unset字段,Drupal推荐设置字段的#access属性为FALSE,这种方式会尊重表单的访问控制逻辑,不容易被后续的表单构建逻辑覆盖:
$form['field_你的字段机器名']['#access'] = FALSE;
4. 检查你的条件判断是否真的触发
可以在条件里加个调试消息,确认逻辑是否走到了隐藏字段的步骤:
if(array_key_exists(5,$user->roles) && !array_key_exists(3,$user->roles)){ drupal_set_message('角色条件触发了!'); // 测试用,上线前删掉 if(empty($form_state['field']['args'][0]->title)){ drupal_set_message('标题为空的条件触发了!'); // 测试用 $form['field_你的字段机器名']['#access'] = FALSE; } }
另外,你获取节点标题的方式$form_state['field']['args'][0]->title不太可靠,Drupal 7里正确获取当前节点的方式是$form_state['node'],改成这样更稳妥:
$node = isset($form_state['node']) ? $form_state['node'] : NULL; if ($node && empty($node->title)) { // 隐藏字段逻辑 }
修正后的完整示例代码
function mymodule_form_alter(&$form, $form_state, $form_id) { global $user; // 替换成你真实的内容类型表单ID if ($form_id == 'my_content_type_node_form') { // 检查用户角色 if (array_key_exists(5, $user->roles) && !array_key_exists(3, $user->roles)) { $node = isset($form_state['node']) ? $form_state['node'] : NULL; // 确认节点标题为空 if ($node && empty($node->title)) { // 隐藏目标字段 $form['field_你的字段机器名']['#access'] = FALSE; // 如果坚持用unset,确保参数是引用传递 // unset($form['field_你的字段机器名']); } } } }
内容的提问来源于stack exchange,提问作者Harinder Maan
相关产品推荐
相关产品推荐

