it-swarm-vi.com

Chuyển hướng biểu mẫu không hoạt động nếu 'đích' nằm trong URL

Trong một trong các biểu mẫu của mình, tôi đang cố gắng đặt $form_state['redirect'] Để biểu mẫu sẽ đi đến đích đó sau khi người dùng nhấp vào một trong các nút hành động.

Nếu tôi kiểm tra $form_state['redirect'] Cả trước và sau khi tôi thêm chuyển hướng, thì đó là NULL trước và sau chứa mảng thích hợp. Đây là cách tôi thiết lập chuyển hướng:

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

Tôi muốn duy trì đích đến từ biểu mẫu mà người dùng đang xem đến đường dẫn tiếp theo (đó là lý do tại sao tôi gọi drupal_get_destination(), trả về một mảng có 'destination' => 'some/path/here' Bên trong.

Dường như, vì đã có một đích đến trong đường dẫn của biểu mẫu hiện tại, biểu mẫu chuyển hướng đến đích đó bất kể tôi đặt gì trong trình xử lý biểu mẫu của riêng mình (xem mã ở trên). Tôi thậm chí đã thử sử dụng drupal_goto () và điều đó cũng không chuyển hướng người dùng.

19
geerlingguy

Khi một biểu mẫu được xử lý, giá trị của $form_state['redirect'] Được gửi đến drupal_goto()drupal_goto() luôn ưu tiên $_GET['destination'] tham số $path của chính nó.

Để hoàn thiện, trong Drupal 6, bạn đã hết may mắn khi không đặt tiêu đề của riêng mình vào hook_exit() :

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

Trong Drupal 7, hook_drupal_goto_alter() đã được thêm cho trường hợp sử dụng cụ thể này:

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

Một tùy chọn khác cho Drupal 7, gần với những gì bạn muốn làm, là đặt lại bộ đệm tĩnh cho drupal_get_destination() trong trình xử lý gửi của bạn sử dụng 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();
}

Vì bạn gọi drupal_get_destination() ngay sau khi đặt lại, Drupal hoàn toàn không biết về tham số đích cho phần còn lại của quá trình xây dựng trang, kể cả khi nó gọi drupal_goto().

Lưu ý: Tôi đã thay đổi mã để xác định $form_state['redirect'] Vì bạn không bao giờ muốn ghi đè lên biến: trình xử lý trình khác có thể đã xác định riêng của họ chuyển hướng. Drupal sẽ luôn sử dụng mục last trong mảng, vì vậy nếu bạn muốn foo/bar Để ghi đè tham số đích (và mọi chuyển hướng khác được xác định cho đến thời điểm đó), nó cần phải là cuối cùng.

27
user7

Cảm ơn vì điều này, nhưng vì một số lý do, nó không hoạt động khi tôi thử nó. Tôi đã gặp một lỗi nghiêm trọng - dữ liệu được gửi trong câu trả lời ví dụ ở trên không thỏa mãn các yêu cầu của drupal_goto()

Có thể là do câu trả lời này khá cũ, nhưng tôi đã có thể khiến nó hoạt động với điều này thay vào đó:

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

}

Tôi biết điều này vi phạm lưu ý này:

bạn không bao giờ muốn ghi đè lên biến: các trình xử lý trình khác có thể đã xác định các chuyển hướng riêng của chúng.

Nhưng, trong trường hợp này, bạn chắc chắn muốn ghi đè lên biến. Bạn sẽ không đặt giá trị này trừ khi bạn muốn bỏ qua các giá trị được đặt của mô-đun khác. Ngoài ra, tôi nghĩ rằng bạn phải vì cách drupal_goto() hoạt động với tham số truy vấn. Đây cũng có thể là lý do tại sao câu trả lời ban đầu đã gây ra lỗi nghiêm trọng trên trang web của tôi.

4
tmsimont