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


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.