Как добавить условие доступа к пункту меню?


Как я могу добавить новые условия поверх существующих условий, которые определяют, виден ли элемент меню? Эти условия не должны ограничиваться настройками разрешений.

В качестве примера использования (не обязательно причина этого вопроса): Предположим, у меня есть тип контента, пользователям которого разрешено создавать только один узел. У меня есть пункт меню для добавления этого типа контента. Но если пользователь уже создал узел этого типа контента, я хочу скрыть пункт меню. Моя первая мысль - запустить запрос, чтобы проверить наличие узла, созданного текущим пользователем, который относится к определенному типу контента. Если таковой существует, скройте пункт меню.

Я бы подумал, что этот тип функциональности должен входить в hook_menu_alter() и добавьте туда необходимую логику. Но я не уверен, как это сделать, не обходя существующие проверки, например, проверку наличия у пользователя разрешений на создание такого типа контента. Должен ли я включать эту логику в свою собственную состояние? Или я могу добавить к существующей логике доступа, не перезаписывая ее?


Редактировать: Некоторые люди, похоже, сосредоточены на ответе "как ограничить пользователя созданием одного узла типа контента". Здесь вопрос не в этом. Вопрос в том, как добавить пользовательские условия доступа к пункту меню.

 16
Author: Chaulky, 2011-03-02

5 answers

Что вам нужно сделать, так это добавить обратный вызов через hook_menu_alter(), а затем внутри обратного вызова вы просто выполняете свою логику, а затем возвращаете данные через исходный обратный вызов.

Чтобы быть уверенным, что вы не перезаписываете никакие другие изменения hook_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);
}
 11
Author: Decipher, 2012-06-09 11:45:37

В ответ на комментарии выше, решением в 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;
}
 1
Author: Dave Reid, 2011-03-17 19:56:02

Вы ищете модуль API доступа к цепочке меню .

API доступа к меню цепочки позволяет вашему модулю подключать свои собственные функции обратного вызова доступа к меню к записям маршрутизатора меню других модулей.

Существует по крайней мере один пример на Drupal Stack Exchange о том, как его использовать.

 1
Author: crantok, 2017-04-13 12:47:02

Одним из вариантов было бы создать новую роль, у которой есть разрешение на создание контента для вашего типа контента. После того, как пользователь создаст узел такого типа, уберите эту роль, и они больше не смогут создавать.

 -1
Author: cjworden, 2011-03-02 23:09:20

Возможно, вам следует попробовать модуль Ограничение узла .

Со страницы проекта:

Модуль Ограничения узлов позволяет администраторам ограничивать количество узлов определенного типа, которые могут создавать роли или пользователи. Например, если на сайте есть роль "Рекламодатель", которая может создавать "рекламу", узлы, затем администратор ограничения узлов может ограничить всех пользователей в этой роли определенным количеством узлов. Он также может ограничивать пользователей на одного пользователя основа.

 -1
Author: Dave Reid, 2012-03-07 15:05:35