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

Главные вкладки

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

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

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

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

Комментарии

Аватар пользователя reMaster reMaster 19 сентября 2012 в 18:15

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

Аватар пользователя divined divined 19 сентября 2012 в 18:24

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

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

Аватар пользователя divined divined 19 сентября 2012 в 18:25

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

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

Аватар пользователя reMaster reMaster 19 сентября 2012 в 18:39

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

Аватар пользователя Orion76 Orion76 19 сентября 2012 в 20:33

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

Аватар пользователя divined divined 19 сентября 2012 в 23:12

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

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

Аватар пользователя divined divined 19 сентября 2012 в 23:13

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

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

Аватар пользователя reMaster reMaster 20 сентября 2012 в 12:26

в формах 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 одинаковый.

Аватар пользователя reMaster reMaster 27 сентября 2012 в 16:04

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

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

Аватар пользователя reMaster reMaster 27 сентября 2012 в 15:35

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

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

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

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

Аватар пользователя divined divined 27 сентября 2012 в 18:18

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

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

Аватар пользователя divined divined 28 сентября 2012 в 11:39

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

<?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), и конечно в момент сабмита абсолютно ВСЕ ФОРМЫ на странице передают ПОСТ, не важно какую из кнопок вы нажали для этого.

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

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