ДВе формы регистрации на одной странице

19 сентября 2012 в 17:56
Аватар пользователя reMaster reMaster 0 19

Вызываю две формы регистрации на одной странице через drupal_get_form('user_register')

form_id естественно разный. Набор полей разный и регулируется через alter.

При submit второй формы, всегда происходит validate первой формы!
Как устранить эту проблему?

Комментарии

не очень хороший выход. Неужели никак по другому?
По каким данным идёт анализ, что именно эта форма отправила данные?

19 сентября 2012 в 18:15

Ну если вы скопировали форму то вы и скопировали ее определенные функции валидации и сабмита.
И именно в форме прописано какой колбэк вызывается для валидации и сабмита.
Что вы еще хотите проверить?

Переопределите сабмит и валидацию, просто скопировав код этих функция с ядра друпала.

19 сентября 2012 в 18:24

Иначе, как хороший выход, создайте свои формы, а не используйте готовые.

Но другие формы и существуют для того что бы их копировать и изменять под себя )))

19 сентября 2012 в 18:25

колбэк общий конечно user_register(), вопрос в другом почему туда уходят данные с первой формы, хотя submit выполняется формы с иным form_id

19 сентября 2012 в 18:39

определите для форм свой идентификатор.. например в $form_state['my_form_id']..
И при валидации и при сабмите производите действия, на основании этого идентификатора..

19 сентября 2012 в 20:33

Скорее всего нужно переписать что-то еще. Выведите массив формы и посмотрите что там еще прописано. Может где-то стоит идентификатор, по которому колбэк функция определяет что эту форму тоже нужно обрабатывать.

Например всякие там: form_build_id и т.д.

19 сентября 2012 в 23:12

Т.к. я недавно не копал этот процесс, то что именно отвечает за идентификатор в подобной ситуации подсказать не смогу.

Посмотрите функцию валидации и сабмита, может они вам подскажут.

19 сентября 2012 в 23:13

в формах form_build_id разные, но
первой формы:
<input type="hidden" value="user_register" id="edit-user-register" name="form_id">

и второй
<input type="hidden" value="user_register" id="edit-user-register-1" name="form_id">

Смущает что value одинаковый.

20 сентября 2012 в 12:26

orion76 wrote:
чтоб не гадать.. код хука form_alter, чтоли, покажите...

ну там массив то не мелкий.
какие именно элементы нужны?

27 сентября 2012 в 16:04

Как оказалась, такая проблема только с формами user_register

Вот пример примитивного кода,

 
$out = 'Первая форма: '.drupal_get_form('user_register');
$out.= 'Вторая форма: '.drupal_get_form('user_register');
return $out;

При сабмите второй формы, сабмитяться обе.

27 сентября 2012 в 15:35

Я увидел где идет опередление при сабмите и валидации.

Посмотрите form.inc там есть строка в которой отлавливаются handler'ы.
Там есть иерархия проверки от младшего к родителю. Попробуйте поменять родителя у второй формы.

27 сентября 2012 в 18:18

Вот что я нарыл:

<?php
if (!isset($form['#validate'])) {
    
// Ensure that modules can rely on #validate being set.
    
$form['#validate'] = array();
    
// Check for a handler specific to $form_id.
    
if (function_exists($form_id '_validate')) {
      
$form['#validate'][] = $form_id '_validate';
    }
    
// Otherwise check whether this is a shared form and whether there is a
    // handler for the shared $form_id.
    
elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_validate')) {
      
$form['#validate'][] = $form_state['build_info']['base_form_id'] . '_validate';
    }
  }

  if (!isset(

$form['#submit'])) {
    
// Ensure that modules can rely on #submit being set.
    
$form['#submit'] = array();
    
// Check for a handler specific to $form_id.
    
if (function_exists($form_id '_submit')) {
      
$form['#submit'][] = $form_id '_submit';
    }
    
// Otherwise check whether this is a shared form and whether there is a
    // handler for the shared $form_id.
    
elseif (isset($form_state['build_info']['base_form_id']) && function_exists($form_state['build_info']['base_form_id'] . '_submit')) {
      
$form['#submit'][] = $form_state['build_info']['base_form_id'] . '_submit';
    }
  }
?>

т.е.

Вы клонируете форму и меняете у нее $form_id, и не переопределяете функцию сабмита,
но есть параметр: "base_form_id".
Потому друпал видит родителя и присваивает туже функцию сабмита что и у родителя.

Теперь, на чем основывается сабмит:

Если мы вспомним историю программирования, то раньше мы пользовались конструкцией:

<?php
if($_POST) {
  
//тут сабмит
} else {
  
//тут сайт
}
?>

Что делает друпал.. (пока теория, в практику лезть нет времени, оставляю это вам)
Так вот, по моему мнению, друпал ставит хэндлер обработчик на загрузку страницы, отлавливает пост запрос и передает на выполнение или стандартной функции сабмита или переопределенной функции.
Причем основным условием передачи является наличие в пост запросе данных:

form_id
form_buil_id
op
...

Или чего-то из этого в отдельности. Или чего-то еще. Просто нет времени закончить анализ.

Потом, я предполагаю, друпал читает форму или из кэша или еще откуда-то.
Смотрит какие переменные там определены и ищет их в ПОСТ запросе или в состоянии формы.

А у вас две одинаковые формы, (возможно дублированные названия полей - аргумент name), и конечно в момент сабмита абсолютно ВСЕ ФОРМЫ на странице передают ПОСТ, не важно какую из кнопок вы нажали для этого.

Причем обе ваши формы вызывают одинаковые функции валидации. И если происходит запуск валидации для одной формы то хэндлер видит что и вторую форму нужно тоже обработать.

Если вам не лень, и вы не хотите переопределить функции валидации и сабмита - закончите анализ )))

28 сентября 2012 в 11:39