Всем привет!
Мне необходимо сделать следующее: Чтобы после отправки формы выполнялся некий скрипт PHP.
Подскажите пожалуйста как лучше перехватить событие, слышал что можно с помощью хуков или с помощью спец. модуля который выполняет определенное действие после указанного события(слышал о таком , но забыл как называется).
Заранее спасибо!
Комментарии
Смотря что за форма. Если в ноде - то hook_nodeapi, если в комментарии, то hook_comment.
Для перехвата, к примеру, создаёте свой небольшой модуль mymodule и в нём функцию mymodule_nodeapi().
Как внутри этого хука обрабатывать события - можно посмотреть в официальной доке или гугле.
Спасибо! Моя форма создана с помощью модуля WebForm.
WebForm создаёт ноду если мне не изменяет память, поэтому пробуйте через hook_nodeapi, можно с проверкой на тип ноды (чтобы в остальных местах не срабатывало).
Спасибо!
hook_nodeapi событие save, пока отвлекся уже написали.
И тебе спасибо!
А нужен ли перехват после отправки? Если это сами решили, то может Ваша задача решается проще.
В Webform имеется при создании анкеты(опросника), специальное поле Additional Processing, которое можно загрузить PHP код, после дополнительной валидации или без неё.
Может это и решит проблему без различных дополнительных манипуляций?
Зависит от того какую задачу хочет выполнить человек после отправки формы. Мы же об этом не знаем, поэтому и подходим к данному вопросу несколько иначе :). + хранить в БД php код не самое лучшее решение (конечно без этого часто не обойтись, но если есть возможность этого избежать, то лучше этого избегать). Болезнь проще предотвратить чем лечить.
Спасибо! Т.е. Всё что мне нужно - создать поле Additional Processing и поместить туда PHP код и где-то в настройках указать чтоб оно срабатывало при отправке формы?
Так это не секрет
Это php скриптик который отправляет SMS(платный сервис) владельцу сайта, которое сообщает что была заполнена форма.
Ну вот теперь все более понятно :), тогда если у Вас подразумевается что таких форм может быть несколько + могут быть разные владельцы, то лучше конечно его не вставлять в вебформу, я бы все равно вынес этот скрипт в отдельную функцию и на событии save только вызывал бы функцию. +ы не надо при создании веб формы каждый раз создавать лишнее поле которое будет по сути дублироваться от ноды к ноде, оно вам надо?
А если она единственная, то тут как хотите можете поступать.
Спасибо! Форма привязана к продукту - это форма заказа продукта.
Продукта есть 3 типа - для каждого своя форма + все эти формы еще и дублируются т.к. сайт двуязычный.
Т.е. правильнее всего в моем случае будет такой алгоритм: Создать отдельную функцию, запихнуть в неё мой скрипт отправки смс и затем вызывать эту функцию из всех моих форм с помощью события save hook_nodeapi. Вроде так?
Нет ничего создавать не надо. Все проще: Открываете Вашу анкету (или создаете новую), затем изменить (при создании новой в открывшихся настройках), ищете Webform advanced settings и там найдете это поле, что я писал Additional Processing . Туда загрузите Ваш код, который будет выполняться при отправке. Там может быть, что угодно и необходимо.
Можно эту задачу решить и другим способом, создать скрытое поле в самой анкете, но для этого подгрузить файл расширения вида hidden dinamic и уже туда загружать PHP код.
Но мне кажется проще первый вариант для этой задачи.
А вообще тут грамотные люди пытаются помочь в вопросе перехвата события. Вы сами дали такой вопрос вот они и стараются Вам помочь именно в перехвате. Как формулируется вопрос, так и отвечают. Это закон.
Но здесь по-моему перехват не нужен. Нужно сделать отправку SMS, но это делается при отправке анкеты. Перехват нужен был бы если в настройках самой анкеты невозможно было что-либо сделать. Тогда требуется перехват и выполнение дополнительного кода. А тут все редактируется как душе угодно, тем и хорош и гибок модуль Webform
Спасибо за подробное объяснение! Теперь знаю 2 варианта как это сделать
На здоровье:)))
Тут вообще эту задачу можно решить и другими вариантами (как это возможно в Drupal), но поскольку используете модуль Webform, проще решить его силами, без напряга и не выдумывать разные сложности.
Я за решение hook_nodeapi. Оба решения будут работоспособны, но! Если у вас несколько продуктов и к каждому надо делать форму, то кол-во форм будет равно кол-ву продуктов да ещё помноженное на кол-во языков. Я правильно понял? Тоесть если продктов 10, а зыков - 2, то форм - 20. И если вам придётся что-то поменять в коде, то придётся отредактировать 20 форм, вместо одного места в модуле. Вообще есть правило: если какой-то блок код выполняется два и более раз - разумно сделать его функцией.
Решать Вам
+100500
"Золотые слова Юрий Бенедиктович, золотые слова".
Только я-бы слово "разумно" заменил на "обязательно".
Согласен. Действительно лучше сделать функцией. Но если продукта три и опыта нет, можно и так обойтись. Потом когда опыта набраться в освоении Друпала, то можно и функцией заменить.
Подскажите еще пожалуйста как в коде "выципить" данные из формы? Т.е. в форме есть поля: Контакт, мыло контакта, заказанный продукт - вот как их в код php засунуть, как-то через token?
Пробовал вот так, но что-то не хочет:
$Contact = $node->field_name[0]['value'];
$Phone = $node->field_phone[0]['value'];
На каком событии пробовали?
Точнее в какой момент вы вызываете свой скриптик в котором собираете данные для отправки смс?
Пока пробую на Additional Processing, которое в настройках вебформы. Скрипт срабатывает, смс уходит, но вот только в тело смс(в текст) не подставляются значения контакт, продукт, телефон...
Название полей я подставлл такие , которые указываются в Field Key при создании поля в WebForm, т.е. например при создании поля Phone в Field Key я указывал phone и соответственно делал так: $Phone = $node->field_phone[0]['value'], а потом уже в тело смс подставлял такую конструкцию:
<?php
$text = "New mail at mysite.com".
", prod:" . $Product .
", cont:" . $Contact .
", pho:" . $Phone .
", email:" . $Email;
?>
А в СМС приходит только: "New mail at mysite.com, prod:, cont:, pho:, email:"
Ну тогда все правильно что там пусто поскольку Вам необходимо, как и указывалось ранее делать отправку сообщения именно на hook_nodeapi событие save там объект $node уже полностью сформирован для сохранения и все переменные на своих местах, а так же проверена корректность и обязательность заполнения всех полей формы. т.е. в Вашем варианте я не исключаю возможной отправки смс даже с незаполненными полями и не отправленной формой :).
Та не, если не заполнить обязательные поля то не отправляется
Почитал API.
Что-то не могу найти событие save, вижу только 'presave', 'insert', 'update', 'delete' и 'view':
function hook_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'presave':
if ($node->nid && $node->moderate) {
// Reset votes when node is updated:
$node->score = 0;
$node->users = '';
$node->votes = 0;
}
break;
case 'insert':
case 'update':
if ($node->moderate && user_access('access submission queue')) {
drupal_set_message(t('The post is queued for approval'));
}
elseif ($node->moderate) {
drupal_set_message(t('The post is queued for approval. The editors will decide whether it should be published.'));
}
break;
case 'view':
$node->content['my_additional_field'] = array(
'#value' => theme('mymodule_my_additional_field', $additional_field),
'#weight' => 10,
);
break;
}
}
?>
Или надо в модуле WebForm искать где происходит событие Save и вешать на него hook_nodeapi() - блин совсем запутался
А свой модуль обязательно создавать?
Или как-то можно переопределить эту функцию в node.tpl.php?
Я не силен в программировании(я не волшебник - я только учусь ), но вот наваял пока такой кусок кода:
<?php
function mymodulename_hook_nodeapi (&$node) {
if ($node->nid == 'my_form_id') {
$Product = $node->field_product[0]['value'];
$Contact = $node->field_name[0]['value'];
$Phone = $node->field_phone[0]['value'];
sendSMS($Product, $Contact, $Phone);
}
}
function sendSMS($Product, $Contact, $Phone){
//MySCRIPT
}
?>
Вот тока куда это добро вставить?
<?php
function mymodulename_hook_nodeapi (&$node, $op, $a3, $a4) {
switch ($op) {
case 'presave':
if ($node->type == 'webform') {
$Product = $node->field_product[0]['value'];
$Contact = $node->field_name[0]['value'];
$Phone = $node->field_phone[0]['value'];
mymodulename_sendSMS($Product, $Contact, $Phone);
}
break;
}
}
function
mymodulename_sendSMS($Product, $Contact, $Phone){//MySCRIPT
}
?>
И это добро вставляете в файл своего модуля
mymodulename.module файл этот вместе с файлом mymodulename.info в папку mymodulename а папку в папку sites/all/modules
что писать в инфо файлах можно подсмотреть в любом модуле.
Сделал свой моуль, назвал sendsms, вот инфо файл: sendsms.info
name = SendSMS
description = Send SMS.
core = 6.x
, вод модульный: sendsms.moule
function sendsms_hook_nodeapi (&$node, $op, $a3, $a4) {
switch ($op) {
case 'presave':
if ($node->type == 'webform') {
$Product = $node->field_product[0]['value'];
$Contact = $node->field_name[0]['value'];
$Phone = $node->field_phone[0]['value'];
$Email = $node->field_email[0]['value'];
$Date = $node->field_date[0]['value'];
sendSMS($Product, $Contact, $Phone, $Email, $Date);
}
break;
}
}
function sendSMS($Product, $Contact, $Phone, $Email, $Date){
//MyScript
}
?>
Затем зашел в админку, активировал модуль.
После отправляю форму - результат - тихо..как в танке..
Во первых function sendsms_nodeapi();
во вторых В процессе диалога, вылетело из головы, что модуль вебформ возможно не создает ноду под каждую отдельно оправленную форму, а пишет данные в свои таблицы, соответственно и хук этот возможно можно приложить разве что к голове
Тогда по ходу нам необходимо перехватить событие webform_client_form_submit($form, &$form_state)
Для этого будем использовать hook_form_alter.
1. С помощью дебага вычисляем form_id оно уникально
2. На hook_form_alter подменяем значение submit на свое собственное, т.е. чтоб вызывалась функция из нашего-же модуля.
3. Собственно модуль:
<?php
function sendsms_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'то что надебажили') {
$form['submit'][] = 'mymodule_submit'; //тут не уверен на 100% надо пробовать
}
}
function
mymodule_submit($form, &$form_state) {$Product = данные из поля формы; //дебажим что и с какого элемента формы берется переменная $form_state
$Contact = данные из поля формы;
$Phone = данные из поля формы;
$Email = данные из поля формы;
$Date = данные из поля формы;
sendSMS($Product, $Contact, $Phone, $Email, $Date);
webform_client_form_submit($form, &$form_state);
}
function
sendSMS($Product, $Contact, $Phone, $Email, $Date){//MyScript
} ?>
Спасибо!
Есть один маленький промежуточный вопросик по поводу:
В C++ через Visual Studio знаю как дебажить, а вот в PHP впервые слышу.
Это как-то через dev модуль?
P.S. Кстати пробовал и sendsms_hook_nodeapi и hook_nodeapi и sendsms_nodeapi - никак не работало
Вставил эту функцию:
function sendsms_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'webform_client_form_30') {
$form['submit'][] = 'sendsms_submit';
}
начало выдавать ошибку на белом экране:
Fatal error: Cannot use string offset as an array in C:\wamp\www\ap1\includes\form.inc on line 984
Дальше не знаю что делать..
Пока добил Additional Processing, вот так вот правильно:
$Phone = $form_values['submitted_tree']['phone'];
$Email = $form_values['submitted_tree']['email'];
Таким образом СМС отправляется с нужными заполненными полями, только есть одно НО - после отправки формы вылазит WARNING такой:
* warning: implode() [function.implode]: Invalid arguments passed in /home/mysite/public_html/includes/database.inc on line 253.
* warning: array_keys() [function.array-keys]: The first argument should be an array in /home/mysite/public_html/modules/user/user.module on line 502.
* user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 query: SELECT p.perm FROM role r INNER JOIN permission p ON p.rid = r.rid WHERE r.rid IN () in /home/mysite/public_html/modules/user/user.module on line 502.
Как убрать этот ворнинг, и чего он вообще вылазит - всё же работает!!!
И что самое интересное после такой отправки формы происходит еще и LOGOUT пользователя!!!
С Warning разобрался - у меня в моей функции sendSMS были переменные USER и PASSWORD - webforms это не понравилось, наверное аналогичные поля есть в её таблице) - заменил на POLZ и PAROL и WARNING перестал появляться
Если, таки, решите вернуться к реализацию через сниппеты внутри самой вебформы, то на странице handbook webform найдете правильный синтаксис для перехвата полей вебформы и примеры.
В частности поле
$Product = $node->field_product[0]['value'];
в сниппете должно выглядеть вот так:$product = $form_values['submitted_tree']['field_product'];
Спасибо! Именно там я и нашел, смотрите на пару постов выше
А со сниппетами так и не получилось: в function sendsms_form_alter выдаеет ошибку а nodeapi не работает