'대상'이 URL에 있으면 양식 리디렉션이 작동하지 않습니다.


20

내 양식 중 하나 $form_state['redirect']에서 사용자가 작업 버튼 중 하나를 클릭하면 양식이 해당 대상으로 이동하도록 양식 을 설정하려고 합니다.

$form_state['redirect']리디렉션을 추가하기 전후에 모두 검사 하면 올바른 배열이 포함되기 전과 후에 NULL입니다. 리디렉션을 설정하는 방법은 다음과 같습니다.

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

사용자 가보고있는 형태에서 다음 경로로 목적지를 보존하고 싶습니다 (그래서 내가 호출하는 이유 drupal_get_destination()'destination' => 'some/path/here'내부 배열을 반환합니다 .

현재 양식의 경로에 대상이 이미 있기 때문에 양식은 내 양식 제출 핸들러에 넣은 내용에 관계없이 해당 대상으로 리디렉션됩니다 (위 코드 참조). drupal_goto ()를 사용하여 시도했지만 사용자를 리디렉션하지 않았습니다.

답변:


27

양식이 처리되면의 값이 (으 $form_state['redirect'])로 전송 drupal_goto()되며 drupal_goto()항상 $_GET['destination']자체 $path매개 변수 보다 우선합니다 .

완벽을 기하기 위해 Drupal 6에서는 다음과 hook_exit()같이 헤더를 설정하지 않은 채 다소 운이 없었습니다 .

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

Drupal 7에서는 hook_drupal_goto_alter()이 특정 사용 사례에 추가되었습니다.

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

Drupal 7의 또 다른 옵션은 수행하려는 작업에 더 가까운 다음을 drupal_get_destination() 사용하여 제출 핸들러에서 정적 캐시를 재설정하는 것입니다 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();
}

drupal_get_destination()재설정 후 즉시 호출하기 때문에 Drupal은 호출 할 때를 포함하여 나머지 페이지 빌드에 대한 대상 매개 변수를 행복하게 인식하지 못합니다 drupal_goto().

참고 :$form_state['redirect'] 변수를 덮어 쓰지 않기 때문에 정의를위한 코드를 변경했습니다 . 다른 제출 핸들러는 자체 리디렉션을 정의했을 수 있습니다. Drupal은 항상 배열 의 마지막 항목을 사용 하므로 foo/bar대상 매개 변수 (및 해당 지점까지 정의 된 다른 모든 리디렉션)를 재정의 하려면 마지막 항목 이어야합니다.


완벽하고 아주 좋은 설명. drupal_goto ()는 궁극적으로 간단한 '리디렉션'이 작동하지 않는 이유입니다. $ _GET [ 'destination']도 덮어 써야했습니다.
geerlingguy 2016 년

고맙습니다! 이것은 실제로 매우 명확합니다.
zilverdistel

4

이것에 감사하지만 어떤 이유로 든 시도했을 때 이것이 작동하지 않았습니다. 치명적인 오류가 발생했습니다. 위의 예제 답변에서 전송 된 데이터가drupal_goto()

이 답변이 다소 오래 되었기 때문일 수도 있지만 대신이 작업을 수행 할 수있었습니다.

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

}

나는 이것이이 메모를 위반한다는 것을 알고 있습니다.

변수를 덮어 쓰고 싶지 않습니다. 다른 제출 핸들러가 자체 리디렉션을 정의했을 수 있습니다.

그러나이 경우 변수를 덮어 쓰려고합니다. 다른 모듈의 설정 값을 무시하지 않으면이 값을 설정하지 않습니다. 또한 drupal_goto()쿼리 매개 변수로 작동 하는 방식 때문에해야한다고 생각합니다 . 이것이 원래 답변이 내 사이트에서 치명적인 오류를 발생시킨 이유 일 수도 있습니다.


이 답변을 통해 어떤 상황에서는을 완전히 재정의 $form_state['redirect']하거나 경쟁 리디렉션이 포함 된 WSOD를 얻을 수 있음을 알 수있었습니다.
tyler.frankenstein

-2

양식 #action 설정

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

-1 전화 drupal_goto()를 걸면 hook_node_insert()문제가 해결된다고 생각합니다 ( 새로운 노드가 저장되지 못하게하는 drupal_goto()전화 때문에 drupal_exit()).
Andy

true-node_insert 훅에서 .. (답변 편집)
rémy

1
OP가 요청한대로 리디렉션을 발행하지는 않지만 양식을 다른 경로로 제출합니다.
Andy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.