Всем привет!
Все предельно просто. Нужно иметь возможность хотя бы проверки данных, веденных пользователем в форму.
Приведу пример.
Есть форма:
$form['#action'] = = 'https://secure....';
$form['some_edit'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#default_value' => 'Text',
'#size' => 60,
'#maxlength' => 128,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#validate' => array('the_function_that_needed_to_call'),
);
Так вот, чтобы хук валидации(сабмита) вызвался я так и не добился. Хотя без указанного св-ва #action все работает замечательно.
Но без #action поставленную задачу никак не решить.
Может кто нибудь из опытных объяснит в чем здесь ошибка?
Почему существует такое "разделение", в работы с #action?
Читал здесь http://drupal.org/node/282557
Читал здесь http://www.drupaler.co.uk/blog/validating-submitting-forms-other-website...
Полследняя ссылка вроде как и решает проблему, но в этой задаче, требуется одновременная передача данных постом и редирект на страницу
указанную в #action. Т.е точно так, как это делает обычная html форма.
Пожалуйса, дайте мне знать, что вы думаете по этому поводу.
Комментарии
Что, никто не сталкивался с задачей отправки параметров формы на другой сервер?
Что, никто не сталкивался с задачей отправки параметров формы на другой сервер?
Что, никто не сталкивался с задачей отправки параметров формы на другой сервер?
Перечитал несколько раз но так и не понял проблемы.
Если у Вас стоит задача отправить данные формы в другой источник, то вернее это было бы делать, на мой взгляд следующим образом
пройти типичный для друпала цикл обработки формы на текущем сайте, в хуке _submit используя например RPC отправить данные на другой.
ОК. Опишу поподробнее.
Определяем простую форму:
function my_custom_form() {
// Простой эдит на форме
$form['edit'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#required' => TRUE,
);
// Простой сабмит на форме
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
// Адрес, куда отправляем параметры формы
$form[#action] = 'https://secure....';
return $form;
}
// Функция валидации введенных данных на форме
function my_custom_form_validate($form, &$form_state) {
if($form_state['values']['edit'] == 'Чему-нибудь') {
form_set_error.....// генерируем ошибку
}
}
Теперь самое главное. Если я не описываю свойство #action, то ф - я валидации вызывается корректно. Но стоит его включить и она не вызывается, и происходит отправка данных на сервер(с переходом) без каких либо проверок. В чем пробелема ума не прилажу. Несколько абсурдная ситуация.
Обобщаю: Требуется передать параметры формы POST-запросом с "содержащимся" в нем редиректом, т.е так, как это делает обычная html форма с атрибутом action.
Что скажете?
В чём в чём... Как должна проходить валидация, если в вашем случае данные уходят на сторонний сервер СРАЗУ минуя друпал?
Используйте редирект в сабмите, а не в форме (т.к. Вы задаёте другой обработчик):
<?php
function ХХХХХХ_form_submit($form_id, &$form_state) {
// ............
$form_state['redirect'] = 'node/123';
}
?>
Если форма будет перестраиваться (POST будет чист), попробуйте добавить $form_state['rebuild'] = false; и/или добавить фиктифный параметр для хранения в форме: $form_state['storage']['dummy'] = true;
Dan, ему ж POST нужен, значит drupal_http_request() или я ошибаюсь?
RxB, да все верно. В самом первом сообщении я указывал вторую ссылку решающую почти такую задачу. С одним "но".
<?php
function my_module_newsletter_form_submit($form, &$form_state) {
// Удаленный урл, куда мы хотим отправить
$url = 'https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8';
// set our headers
$headers = array(
'Content-Type' => 'application/x-www-form-urlencoded',
);
// отправление данных
$response = drupal_http_request($url, $headers, 'POST', http_build_query($form_state['values'], '', '&'));
// если все хорошо...
if ($response->code == 200) {
drupal_set_message(t('Thank you for subscribing to our newsletter.'));
// Или генерируем косяк
} else {
drupal_set_message(t('There was a problem with your submission. Please try again later.'), 'error');
}
}
?>
Все параметры корректно отправляются на сервер, но нужен редирект на ту страницу вместе с отправляемыми данными. Здесь мы только получаем ответ от сервера.
Dan, спасибо за помощь, но думаю что так не пройдет.
Какие еще могут быть варианты?
Ну так и установите в submit, в конце, после того как отправили данные постом:
В массив $data данные, если нужно их включить в GET
<?php$form_state['redirect'] = array('http://secret-site.com/script.cgi', $data);?>
что если проверять перед рендером формы, значение form_state, если форма сабмиченая, то менять action + рисовать hidden поля, написать please wait.. и js-сом засабмитеть 2й раз ?
Я описал решение, которое у меня работало. Возможно я не понял проблему. У меня была задача - надо было при отправке формы перейти на другую страницу и поймать там POST формы. Вышеприведённый код это делал.
если речь идет о простой валидации данных перед отправкой их на удаленный сервер посредством браузера, как то:
-- ввел данные
-- нажал кнопку
-- данные провалидировались
-- ушел с данными на сайт
такая система работать не будет идеологически, потому как POST вы можете послать ТОЛЬКО из браузера (в ДАННОМ вашем желании), где данные легко могут поменять и после валидации, что сводит всю замороку с ней к нулю, то есть вы пытаетесь сделать систему, которая спросит сервер "все в порядке?", и после ответа "все в порядке" будет вольна делать что хочет. небольшая промашка в архитектуре. в данном случает drupal_http_requiest как раз-таки полностью решает задачу, потому как модифицировать запрос невозможно. как вариант - написать обертку для http_requiest и не перенаправлять на сайта, а эмулировать все это, но это такая морока...
Ух, всем спасибо за помощь.
Немного расскажу о чем вообще это все. Пишется платежный модуль(точнее уже написан). Для оплаты товаров карточками VISA и MasterCart.
Есть html-форма примерно след содержания:
...
Вот эти инпуты, это отправляемые параметры на удаленный сервер "https://secure.webpay.by". И сразу же редирект на форму оплаты.
На самом деле сами параметры проверять нет смысла, они генерируются кодом, это не ручной ввод.
Весь сыр бор из-за того, что я хотел объединить пользовательское соглашение (несколько параметров формы) с формой оплаты. Как раз параметры соглашения и нужно было проверять на валидность. Сейчас это просто на разных страницах.
bora-89@drupal.org, в итоге, получилось запустить validate с #action на удаленный сервер?
это технически не возможно, тут редирект, либо валидация через JS, либо валидация на том ресурсе, куда Вы отдали форму.
sg85, я поступил так, как в этом топике посоветовал penexe. Да, немного некрасиво, что форма дважды грузится, но валидация выполняется.
Чтобы форма дважды не грузилась, нужно делать ajax сабмит формы на свой сайт, а при успешном сабмите возвращать код, меняющий action формы на нужный и делающий нормальный сабмит на внешний сайт.
Понятно, я до этого еще не дошел, времени мало, пока без ajax.