Когда ваш сайт засыпают спамом, на помощь приходит CAPTCHA. В данном примере вы увидите как в своих формах можно применять этот замечательный инструмент, который помогает бороться с ботами и хламом в почте или инфоблоках.
CAPTCHA в своих формах при помощи 1C-Битрикс
В формах у 1С-Битрикс капча присутствует, и включается в настройках компонента. Рассмотрим пример генерации CAPTCHA для своих веб-форм при помощи встроенных инструментов в данную CMS.
Для понимания разобьем весь процесс на 3 шага.
ШАГ I. Разбираем HTML код формы:
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");?> <?include_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/classes/general/captcha.php"); $cpt = new CCaptcha(); $captchaPass = COption::GetOptionString("main", "captcha_password", ""); if(strlen($captchaPass) <= 0) { $captchaPass = randString(10); COption::SetOptionString("main", "captcha_password", $captchaPass); } $cpt->SetCodeCrypt($captchaPass); ?> <form id="writeUs" method="post" action="/ajax/writeUs.php" class="zayavkaform js-form"> <div class="zayavwrap"> <h1>Написать нам</h1> <input name="contactmail" type="hidden" value="<?=$email?>"> <p>Контактное лицо<span>*</span></p> <input required="" name="fio" type="text" class="inptext"> <p>Номер телефона<span>*</span></p> <input required="" name="phone" type="text" class="inptext"> <p>Введите код с картинки<span>*</span></p> <input class="captchaSid" name="captcha_code" value="<?=htmlspecialchars($cpt->GetCodeCrypt());?>" type="hidden"> <table> <tr> <td><input class="inptext" required="" id="captcha_word" name="captcha_word" type="text"></td> <td><img class="captchaImg" src="/bitrix/tools/captcha.php?captcha_code=<?=htmlspecialchars($cpt->GetCodeCrypt());?>"></td> </tr> </table> <input type="submit" value="ОТПРАВИТЬ"> <div class="error-text"></div> </div> </form> <?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
В самом начале мы генерируем капчу, если всё сработало правильно, в вашей форме появится поле для ввода. Также, подключается класс для работы с капчей.
Как это выглядит:
ШАГ II. Теперь пишем js, который отвечает за отправку формы (jquery – ajax):
$('.js-form').on('submit', function(){ var $this = $(this); $.ajax({ url: $this.attr('action'), type: 'post', cache: false, data: $this.serialize(), }).done(function(data){ if (data == 'error') { $this.find('.error-text').text('Вы не правильно заполнили поля!'); } else { //$this.html('<h1>'+data+'</h1>'); parent.$.fancybox.close(); $.fancybox({ href: '#finish', closeBtn: true }); } console.log(data); }).error(function(){ console.log('There was an error'); }); return false; });
Какие в скрипте есть нюансы:
1. В action мы записываем ссылку на файл, который обрабатывает данные из формы и записывает их в админку Битрикса;
2. Выводим на месте ошибки что поля заполнены не верно в случае если это так – когда js переменная data = error;
3. При помощи плагина fancybox, мы сначала закрываем окно с нашей формой, а потом открываем окно с благодарностью, универсальное для всех форм.
Подключение jquery на сайте – обязательно.
ШАГ III. Страница для нашей формы – /ajax/writeUs.php :
<?php require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php"); if(!$APPLICATION->CaptchaCheckCode($_POST["captcha_word"], $_POST["captcha_code"])) { echo 'error'; } else { CModule::IncludeModule("iblock"); $el = new CIBlockElement; $arLoadProductArray = Array( "MODIFIED_BY" => $USER->GetID(), "IBLOCK_SECTION_ID" => false, "IBLOCK_ID" => 31, "NAME" => htmlspecialchars($_POST['fio']).' ('.htmlspecialchars($_POST['phone']).')', "PREVIEW_TEXT" => 'Контактное лицо: '.htmlspecialchars($_POST["fio"])."\r\n". 'Название организации: '.htmlspecialchars($_POST["name"])."\r\n". 'Телефон: '.htmlspecialchars($_POST["phone"])."\r\n". 'E-mail: '.htmlspecialchars($_POST["email"])."\r\n". 'Вопрос: '.htmlspecialchars($_POST["text"]), "ACTIVE" => "Y" ); $ELEMENT_ID = $el->Add($arLoadProductArray); $arEventFields = array( "EMAIL_FROM" => FORM_SENDER_EMAIL, "EMAIL_TO" => FORM_RECEIVE_EMAIL, "NAME" => htmlspecialchars($_POST["fio"]), "COMPANY_NAME" => htmlspecialchars($_POST["name"]), "PHONE" => htmlspecialchars($_POST["phone"]), "EMAIL" => htmlspecialchars($_POST["email"]), "QUESTION" => htmlspecialchars($_POST["text"]) ); CEvent::Send("SEND_FEEDBACK", "s1", $arEventFields); echo '<span class="form-success">Спасибо! Форма отправлена.</span>'; }
В самом начале мы проверяем – правильная ли у нас капча, если нет то передаем слово error и скриптом проверяем есть у нас ошибка или нет. Разбирать подробно как добавить поля в инфоблок, отправить почтовое сообщение в данной статье мы не будем (но самые любопытные смогут прочитать код и понять как это делается 🙂 ).
Пара слов о блоке с формой:
<p>Введите код с картинки<span>*</span></p> <input class="captchaSid" name="captcha_code" value="<?=htmlspecialchars($cpt->GetCodeCrypt());?>" type="hidden"> <table> <tr> <td><input class="inptext" required="" name="captcha_word" type="text"></td> <td><img class="captchaImg" src="/bitrix/tools/captcha.php?captcha_code=<?=htmlspecialchars($cpt->GetCodeCrypt());?>"></td> </tr> </table>
Как вы видите, у нас есть скрытый инпут в который мы пишем значение капчи и тег с картинкой, в которую и передается CAPTCHA ID.
Как в битриксе обновить капчу без перезагрузки страницы
В нашей форме уже есть “защита от спама”. Очень нужная вещь, обновление картинки – на случай если плохо читается, или просто не видно.
Взглянем на наш код теперь:
<div class="captcha-block"> <p>Введите код с картинки<span>*</span></p> <input class="captchaSid" name="captcha_code" value="<?=htmlspecialchars($cpt->GetCodeCrypt());?>" type="hidden"> <table> <tr> <td><input class="inptext" required="" id="captcha_word" name="captcha_word" type="text"></td> <td><img class="captchaImg" src="/bitrix/tools/captcha.php?captcha_code=<?=htmlspecialchars($cpt->GetCodeCrypt());?>"></td> </tr> </table> <a class="captcha-link reloadCaptcha" href="#">Поменять картинку</a> </div>
Как видно из кода выше, мы добавили текстовую ссылку на смену картинки. Теперь напишем скрипт, который будет менять код для родительского блока captcha-block:
<script type="text/javascript"> $(document).ready(function(){ $('.captcha-block').on('click', '.reloadCaptcha', function(){ var $parent = $(this).closest('.captcha-block'); //$parent.find('.whiteBlock').show(); $.getJSON('/ajax/reload_captcha.php', function(data) { $parent.find('.captchaImg').attr('src','/bitrix/tools/captcha.php?captcha_sid='+data); $parent.find('.captchaSid').val(data); //$parent.find('.whiteBlock').hide(); }); return false; }); }); </script>
Чуть ниже код, который отвечает за генерацию капчи, а пока что давайте разберемся что тут происходит.
1. Мы пишем что скрипт срабатывает когда загружена все элементы страницы – документ рэди;
2. Регистрируем обработчик событий по клику на ссылку с классом reloadCaptcha в блоках с классом captcha-block ;
3. Записываем объект в переменную $parent, который и является нашим родительским блоком (у каждой формы он свой, а нам надо менять только внутри того, где мы кликнули);
4. Далее мы отправляем запрос на страницу, которая находится в корне сайта, в папке /ajax/ – имя страницы вы уже поняли 🙂 ;
5. Полученный результат (data) – мы записываем и в переменную внутри тега img и в скрытый инпут, который в дальнейшем и проверяется при отправке формы.
Код для страницы /ajax/reload_captcha.php:
<?php require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php'); echo json_encode($APPLICATION->CaptchaGetCode()); ?>
Внимательный читатель догадался, показ и исчезновение блока .white-block находится в комментариях. Из кода я его убрал – в другой статье речь идет про обычный прелоадер во время выполнения запроса к серверу. Но на проекте был настолько быстрый отклик, что в прелоадере просто отпала вся необходимость, и капча генерировалась очень быстро.
Благодарю автора статьи за отличное решение, ссылка на оригинал:
https://dev.1c-bitrix.ru/community/webdev/user/61475/blog/2818/#like