如何将访问条件添加到菜单项? -- routes 领域 drupal 相关 的问题

How do I add an access condition to a menu item?


16
vote

问题

中文

如何在现有条件的顶部添加新条件,以确定菜单项是否可见?这些条件不应限于权限设置。

作为示例用例(不一定是这个问题的原因):假设我的内容类型只允许用户创建一个节点。我有一个菜单项,用于添加该类型的内容。但是,如果用户已经创建了该内容类型的节点,则我想隐藏菜单项。我的第一个想法是运行一个查询来检查是否存在由特定内容类型的当前用户创建的节点。如果存在,请隐藏菜单项。

我认为这种类型的功能应该进入 <代码> hook_menu_alter() 并在那里添加所需的逻辑。但是,如果没有绕过现有检查,我不确定如何做到这一点,例如检查用户是否具有创建该类型的内容的权限。我是否必须在自己的条件下包括该逻辑?或者我可以添加到现有的访问逻辑而不覆盖它?


编辑:有些人似乎专注于回答"如何将用户限制为创建内容类型的一个节点" 。这不是这里的问题。问题是如何将自定义访问条件添加到菜单项。

英文原文

How can I add new conditions on top of existing conditions that determine whether a menu item is visible? These conditions should not be limited to permissions settings.

As an example use case (not necessarily the reason for this question): Suppose I have a content type of which users are only allowed to create one node. I have a menu item for adding that type of content. But if the user has already created a node of that content type, I want to hide the menu item. My first thought is to run a query to check for the existence of a node created by the current user that is of the specific content type. If one exists, hide the menu item.

I would think this type of functionality should go into hook_menu_alter() and add the required logic there. But I'm not sure how to do that without bypassing the existing checks, like checking if the user has permissions to create that type of content. Would I have to include that logic within my own condition? Or can I add to the existing access logic without overwriting it?


Edit: Some people seem focused on answering "how do I limit a user to creating one node of a content type". That is not the question here. The question is how to I add custom access conditions to a menu item.

  

回答列表

11
 
vote
vote
最佳答案
 

您需要做的是通过hook_menu_alter()添加回调,然后在您的回调中,您只需执行逻辑,然后通过原始回调返回数据。

确保您不要覆盖任何其他钩子_menu_alter()更改,您应该通过访问参数将以前的回调传递给回调。

