it-swarm.com.de

Wie füge ich einem Menüelement eine Zugriffsbedingung hinzu?

Wie kann ich zusätzlich zu vorhandenen Bedingungen neue Bedingungen hinzufügen, die bestimmen, ob ein Menüelement sichtbar ist? Diese Bedingungen sollten nicht auf Berechtigungseinstellungen beschränkt sein.

Als Beispiel für einen Anwendungsfall (nicht unbedingt der Grund für diese Frage): Angenommen, ich habe einen Inhaltstyp, von dem Benutzer nur einen Knoten erstellen dürfen. Ich habe einen Menüpunkt zum Hinzufügen dieser Art von Inhalten. Wenn der Benutzer jedoch bereits einen Knoten dieses Inhaltstyps erstellt hat, möchte ich den Menüpunkt ausblenden. Mein erster Gedanke ist, eine Abfrage auszuführen, um zu überprüfen, ob ein vom aktuellen Benutzer erstellter Knoten vom spezifischen Inhaltstyp vorhanden ist. Wenn einer vorhanden ist, verbergen Sie den Menüpunkt.

Ich würde denken, diese Art von Funktionalität sollte in hook_menu_alter() gehen und dort die erforderliche Logik hinzufügen. Ich bin mir jedoch nicht sicher, wie ich das tun soll, ohne die vorhandenen Überprüfungen zu umgehen, z. B. zu überprüfen, ob der Benutzer über Berechtigungen zum Erstellen dieser Art von Inhalten verfügt. Müsste ich diese Logik in meinen eigenen Zustand aufnehmen? Oder kann ich die vorhandene Zugriffslogik ergänzen, ohne sie zu überschreiben?


Bearbeiten: Einige Leute scheinen sich auf die Antwort zu konzentrieren: "Wie beschränke ich einen Benutzer darauf, einen Knoten eines Inhaltstyps zu erstellen?". Das ist hier nicht die Frage. Die Frage ist, wie ich einem Menüelement benutzerdefinierte Zugriffsbedingungen hinzufügen kann.

16
Chaulky

Was Sie tun müssen, ist, Ihren Rückruf über hook_menu_alter () hinzuzufügen, und dann in Ihrem Rückruf einfach Ihre Logik zu tun und dann die Daten über den ursprünglichen Rückruf zurückzugeben.

Um sicherzugehen, dass Sie keine anderen Änderungen an hook_menu_alter () überschreiben, sollten Sie den vorherigen Rückruf über das Zugriffsargument an Ihren Rückruf übergeben.

Das ist alles theoretisch, aber der Code sollte ungefähr so ​​aussehen:

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
Decipher

Sie suchen das Modul Chain Menu Access API .

Mit der Chain Menu Access API kann Ihr Modul seine eigenen Menüzugriffs-Rückruffunktionen in die Menü-Router-Einträge anderer Module verketten.

Es gibt mindestens ein Beispiel on Drupal Stack Exchange, wie man es benutzt.

1
crantok

In Reaktion auf die obigen Kommentare würde die Lösung in D7 lauten:

/**
 * 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
Dave Reid