Як додати умову доступу до пункту меню?


17

Як я можу додати нові умови поверх існуючих умов, які визначають, чи відображається пункт меню? Ці умови не повинні обмежуватися налаштуваннями дозволів.

Як приклад використання випадку (не обов'язково причину цього питання): Припустимо, у мене є тип вмісту, користувачі якого можуть створювати лише один вузол. У мене є пункт меню для додавання цього типу вмісту. Але якщо користувач уже створив вузол цього типу вмісту, я хочу приховати пункт меню. Перша моя думка - запустити запит, щоб перевірити наявність вузла, створеного поточним користувачем, який має певний тип вмісту. Якщо така існує, схойте пункт меню.

Я думаю, що цей тип функціональності повинен увійти hook_menu_alter()і додати туди необхідну логіку. Але я не впевнений, як це зробити без обходу існуючих чеків, як-от перевірка наявності у користувача дозволу на створення такого типу вмісту. Чи повинен я включати цю логіку в свої умови? Або я можу додати до існуючої логіки доступу, не перезаписуючи її?


Редагувати: Деякі люди здаються зосередженими на відповіді "як я обмежую користувача у створенні одного вузла типу вмісту". Тут не в цьому питання. Питання полягає в тому, як додати спеціальні умови доступу до пункту меню.

Відповіді:


11

Що вам потрібно зробити, це додати зворотний дзвінок за допомогою гачка_menu_alter (), а потім всередині зворотного дзвінка ви просто зробите свою логіку, а потім повернете дані за допомогою початкового зворотного дзвінка.

Щоб бути впевненим, що ви не перезаписуєте жодних інших змін_ук_меню_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);
}

тож якщо я призначу нову функцію зворотного виклику доступу, чи обов'язково це перезаписує оригінальний зворотний дзвінок?
Chaulky

Так, у вас може бути лише один зворотний дзвінок доступу на пункт меню, отже, переконайтеся, що ви переходите до початкового зворотного дзвінка. Я бачив модуль, який робить щось подібне, один із важких модулів дозволів, але не можу згадати, який з них.
Розшифровка

що робить array_shift для $ args?
Чаулькі

Він виводить перший аргумент із "аргументів доступу", який ми зробили старим "зворотним дзвінком доступу". Отже, якщо старий зворотний дзвінок був "MYMODULE2_access_callback", це те, що повертається array_shift. Він також видаляє його з масиву, так що ми передаємо лише ті аргументи, яких очікує зворотний виклик.
Розшифруйте

1

У відповідь на коментарі вище, рішенням у 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
Здається, це не має нічого спільного з пунктами меню. Я ще не надто знайомий з D7, але схоже, що це характерно для створення вузлів. Питання зосереджено на пунктах меню загалом.
Chaulky

О, я бачу ... це у відповідь на мій коментар із проханням отримати більш детальну інформацію про ваше рішення D7, запропоноване у вашій відповіді, що вказує на модуль Обмеження вузла. Ще трохи поза темою, але оцінено.
Chaulky

Оскільки видимість посилань створювати мінодетип контролюється функцією node_access (), яка б викликала цей гачок у Drupal 7.
Дейв Рейд,

1

Ви шукаєте модуль API доступу до ланцюжкового меню .

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

На Drupal Stack Exchange є принаймні один приклад, як ним користуватися.


-1

Одним із варіантів було б створити нову роль, яка має дозвіл на вміст для вашого типу вмісту. Після того, як користувач створить вузол цього типу, зніміть цю роль, і він більше не зможе створити.


-1

Можливо, вам слід спробувати модуль Node Limit .

На сторінці проекту:

Модуль обмеження вузлів дозволяє адміністраторам обмежувати кількість вузлів певного типу, які можуть створювати ролі або користувачі. Наприклад, якщо на сайті є роль "Рекламодавець", яка може створювати вузли "реклами", то адміністратор ліміту вузлів може обмежувати всіх користувачів у цій ролі певним числом вузлів. Він також може обмежувати користувачів на основі кожного користувача.


Обмеження одним вузлом - лише приклад використання для додавання способу зворотного виклику доступу. Крім того, Node Limit не видаляє пункт меню, він просто не дозволяє користувачеві додати ще один вузол цього типу вмісту.
Chaulky

Це правда зараз, коли я знову переглядаю опис модуля. Якби це було на Drupal 7, це насправді було б просто, оскільки ви можете використовувати kuk_node_access ($ node, 'create', $ account), що вплине на видимість самого посилання типу вузла створення.
Дейв Рейд

Це цікаво. Я планую незабаром перейти на D7. Ви б не хотіли написати це детальніше та опублікувати відповідь?
Chaulky

Версія відповіді D7 розміщена.
Дейв Рейд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.