Il reindirizzamento del modulo non funziona se "destinazione" è nell'URL


20

In uno dei miei moduli, sto cercando di impostare un in $form_state['redirect']modo che il modulo vada a quella destinazione dopo che l'utente ha fatto clic su uno dei pulsanti di azione.

Se controllo $form_state['redirect']sia prima che dopo aggiungo il reindirizzamento, è NULL prima e dopo contiene l'array corretto. Ecco come sto impostando il reindirizzamento:

$form_state['redirect'] = array(
  'my/custom/path/' . $nid,
  array('query' => drupal_get_destination()),
);

Voglio preservare la destinazione dal modulo che l'utente visualizza al percorso successivo (ecco perché sto chiamando drupal_get_destination(), che restituisce un array con 'destination' => 'some/path/here'dentro.

Sembra che, poiché esiste già una destinazione nel percorso del modulo corrente, il modulo reindirizza a tale destinazione, indipendentemente da ciò che ho inserito nel mio gestore di invio del modulo (vedere il codice sopra). Ho anche provato a usare drupal_goto () e neanche questo ha reindirizzato l'utente.

Risposte:


27

Quando un modulo viene elaborato, il valore di $form_state['redirect']viene inviato a drupal_goto()e drupal_goto()favorisce sempre $_GET['destination']il proprio $pathparametro.

Per completezza, in Drupal 6, sei stato un po 'sfortunato senza impostare le tue intestazioni hook_exit():

function mymodule_exit($destination = NULL) {
  $my_destination = 'foo/bar';
  header('Location: ' . url($my_destination));
  exit;
}

In Drupal 7, è hook_drupal_goto_alter()stato aggiunto per questo caso d'uso specifico:

function mymodule_drupal_goto_alter(&$path, &$options, &$http_response_code) {
  $path = 'foo/bar';
}

Un'altra opzione per Drupal 7, che è più vicina a ciò che si desidera fare, è ripristinare la cache statica drupal_get_destination() nel gestore di invio utilizzando drupal_static_reset():

function mymodule_form_submit($form, &$form_state) {
  // See note
  $form_state['redirect'][] = drupal_get_destination();
  $form_state['redirect'][] = 'foo/bar';

  unset($_GET['destination']);
  drupal_static_reset('drupal_get_destination');
  drupal_get_destination();
}

Dato che chiami drupal_get_destination()subito dopo il ripristino, Drupal è beato inconsapevolmente del parametro di destinazione per il resto della creazione della pagina, anche quando chiama drupal_goto().

Nota: ho modificato il codice per la definizione $form_state['redirect']perché non si desidera mai sovrascrivere la variabile: altri gestori di invio potrebbero aver definito i propri reindirizzamenti. Drupal userà sempre l' ultimo elemento dell'array, quindi se vuoi foo/barsovrascrivere il parametro di destinazione (e ogni altro reindirizzamento definito fino a quel punto), deve essere l'ultimo.


Spiegazione perfetta e molto buona. In realtà ho trovato un po 'di più lavorando attraverso il flusso di una forma elaborata: drupal_goto () è in definitiva la ragione per cui il mio semplice "reindirizzamento" non funzionava. Ho dovuto anche sovrascrivere $ _GET ['destinazione'].
geerlingguy,

Grazie! Questo è davvero molto chiaro.
zilverdistel,

4

Grazie per questo, ma per qualche motivo questo non ha funzionato quando l'ho provato. Ho riscontrato un errore fatale: i dati inviati nella risposta di esempio sopra non soddisfano i requisiti didrupal_goto()

Forse perché questa risposta è piuttosto vecchia, ma sono stato in grado di farlo funzionare con questo invece:

function mymodule_form_submit($form, &$form_state) {


  $form_state['redirect'] = array(
    'foo/bar', array(
      'query' => drupal_get_destination()
    )
  );

  unset($_GET['destination']);
  drupal_static_reset('drupal_get_destination');
  drupal_get_destination();

}

So che questo viola questa nota:

non si desidera mai sovrascrivere la variabile: altri gestori di invio potrebbero aver definito i propri reindirizzamenti.

Ma, in questo caso, vuoi sicuramente sovrascrivere la variabile. Non imposteresti questo valore se non volessi ignorare i valori impostati di altri moduli. Inoltre, penso che devi farlo a causa del modo in cui drupal_goto()funziona con il parametro query. Questo potrebbe anche essere il motivo per cui la risposta originale stava generando errori fatali sul mio sito.


Questa risposta mi ha aiutato a rendermi conto che in alcune circostanze, potresti voler annullare completamente $form_state['redirect']o potresti ottenere un WSOD con reindirizzamenti concorrenti.
tyler.frankenstein,

-2

imposta modulo #action

global $base_path;
$form['#action'] = $base_path . '/node/'.$form_state['node']->nid.'/mytab';

-1 Penso che chiamare drupal_goto()dentro hook_node_insert()rovinerà le cose (perché le drupal_goto()chiamate drupal_exit()impediscono il salvataggio del nuovo nodo).
Andy,

true - in un hook node_insert .. (ha modificato la risposta)
rémy l'

1
Questo non emette un reindirizzamento come richiesto da OP, ma invia il modulo a un percorso diverso.
Andy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.