Pengalihan Formulir tidak berfungsi jika 'tujuan' ada di URL


20

Di salah satu formulir saya, saya mencoba mengatur $form_state['redirect']agar formulir akan menuju ke tujuan itu setelah pengguna mengklik salah satu tombol tindakan.

Jika saya memeriksa $form_state['redirect']sebelum dan setelah saya menambahkan arahan ulang, itu NULL sebelum, dan setelah berisi array yang tepat. Inilah cara saya mengatur pengalihan:

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

Saya ingin mempertahankan tujuan dari bentuk yang dilihat pengguna ke jalur berikutnya (itu sebabnya saya menelepon drupal_get_destination(), yang mengembalikan array dengan 'destination' => 'some/path/here'di dalamnya.

Tampaknya, karena sudah ada tujuan di jalur formulir saat ini, formulir dialihkan ke tujuan itu tidak peduli apa yang saya masukkan ke formulir saya sendiri menyerahkan penangan (lihat kode di atas). Saya bahkan mencoba menggunakan drupal_goto () dan itu tidak mengarahkan pengguna juga.

Jawaban:


27

Ketika formulir diproses, nilai $form_state['redirect']dikirim ke drupal_goto(), dan drupal_goto()selalu $_GET['destination']lebih menyukai $pathparameternya sendiri .

Demi kelengkapan, di Drupal 6, Anda agak kurang beruntung tanpa menetapkan header Anda sendiri di hook_exit():

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

Dalam Drupal 7, hook_drupal_goto_alter()ditambahkan untuk kasus penggunaan khusus ini:

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

Opsi lain untuk Drupal 7, yang lebih dekat dengan apa yang ingin Anda lakukan, adalah untuk mereset cache statis untuk drupal_get_destination() di submit handler Anda menggunakan 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();
}

Karena Anda menelepon drupal_get_destination()segera setelah pengaturan ulang, Drupal sangat tidak menyadari parameter tujuan untuk sisa halaman, termasuk ketika panggilan drupal_goto().

Catatan: Saya mengubah kode untuk mendefinisikan $form_state['redirect']karena Anda tidak pernah ingin menimpa variabel: penangan kirim lain mungkin telah mendefinisikan pengalihan mereka sendiri. Drupal akan selalu menggunakan item terakhir dalam array, jadi jika Anda ingin foo/barmengganti parameter tujuan (dan setiap pengalihan lain yang ditetapkan hingga titik itu), itu harus menjadi yang terakhir.


Penjelasan sempurna, dan sangat bagus. Saya sebenarnya menemukan sedikit lebih banyak dengan bekerja melalui aliran formulir yang diproses - drupal_goto () pada akhirnya adalah alasan 'redirect' sederhana saya tidak berfungsi. Saya perlu menimpa $ _GET ['tujuan'] juga.
geerlingguy

Terima kasih! Ini memang sangat klarifikasi.
zilverdistel

4

Terima kasih untuk ini, tetapi untuk beberapa alasan ini tidak berhasil ketika saya mencobanya. Saya mendapat kesalahan fatal - data yang dikirim dalam contoh jawaban di atas tidak memenuhi persyaratandrupal_goto()

Mungkin karena jawaban ini agak lama, tetapi saya dapat membuatnya bekerja dengan ini sebagai gantinya:

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();

}

Saya tahu ini melanggar catatan ini:

Anda tidak pernah ingin menimpa variabel: penangan kiriman lain mungkin telah mendefinisikan pengalihan mereka sendiri.

Tapi, dalam hal ini, Anda tentu ingin menimpa variabel. Anda tidak akan menetapkan nilai ini kecuali Anda ingin mengabaikan nilai set modul lain. Juga, saya pikir Anda harus melakukannya karena cara drupal_goto()kerjanya dengan parameter kueri. Ini mungkin juga mengapa jawaban asli melemparkan kesalahan fatal di situs saya.


Jawaban ini membantu saya menyadari bahwa dalam beberapa keadaan, Anda mungkin ingin sepenuhnya menimpa $form_state['redirect'], atau Anda mungkin mendapatkan WSOD dengan pengalihan yang bersaing.
tyler.frankenstein

-2

atur formulir #action

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

-1 Saya pikir menelepon drupal_goto()di hook_node_insert()akan mengacaukan segalanya (karena drupal_goto()panggilan drupal_exit()mencegah node baru dari yang disimpan).
Andy

true - di hook node_insert .. (diedit jawabannya)
rémy

1
Ini tidak mengeluarkan redirect seperti yang diminta OP, tetapi mengirimkan formulir ke jalur yang berbeda.
Andy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.