这是所有理论的,但代码应该去这样:

  MYMODULE_menu_alter(&$items) {   $items['menu']['access arguments'] = array_merge(array($items['menu']['access callback']), $item['menu']['access arguments']);   $items['menu']['access callback'] = 'MYMODULE_access_callback'; }  MYMODULE_access_callback() {   $args = func_get_args();    // Do Stuff.   if ($something == FALSE) {     return FALSE;   }    $function = array_shift($args);   return call_user_func_array($function, $args); }   
 

What you need to do is to add your callback via hook_menu_alter(), and then inside your callback you simply do your logic then return the data via the original callback.

To be certain that you don't overwrite any other hook_menu_alter() changes, you should pass the previous callback to your callback via the access argument.

This is all theoretical, but the code should go something like this:

MYMODULE_menu_alter(&$items) {   $items['menu']['access arguments'] = array_merge(array($items['menu']['access callback']), $item['menu']['access arguments']);   $items['menu']['access callback'] = 'MYMODULE_access_callback'; }  MYMODULE_access_callback() {   $args = func_get_args();    // Do Stuff.   if ($something == FALSE) {     return FALSE;   }    $function = array_shift($args);   return call_user_func_array($function, $args); } 
 
 
       
       
1
 
vote

响应上述评论,D7中的解决方案将使用:

  /**  * Implements hook_node_access().  */ function mymodule_node_access($node, $op, $account) {   $type = is_string($node) ? $node : $node->type;    if ($op == 'create' && $type == 'mynodetype' && db_query("SELECT 1 FROM {node} WHERE type = :type AND uid = :uid", array(':type' => $type, ':uid' => $account->uid))->fetchField()) {     // If the user has already created a node of a specific type, they cannot     // create any more.     return NODE_ACCESS_DENY;   }    // Otherwise do not affect any node access.   return NODE_ACCESS_IGNORE; }   
 

In response to the comments above, the solution in D7 would be to use:

/**  * Implements hook_node_access().  */ function mymodule_node_access($node, $op, $account) {   $type = is_string($node) ? $node : $node->type;    if ($op == 'create' && $type == 'mynodetype' && db_query("SELECT 1 FROM {node} WHERE type = :type AND uid = :uid", array(':type' => $type, ':uid' => $account->uid))->fetchField()) {     // If the user has already created a node of a specific type, they cannot     // create any more.     return NODE_ACCESS_DENY;   }    // Otherwise do not affect any node access.   return NODE_ACCESS_IGNORE; } 
 
 
     
     
1
 
vote

您正在寻找链菜单访问API 模块。

链菜单访问API允许模块将其自己的菜单链接到其他模块的菜单路由器条目中的回调函数。

至少有一个例子在Drupal堆栈交换如何使用它。

 

You're looking for the Chain Menu Access API module.

Chain Menu Access API allows your module to chain its own menu access callback functions into other modules' menu router entries.

There is at least one example on Drupal Stack Exchange of how to use it.

 
 
-1
 
vote

一个选项是创建一个创建内容类型内容权限的新角色。用户创建该类型的节点后,带走该角色,它们不会再创建。

 

One option would be to create a new role that has create content permission for your content type. After a user creates a node of that type, take away that role and they wont be able to create any more.

 
 
-1
 
vote

也许你应该尝试节点限制模块。

从项目页面:

节点限制模块允许管理员限制数量 角色或用户可以创建的特定类型的节点。例如, 如果网站有一个可以创建"广告" 的"广告商" 角色 节点,那么节点限制管理员可以限制所有用户 该角色对特定数量的节点。他还可以限制用户 每个用户的基础。

 

Perhaps you should try the Node Limit module.

From the project page:

The Node Limit module allows administrators to restrict the number of nodes of a specific type that roles or users may create. For example, if a site has an "Advertiser" role that can create "advertisement" nodes, then the node limit administrator can restrict all users in that role to a specific number of nodes. He may also restrict users on a per-user basis.

 
 
       
       

相关问题

1  hook_translated_menu_link_alter()认为仅在翻译的菜单链接上使用?  ( Is hook translated menu link alter thought to be used only on translated menu ) 
可以 hook_translated_menu_link_alter() 实现以简单地改变渲染之前的菜单链接? 清楚, hook_translated_menu_link() 仅针对从 hook_menu_link_alter() 已更改的菜单项调用的菜单项;如果模块使用 998876664 在呈现之前更改菜单项,则...

3  核心论坛形式下拉空  ( Core forum form dropdown empty ) 
在D6站点中,当用户进入节点/添加/论坛时,他们发现下拉"论坛" 只是显示"请选择" 但是该菜单中没有任何内容。 PHP错误日志或看门狗中没有任何内容。 我相信用户有正确的权限 - 毕竟,表单确实显示。否则(admin)的下拉列表显示了站点上的所有不同论坛,都是空的,而且没有它不能提交表单。 我已经看到了几乎所有...

4  将物品放在菜单中的多个地方  ( Putting items in multiple places in a menu ) 
我正在尝试设置一个菜单布局,它有两个链接到 /biblio ;一个在"研究人员" 下,一个"工作人员" 。这是为了方便起见,仿佛您在"工作人员" 下,"研究人员" 封闭式,"员工" 子菜单不可用于未注册的用户。我运行的问题是,虽然我可以在菜单的不同部分中有两个链接,但在查看页面时,它将始终尝试将菜单打开到其中一个。这...

2  hook_preprocess_page:“node_load()+ node_page_view()”Versus“%节点+ node_page_view()”  ( Hook preprocess page node load node page view versus node node page ) 
存在基本节点(NID"123" ),并且使用 hook_menu :注册了两个路径的模块 first/%node second 两个页面回调使用 node_page_view($node) 要显示节点的全部页面视图,除了第二个回调还使用 99887668 以获得 $node 。 因此 <div ...

7  Drupal 7中的主题_Menu_Item是什么?  ( What is the equivalent of theme menu item in drupal 7 ) 
我知道在drupal 6存在: theme_menu_item ,但在drupal 7中没有。是否有替换,以便我修改主系统菜单的输出? 实际上我想做一个菜单项的过滤器,具体取决于一些标准,我将设置在功能中。 ...

3  如何在Drupal 7中挂钩主系统菜单的主题,仅显示一些元素?  ( How to hook theme of the main system menu in drupal 7 to display only some of th ) 
我想在drupal 7中修改主系统菜单7.实际上我只想只显示菜单的某些特定元素,并在给定案例中隐藏一些其他特定元素(我将由 if if < / code>或 switch在函数中的语句)。 什么是最简单的方法?怎么做?你能给我一个例子吗? 我已经读到了使用 hook_theme 或 hook_menu 可以完成,但...

2  自定义模块的默认路由  ( Default routing of custom module ) 
我正在尝试编写我的第一个模块,我正在使用hook_menu来路由页面。该模块由多步形式和两个静态内容页面组成。 /** * Implements hook_menu(). */ function order_menu() { $items = array(); $items['order/form'...

3  如何在用户的配置文件上制作菜单_local_task仅在其配置文件上显示?  ( How to make a menu local task on a users profile only appear on their profile ) 
我使用这样的逻辑在每个用户的个人资料上放置选项卡,因此用户可以从WebApp的使用中查看分析: // maps a url to a sub-page of user's profile, url to user's Analytics-Management form $items['user/%user...

4  与分类术语的自定义路径的分类菜单  ( Taxonomy menu with custom path for taxonomy terms ) 
我正在尝试使用分类菜单模块为分类的自定义路径条款。而不是/分类/术语/ tid我想要/ proj /!tid(或最终/ proj /!term-name,但我会满足于我能得到的)。当我将"菜单路径类型" 设置为默认设置时,我有分类菜单正常工作,使其成为/分类/术语/ tid。每当我尝试使用"词汇路径" 选项时,菜单术...

3  如何为我的菜单添加额外的信息?  ( How can i add extra info to my menus ) 
我有一些在标准菜单模块中管理的菜单(Drupal 6,BTW)。我想在我编辑菜单项时添加一个复选框,以控制通过CSS的"新建" 横幅的显示(通过为打开复选框的项目添加类)。 我可以将我的复选框添加到形式,如下所示: function mymodule_form_menu_edit_item_alter(&$for...

8  使用自己的菜单自定义模块?  ( Custom module with its own menu ) 
我在编写我的第三种定制模块的过程中,这是我最大的挑战。 我知道如何使用hook_menu生成菜单项,并且根据您选择的路径确定它们在网站上显示的位置(管理菜单或主菜单等)。 我的问题是 - 如何指定一个新菜单,以便我创建的路径不会出现在"主链接" 或"导航" 中,而是在自己的"自定义模块" 菜单中? ...

1  我想修改Marinelli的下拉菜单(Drupal主题)  ( I want to modify the drop down menus for marinelli a drupal theme ) 
我在网站上有Marinelli菜单设置我是内部测试。 我想修改下拉菜单(我知道它使用jQuery),但我不知道该怎么办才能显示下拉的所有嵌套。 换句话说,而不是在Marinelli主题中拥有它 menu1 子菜单 undermenu undermenu 子菜单 undermenu 我想拥有像 co...

1  创建新节点时如何启用菜单链接?  ( How to enable menu link when creating a new node ) 
我尝试以编程方式启用菜单链接,这是我的方式: function create_menu_link() { $node = new stdClass(); $node->type = 'mytype'; node_object_prepare($node); $node->menu...

2  使用node_view()显示节点未打印本地菜单项  ( Using node view to display a node doesnt print local menu items ) 
当使用node_view()以显示节点(通过从hook_menu()调用的函数返回)缺少通常的视图/编辑选项卡。 是这个预期的行为吗? ...

3  菜单管理  ( Menu management ) 
我正在尝试在Drupal 7中为我的客户进行菜单管理。 如何使客户端可以在菜单上移动链接但无法删除顶级菜单?例如,如果顶级菜单项是"产品" ,我如何使客户端删除菜单项"产品" (甚至是节点本身),但它们可以重新排序子项? 让我们说我有一个名为"产品" 的主菜单项,并在它下面我有"手机" 。我如何使其成为其中,如果节...

4  如何隐藏主菜单项?  ( How do i hide the main menu items ) 
我有一个是某些节点的所有者的用户,每个节点都有一个主菜单中的菜单链接。用户只能看到他们拥有的节点,并且无法看到其他用户节点。 现在问题是,对于所有用户,菜单在以下图像中显示如下所示;它显示了当前用户拥有的每个节点的链接,以及当前用户不拥有的节点。 我想仅显示与登录用户拥有的节点对应的菜单项。我该怎么办? ...

5  为什么页面回调有两个参数?  ( Why does the page callback have two arguments ) 
if($page['header']['search_form']): print render($page['header']['search_form']); endif; 2 在 if($page['header']['search_form']): print render($page['he...

4  如何在我的主菜单上插入<a> </a>标记中的<span> </ span>标记  ( How do i insert a span span tag inside the a a tag on my main menu ) 
我已经问过这个问题堆栈溢出,但在这里询问它会更有意义。 我正在尝试通过在a中包装它然后在样式中进行标记之间的文本来显示。 我已将以下函数添加到我的template.php文件中,但我看不到前端的任何区别;跨度刚刚出现。 (我已经清除了我的缓存。) 我是我使用的右功能吗?我做错了什么? function my_th...

1  如何以编程方式在某些内容区域中创建和设置新的菜单块  ( How to create and set a new menu block in some content region programmatically ) 
我想创建一个以编程方式为他添加一些元素的新菜单,并将其激活它在某些内容区域中作为块。 如何以编程方式做到这一点? 我知道如何为现有菜单添加新元素,但我不知道如何创建新菜单。 ...

2  如何实现2个级别标签?  ( How do i achieve 2 level tabs ) 
drupal 6有一种简单的方法来做到这一点,但D7没有。 我在Drupal.org论坛上问了这个问题,我没有得到回答。我问太多了吗?我只想要2级选项卡主菜单,我可以完全控制链接样式。 底线,我想从主菜单中提取每个单独的链接(和子链路),单独主题。 ...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.