it-swarm.it

Come faccio ad aggiungere una condizione di accesso a una voce di menu?

Come posso aggiungere nuove condizioni oltre alle condizioni esistenti che determinano se una voce di menu è visibile? Queste condizioni non dovrebbero essere limitate alle impostazioni delle autorizzazioni.

Ad esempio un caso d'uso (non necessariamente il motivo di questa domanda): supponiamo di avere un tipo di contenuto di cui gli utenti sono autorizzati a creare solo un nodo. Ho una voce di menu per l'aggiunta di quel tipo di contenuto. Ma se l'utente ha già creato un nodo di quel tipo di contenuto, voglio nascondere la voce di menu. Il mio primo pensiero è quello di eseguire una query per verificare l'esistenza di un nodo creato dall'utente corrente che è del tipo di contenuto specifico. Se ne esiste uno, nasconde la voce di menu.

Penso che questo tipo di funzionalità dovrebbe andare in hook_menu_alter() e aggiungere lì la logica richiesta. Ma non sono sicuro di come farlo senza ignorare i controlli esistenti, come verificare se l'utente dispone delle autorizzazioni per creare quel tipo di contenuto. Dovrei includere quella logica nelle mie condizioni? Oppure posso aggiungere alla logica di accesso esistente senza sovrascriverla?


Modifica: alcune persone sembrano concentrate sulla risposta "come posso limitare un utente alla creazione di un nodo di un tipo di contenuto". Questa non è la domanda qui. La domanda è come aggiungere condizioni di accesso personalizzate a una voce di menu.

16
Chaulky

Quello che devi fare è aggiungere il tuo callback tramite hook_menu_alter (), e poi all'interno del tuo callback fai semplicemente la tua logica e poi restituisci i dati tramite il callback originale.

Per essere certi di non sovrascrivere altre modifiche hook_menu_alter (), è necessario passare il callback precedente al callback tramite l'argomento access.

Questo è tutto teorico, ma il codice dovrebbe andare in questo modo:

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

Stai cercando il modulo Chain Menu Access API .

L'API di accesso ai menu a catena consente al modulo di concatenare le proprie funzioni di richiamata di accesso ai menu nelle voci del router dei menu di altri moduli.

C'è almeno n esempio on Drupal Stack Exchange su come usarlo.

1
crantok

In risposta ai commenti sopra, la soluzione in D7 sarebbe quella di utilizzare:

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