RadicalForm для Joomla – профессиональная AJAX-форма обратной связи для Joomla с антиспамом

Плагин распространяется по принципу «как есть». Поддержка оказывается индивидуально по запросам и может быть бесплатной или платной в зависимости от задачи. Предложения по развитию можно обсудить в чатах Telegram или MAX.

Системные требования
-
Минимальная версия PHP8.2
-
Минимальная версия Joomla5.2
История изменений
Что умеет плагин
- Бесплатный системный плагин для Joomla, не требующий jQuery.
- Работает с обычной HTML-разметкой, конструкторами страниц, интернет-магазинами и модальными окнами.
- Отправляет формы через AJAX; количество форм на странице не ограничено.
- Поддерживает HTML5-валидацию, обязательные поля, checkbox и select multiple.
- Позволяет назначать адресатов, тему письма, Reply-To, копии CC/BCC и индивидуальные настройки через rfTarget.
- Загружает несколько файлов, контролирует хранилище и при необходимости прикрепляет файлы к письму.
- Ведёт историю обычных и заблокированных отправок и экспортирует данные в CSV.
- Собирает разрешённые UTM-метки и передаёт их вместе с формой.
- Содержит антиспам по времени, IP и содержимому, JavaScript-проверку браузера и ограничения массовых отправок.
- Интегрируется с Telegram, MAX, JivoSite и Verbox.
- Поддерживает переопределение шаблона письма, собственные PHP-макеты и плагины группы radicalform.
- Корректно работает с кешированием Joomla и многоязычными сайтами.
Руководство актуализировано для RadicalForm 4.2.6.
Идея RadicalForm
Большинство конструкторов форм одновременно создают разметку, подключают собственные стили и обрабатывают данные. Это удобно для типовых задач, но усложняет точную интеграцию с шаблоном, конструктором страниц или интернет-магазином.
RadicalForm отделяет внешний вид от обработки. Разметку и оформление формы задаёт разработчик сайта, а плагин добавляет AJAX-отправку, CSRF-токен, валидацию, файлы, уведомления, историю и антиспам.
Такой подход особенно удобен для форм в модальных окнах, кнопок «Купить в один клик» и страниц, где несколько форм должны выглядеть по-разному. Плагин не навязывает CSS-фреймворк и не требует jQuery.
Для работы потребуется базовое знание HTML: нужно правильно разместить контейнер, назначить кнопке класс rf-button-send и задать полям атрибуты name.
Оглавление
- Создание формы
- Настройка после установки
- Имена полей, переводы и зарезервированные имена
- JavaScript №1, №2, №3 и обработчик ошибок №9
- Всплывающие окна
- JavaScript №0 перед отправкой
- Сообщение после отправки
- Индивидуальное сообщение формы
- Цели Яндекс Метрики
- Тема письма
- Индивидуальная тема письма
- Выбор адресата через rfTarget
- Поле Reply-To
- Обязательные поля и HTML5-валидация
- Тексты ошибок полей
- Checkbox и select multiple
- Сообщение «Подождите»
- Загрузка файлов
- Telegram
- MAX
- Переопределение шаблона письма
- JivoSite и Verbox
- Собственный PHP-код
- Плагины RadicalForm
- UTM-метки
- История и CSV
- Bitrix24 CRM
- AmoCRM
- Антиспам
- JavaScript-проверка браузера
- Защита от массовых отправок
Как создать форму обратной связи?
RadicalForm не генерирует разметку формы: вы размещаете обычные элементы HTML там, где они нужны в шаблоне, модуле или конструкторе страниц.
- Рекомендуемый контейнер — тег
<form>. Если он содержит кнопку.rf-button-send, RadicalForm автоматически добавит ему классrf-form. Когда среда уже создаёт внешний<form>, используйте нейтральный контейнер, например<div class="rf-form">; вкладывать один тег<form>в другой нельзя. - Кнопке отправки назначьте класс
rf-button-send. Для кнопки внутри<form>рекомендуется указатьtype="button". - Каждому передаваемому полю задайте атрибут
name. Поля безnameRadicalForm игнорирует.
Атрибуты action и method не требуются: запрос формирует JavaScript плагина.
<form class="rf-form">
<input class="uk-input" name="phone" placeholder="Введите номер телефона" type="tel" required>
<button type="button" class="uk-button rf-button-send">Заказать звонок</button>
</form>Кнопка с классом rf-button-send должна находиться внутри контейнера .rf-form. При ошибке RadicalForm покажет сообщение и выведет проблемные элементы в консоль браузера.
Класс required отмечает обязательное поле. Если оно пустое, RadicalForm добавит CSS-классы, указанные в параметре «CSS класс для невалидных полей». Можно также использовать стандартные атрибуты HTML5 required, type и pattern.
Что настроить после установки?
- Если нужна почта, оставьте включённой «Отправку email» и укажите основной адрес. При необходимости заполните CC, BCC, Reply-To и альтернативных адресатов.
- Проверьте CSS-классы невалидных полей и ошибок загрузки файлов. Значения по умолчанию подходят Bootstrap и UIkit, но их можно заменить классами вашего шаблона.
- Проверьте JavaScript №2. По умолчанию RadicalForm использует
Joomla.renderMessages(), а если эта функция недоступна — обычныйalert(). - Включите только нужные интеграции, загрузку файлов, UTM-метки и механизмы антиспама. Дополнительная JavaScript-проверка и ограничения массовых отправок по умолчанию выключены.
Имена полей и перевод
Подпись поля в письме и истории формируется из атрибута name. Для перевода создайте переопределение языковой константы Joomla. Например, для name="phone" создайте константу PHONE со значением «Телефон».
<input class="uk-input" name="phone" type="tel" required>
Если перевод должен работать и на сайте, и в панели управления, создайте переопределение для обеих областей.
Зарезервированные имена
Нельзя использовать служебные имена Joomla: option, plugin, group, format, module, template, method. Также зарезервированы поля RadicalForm: rfJsAction, rfJsChallenge, rfJsProof, rfJsPermit. Проверка выполняется без учёта регистра.
При конфликте переименуйте поле, например format в contact_format. RadicalForm проверяет имена и в браузере, и на сервере.
Если вы хотите, чтобы перевод языковой константы отображался не только в письмах и отправленных сообщениях, но и в логах админки сайта, лучше поставить галочку "Для сайта и панели".
Тогда перевод ваших языковых переменных отобразится и в истории отправленных сообщений в настройках плагина.
JavaScript №1, №2, №3 и обработчик ошибок №9
JavaScript №1–3 выполняется после успешной отправки. Без атрибута data-rf-call вызывается JavaScript №2. В каждый обработчик передаются переменные rfMessage — текст результата и here — нажатая кнопка.
Значение JavaScript №2 по умолчанию создаёт рядом с кнопкой контейнер и выводит сообщение через Joomla.renderMessages(). Если функция Joomla недоступна, используется alert(rfMessage). Код можно заменить под ваш шаблон, например:
UIkit.modal.alert(rfMessage);
Атрибут data-rf-call="13" последовательно вызовет обработчики №1 и №3. Цифра 0 имеет особое значение: JavaScript №0 запускается до отправки.
Отдельный вывод ошибок
Если включить «Использовать отдельный код для вывода ошибок», для ошибок будет вызываться JavaScript №9. Ему также доступны rfMessage и here. Если отдельный обработчик выключен, RadicalForm использует первый доступный обработчик сообщения, обычно JavaScript №2.
Всплывающие окна
Чтобы после успешной отправки закрыть модальное окно и показать сообщение, поместите закрытие окна в JavaScript №1:
UIkit.modal(document.querySelector('#callback')).hide();
Затем вызовите №1 и №2 одной кнопкой:
<button type="button" class="uk-button uk-button-primary rf-button-send" data-rf-call="12">Отправить заявку</button>
Если библиотека модального окна переносит разметку в конец документа, проверьте в инструментах разработчика, что кнопка после открытия по-прежнему находится внутри .rf-form.
JavaScript №0 перед отправкой
JavaScript №0 позволяет добавить или изменить данные непосредственно перед отправкой. Для его вызова атрибут data-rf-call должен начинаться с нуля, например data-rf-call="02".
const code = document.querySelector('#product-code')?.textContent?.trim();
const form = here.closest('.rf-form');
if (code && form) {
let field = form.querySelector('input[name="article"]');
if (!field) {
field = document.createElement('input');
field.type = 'hidden';
field.name = 'article';
form.append(field);
}
field.value = code;
}
В JavaScript №0 доступны here и needReturn. Возврат false отменяет отправку:
if (!confirm('Отправить форму?')) {
return false;
}
Сообщение после отправки
Текст успешного результата задаётся параметром «Сообщение после отправки формы». Его получает JavaScript №2 или обработчики, перечисленные в data-rf-call. Поле поддерживает HTML, но способ отображения должен уметь его обработать.
Индивидуальное сообщение формы
Для разных форм можно назначить JavaScript №3 и прочитать сообщение из data-атрибута кнопки:
UIkit.modal.alert(String(here.dataset.rfText));
<button type="button" class="uk-button rf-button-send"
data-rf-call="3" data-rf-text="Мы вам перезвоним">
Отправить заявку
</button>
Не помещайте пользовательский ввод в HTML без экранирования.
Цели Яндекс Метрики
В обработчик успешной отправки можно добавить достижение цели. Выполняйте вызов только после вывода сообщения:
UIkit.modal.alert(rfMessage);
if (typeof ym === 'function') {
ym(12345678, 'reachGoal', 'FORM_SENT');
}
Замените номер счётчика и имя цели своими значениями. Код выполняется только после успешной обработки формы сервером.
Тема письма
Общая тема задаётся в параметрах плагина. В неё можно подставить значение любого поля формы, заключив его имя в фигурные скобки:
Заказ на сайте. Телефон: {phone}
Для множественного поля значения объединяются через запятую. Если поля нет, маркер остаётся без замены. Также доступен маркер {rfLatestNumber} с номером записи.
Индивидуальная тема письма
Скрытое поле rfSubject переопределяет тему для конкретной формы. В индивидуальной теме тоже работают подстановки:
<input type="hidden" name="rfSubject" value="Заказ {product_name}">
Выбор адресата через rfTarget
Скрытое поле rfTarget связывает форму с альтернативными адресами email, получателями Telegram и MAX, а также с собственными PHP-макетами:
<input type="hidden" name="rfTarget" value="sales">
Укажите тот же Target ID у всех получателей, которым должна уйти эта форма. Получатели с пустым Target ID используются для форм без rfTarget.
Поле Reply-To
Параметр «Имя поля “Ответить на”» указывает, из какого поля формы брать адрес ответа. Значение по умолчанию — email. Если форма использует другое имя, укажите его в настройке. Поле должно содержать корректный email-адрес.
Обязательные поля и HTML5-валидация
RadicalForm поддерживает два способа проверки:
- CSS-класс
requiredпроверяет непустое значение, а для checkbox — состояниеchecked; - стандартные ограничения HTML5 проверяются методом браузера
checkValidity().
<input class="uk-input" name="email" type="email" required>
<input class="uk-input" name="quantity" type="text" pattern="\d+" required>
Невалидные поля получают классы из параметра «CSS класс для невалидных полей». Проверка в браузере улучшает интерфейс, но серверную проверку важных данных всё равно следует выполнять в интеграционном плагине или собственном коде.
Тексты ошибок полей
Индивидуальную подсказку удобно разместить сразу после поля и показывать её, когда RadicalForm добавит класс ошибки:
<input class="uk-input" name="email" type="email" required>
<div class="rf-field-error">Укажите корректный email</div>
.rf-field-error {
display: none;
color: #b42318;
}
.is-invalid + .rf-field-error,
.uk-form-danger + .rf-field-error {
display: block;
}
Checkbox и select multiple
Поля с несколькими значениями должны иметь одинаковое имя с суффиксом []:
<label><input type="checkbox" name="service[]" value="delivery"> Доставка</label>
<label><input type="checkbox" name="service[]" value="installation"> Установка</label>
<select name="city[]" multiple>
<option value="moscow">Москва</option>
<option value="kazan">Казань</option>
</select>
RadicalForm передаст все выбранные значения; в письме они объединяются разделителем из настроек.
Сообщение «Подождите»
Во время запроса кнопка блокируется, а её содержимое временно заменяется текстом из параметра «Сообщение “Подождите”». После ответа исходное содержимое восстанавливается. Можно использовать HTML, например спиннер вашего шаблона.
Загрузка файлов
Сначала включите «Разрешить загрузку файлов» на вкладке «Файлы». Полю задайте класс rf-upload-button и уникальное имя:
<input class="rf-upload-button" name="documents" type="file" multiple>
<div class="rf-filenames-list"></div>
.rf-filenames-list должен находиться внутри той же .rf-form. В нём отображаются загруженные файлы, ошибки и кнопки удаления.
Для кастомной кнопки элемент .rf-upload-button-text разместите рядом с input внутри общего родителя:
<div class="uk-form-custom" uk-form-custom>
<button type="button" class="uk-button rf-upload-button-text">Приложить файлы</button>
<input class="rf-upload-button" name="photos" type="file" multiple>
</div>
По умолчанию в сообщение добавляются ссылки на файлы. Параметр «Вставлять файлы в письмо как вложения» дополнительно прикрепляет их с учётом ограничения размера. Проверьте максимальный объём хранилища, срок хранения и путь скачивания.
Telegram
- Создайте бота через @BotFather командой
/newbot. - Включите Telegram, вставьте HTTP API token и сохраните плагин.
- Отправьте боту сообщение, затем нажмите «Обновить chat_id».
- Выберите получателей и при необходимости задайте им Target ID.
Если Telegram недоступен напрямую, RadicalForm поддерживает SOCKS5-прокси, включая DNS через прокси.
MAX
- Получите токен чат-бота MAX, включите интеграцию, вставьте токен и сохраните настройки.
- Нажмите «Проверить подключение MAX». RadicalForm отдельно проверит сеть, доверие TLS-сертификату и токен.
- Отправьте сообщение боту и нажмите «Обновить MAX ID». При первом нажатии может быть только сохранён маркер обновлений — тогда отправьте новое сообщение и повторите обновление.
- Для каждого получателя проверьте ID, тип
user_idилиchat_idи Target ID.
Переопределение шаблона письма
Скопируйте /plugins/system/radicalform/tmpl/default.php в /templates/your_template/html/plg_system_radicalform/default.php, заменив your_template именем активного шаблона.
Макету доступны подготовленные переменные $subject, $header, $mainbody и $footer. Массив полей формы называется $input; переменной $source в RadicalForm 4 нет.
Если вы заново формируете тело письма, используйте актуальный класс Joomla:
use Joomla\CMS\Language\Text;
$mainbody = '';
foreach ($input as $key => $record) {
if (is_array($record)) {
$record = implode(', ', $record);
}
$label = htmlspecialchars(Text::_($key), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$value = htmlspecialchars((string) $record, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$mainbody .= '<p>' . $label . ': <strong>' . $value . '</strong></p>';
}
После обновления RadicalForm сравните переопределение с актуальным default.php в репозитории: Joomla не обновляет файлы шаблона автоматически.
JivoSite и Verbox
Установите код нужного виджета на сайте и включите соответствующий переключатель RadicalForm. Поля name, phone и email передаются в карточку клиента, если присутствуют в форме. Текст заявки отправляется в чат после успешной обработки.
Собственный PHP-код
Создайте PHP-файл в /templates/your_template/html/plg_system_radicalform/, включите «Использовать свой код» и укажите имя файла в поле Layout. Для выполнения только у определённой формы задайте одинаковый Target ID в настройке макета и в поле rfTarget.
<?php
defined('_JEXEC') or die;
if (isset($input['name'])) {
$contactName = (string) $input['name'];
}
В собственном макете массив пользовательских полей называется $input. Также доступны $params, $target, $formID и подготовленные части письма. Не переопределяйте $body: в этой переменной RadicalForm хранит готовое письмо. Не выводите текст через echo — неожиданный вывод записывается в журнал.
Плагины RadicalForm
Для повторно используемой интеграции создайте плагин группы radicalform. В RadicalForm 4.2.6 предпочтительно событие onBeforeProcessRadicalForm с объектом события:
use Joomla\Plugin\System\RadicalForm\Event\BeforeProcessRadicalFormEvent;
public function onBeforeProcessRadicalForm(BeforeProcessRadicalFormEvent $event): void
{
$input =& $event->getInput();
$input['name'] = trim((string) ($input['name'] ?? ''));
}
$event->getClearInput() возвращает данные без служебных полей, $event->getInput() — полный изменяемый массив, а $event->getParams() — параметры RadicalForm с дополнительными значениями uploaddir и rfLatestNumber.
Старое событие onBeforeSendRadicalForm($clear, &$input, $params) продолжает вызываться для совместимости. Чтобы отклонить отправку, результат обработчика должен содержать ['send' => false, 'message' => 'Причина', 'fields' => ['email']]; обычная строка игнорируется. Для нового кода используйте объект события Joomla.
Скачать пример плагина RadicalForm
UTM-метки
Включите «Отслеживать UTM-метки», чтобы сохранить параметры из URL и добавить их к заявке. По умолчанию разрешены utm_source, utm_medium, utm_campaign, utm_term и utm_content; список можно изменить.
Время хранения задаётся в минутах. Значение 0 хранит метки до окончания текущей сессии Joomla. Не добавляйте в разрешённый список секретные или произвольные параметры URL.
История и экспорт CSV
На вкладке «История отправки форм» доступны журналы сообщений и спама. Можно показывать Target ID, Form ID и дополнительную информацию о посетителе, очищать историю, сбрасывать нумерацию и экспортировать записи в CSV, в том числе с раскладкой по полям.
Размер журнала ограничивается параметром «Очищать лог при достижении». RadicalForm совместим с ротацией журналов Joomla. CSV-экспорт экранирует разделители, кавычки и переносы строк, а также защищает значения, похожие на формулы электронных таблиц.
Интеграция с Bitrix24 CRM
Готовую интеграцию предлагает плагин WT JoomShopping Bitrix24 PRO, который поддерживает RadicalForm. Для собственной интеграции можно использовать пример кода как отправную точку, предварительно адаптировав авторизацию и поля под свою CRM.
Интеграция с AmoCRM
Для AmoCRM доступен плагин WT AmoCRM — RadicalForm; проверьте на странице разработчика актуальные требования к библиотеке и Joomla. Для собственной реализации доступен пример интеграции. Настройки CRM индивидуальны, поэтому готовый код необходимо проверить и адаптировать.
Антиспам
В этом поле можно указать сообщение, которое будет выводиться пользователям (или ботам), чье сообщение воспринято как спам.
Можно указать непосредственно сообщение или языковую константу, которую можно переопределить.
Можно указать блокируемые диапазоны задержки перед отправкой формы. Используется метрика "Через какое время после загрузки страницы отправлена форма".
Чтобы лучше понять смысл этой блокировки, нужно увидеть поведение некоторых ботов.
Некоторые боты отправляют форму через одинаковое время после каждой загрузки страницы. Такие обращения можно блокировать одним или несколькими диапазонами в секундах, разделёнными запятыми.
Например:
0-4, 12-13
Форма будет заблокирована, если значение rf-duration попадает в диапазон от 0 до 4 секунд или от 12 до 13 секунд. Используйте эту проверку только после анализа истории: слишком широкий диапазон может затронуть реальных посетителей.
Правила блокируют форму по содержимому выбранных полей. В поле «Поля» укажите имена через запятую; значение * или пустое поле проверяет все доступные поля.
- Режим «Содержит» ищет заданный фрагмент без сложного синтаксиса.
- Режим «Регулярное выражение» использует PCRE-выражение PHP, включая ограничители и модификаторы, например
/(casino|viagra)/iu.
Проверяйте регулярные выражения перед публикацией: ошибочное или слишком общее правило может блокировать нормальные заявки. Готовые примеры приведены ниже.
/@gmail\.com$/i
Gmail-адрес, где перед @ есть точка:
/^[^@\s]+\.[^@\s]+@gmail\.com$/i
Gmail-адрес с несколькими сегментами через точки, что часто встречается у спама:
/^[^@\s]+(?:\.[^@\s]+){2,}@gmail\.com$/i
Ссылка в сообщении:
/(https?:\/\/|www\.)/i
Типичные спам-слова:
/(casino|betting|slots|viagra)/iu
Сообщение только латиница/цифры/символы без пробелов, что часто бывает у мусора:
/^[A-Za-z0-9._-]{12,}$/
i — без учета регистра.
u — корректная работа с UTF-8, включая кириллицу.
JavaScript-проверка браузера
Параметр «Требовать JavaScript для отправки» добавляет одноразовую проверку перед обработкой формы и блокирует прямые HTTP-запросы, которые не выполняют JavaScript-протокол RadicalForm. Проверка выключена по умолчанию.
Можно задать задержку от 100 до 1000 мс и собственное сообщение об ошибке. Значение по умолчанию — 350 мс. Не увеличивайте задержку без необходимости: она добавляется к отправке каждой формы.
Защита от массовых отправок
Два независимых лимита ограничивают поток заявок, которые прошли остальные антиспам-проверки:
- Блокировка при всплеске считает успешно обработанные формы за выбранный период и после достижения лимита приостанавливает дальнейшие отправки. По умолчанию в интерфейсе предлагаются 30 форм за 10 минут и блокировка на 60 минут.
- Суточная блокировка задаёт максимум форм за календарные сутки в часовом поясе Joomla. Предлагаемое значение по умолчанию — 200.
Оба механизма выключены по умолчанию. Подберите лимиты с запасом относительно обычного потока заявок. При начале блокировки RadicalForm может один раз отправить уведомление на указанный email; срабатывания сохраняются в истории спама.




