Все что я буду сегодня делать, разрабатывается на основе плагина, который мы с вами сделали в инструкциях: "Создание плагина через Artisan. Инструкция для новичков. Часть 1", Создание плагина через Artisan. Инструкция для новичков. Часть 2".
Если вы хотите сразу следовать за мной, без предварительной подготовки своего плагина, можете скачать готовый из GitHub.
Разработка AJAX формы обратного звонка
Наш плагин представляет из себя каталог, где есть категории и предметы. Представим такую ситуацию: у нас появилась задача реализовать на карточке предмета, форму обратной связи, чтобы клиенты, могли заполнить свое имя, email и номер телефона. Заявка с этими данными и с данными о текущей странице, должна отправляться по email, который мы укажем в настройках компонента.
Давайте создадим новый компонент, в нашем плагине. В нем мы реализуем весь необходимый функционал, и сделаем настройки для того чтобы можно беспроблемно через CMS страницу указать email для уведомлений.
Вводим в консоли:
php artisan create:component Author.PluginName ComponentName
Я создал компонент с названием Feedback.
Давайте сразу укажем наш новый компонент в plugin.php
нашего плагина.
Пример того как я добавил:
public function registerComponents()
{
return [
'OctoClub\Tutorial\Components\Catalog' => 'OctoClubCatalog',
'OctoClub\Tutorial\Components\Category' => 'OctoClubCategory',
'OctoClub\Tutorial\Components\Item' => 'OctoClubItem',
'OctoClub\Tutorial\Components\Feedback' => 'OctoClubFeedback',
];
}
Сохраняем, и переходим в папку с компонентами, и открываем файл Feedback.php
.
Здесь мы сразу приступим к defineProperties()
, и укажем возможность менять email для уведомлений.
В настройках компонента, это будет обычное текстовое поле, которое будет обязательно для уведомлений.
Пример выполнения:
public function defineProperties()
{
return [
'email' => [
'title' => 'Email',
'description' => 'Данный email будет использоваться для отправки всех заявок с формы.',
'default' => 'admin@test.ru',
'required' => true,
],
];
}
Здесь ничего необычного, абсолютно все так, как мы делали в первой части инструкции по созданию плагина.
Теперь давайте пропишем наш хандлер onSend()
, который будет принимать данные с формы и отправлять по указанному email.
Сразу под функцией defineProperties(), создаем новую: onSend()
:
public function onSend()
{
}
Данная функция будет вызываться с помощью AJAX Data Request, который мы укажем в html нашей формы.
Давайте напишем небольшую логику обработки данных, которые приходят с формы, и если что-то важное будет не заполнено, мы укажем это через стандартное всплывающее уведомление Flash.
Для этого нам нужно в наш компонент подключить классы, которые мы будем использовать.
В шапке нашего компонента добавляем:
use Mail;
use Input;
use Flash;
- Mail – будем использовать для отправки письма.
- Input – для получения и данных из формы.
- Flash – для уведомлений.
Небольшое отступление: я не буду проверять все данные через валидатор, данная форма будет простой, и небольшой. Никаких специальных полей с уникальными данными, которые должен указать пользователь – не будет. Поэтому если вы хотите написать супер сложную валидацию полей, вы можете обратиться к документации, и внедрить примеры оттуда в данный компонент.
Давайте определимся, какие поля пользователь должен будет заполнить в нашей форме:
- Имя – name
- Email – email
- Контактный телефон (опционально) – phone
И поля, которые пользователь не должен заполнять, они будут скрытыми (hidden):
- Наименование предмета – item_name
Для нашего случая большего и не нужно. Если вы хотите, можете добавить любое количество полей, скрытых или нет.
Поделюсь своим небольшим опытом:
Неплохо бы в input наших полей name="" прописывать не стандартные названия, Имя - name и Email - email. А прописывать их как угодно по-другому. Это такая защита от ботов, которые краулят сайты и находят формы без каптчи, вбивают поля по ключам, которые чаще всего используются в формах.
Если вы назовете Поле Имя - alsdkals, а поле Email – xcvxqwew, будет в десятки раз меньше шансов того, что бот сможет заполнить поле со всеми необходимыми полями.
Данный способ проверен на сайтах, которые до сих пор имеют формы без каптчи, после применения данного "лайфхака", практически со всех форм перестали падать спамовые рассылки.
В данной инструкции я не буду применять данный способ, чтобы вам было легче ориентироваться, но советую по завершению написания формы, все-таки реализовать какую-нибудь "защиту". Боты безжалостны.
Вернемся к нашему хандлеру onSend()
.
Давайте пропишем небольшую логику на проверку всех самых важных полей, а именно: имя, и email.
нам важно получить имя и его почту человека, даже если все остальное по какой-либо причине не будет указано, мы хотя-бы сможем связаться с человеком.
Прописываем эту небольшую логику в тело функции:
if(!Input::has('name') || empty(Input::get('name'))){
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Вы должны указать свое имя' ]);
}
if(!Input::has('email') || empty(Input::get('email'))){
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Вы должны указать email для связи' ]);
}
После этого, мы формируем массив полученных данных, который мы будем позднее использовать в шаблоне нашего письма.
$data = [
'name' => e(Input::get('name')),
'email' => e(Input::get('email')),
'item_name' => e(Input::get('item_name')),
];
if(Input::has('phone') && !empty(Input::get('phone'))){
$data['phone'] = e(Input::get('phone'));
}
Здесь все очень просто. Мы делаем массив $data
, где ключи будут использоваться в шаблоне как переменные. Функция e()
– очищает полученные данные из формы от любого исполняемого кода в escaped string.
У нас есть все данные, осталось просто добавить отправку письма, делаем:
$email = $this->property('email');
Mail::send('octoclub.tutorial::mail.feedback', $data, function($message) use ($email) {
$message->to($email, 'Admin Person');
});
// Проверка успешно ли ушло письмо
if (count(Mail::failures()) == 0){
Flash::success( 'Форма успешно отправлена!' );
} else {
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Произошла ошибка, попробуйте позже' ]);
}
Как вы заметили, я использую в функции send на первый взгляд не очень понятную строку 'octoclub.tutorial::mail.feedback'
. Все очень просто, это мы указываем шаблон письма. Мы создадим данный шаблон следующим шагом.
В итоге, вся функция выглядит так:
public function onSend()
{
// Проверка
if(!Input::has('name') || empty(Input::get('name'))){
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Вы должны указать свое имя' ]);
}
if(!Input::has('email') || empty(Input::get('email'))){
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Вы должны указать email для связи' ]);
}
// Составление массива
$data = [
'name' => e(Input::get('name')),
'email' => e(Input::get('email')),
'item_name' => e(Input::get('item_name')),
];
if(Input::has('phone') && !empty(Input::get('phone'))){
$data['phone'] = e(Input::get('phone'));
}
// Отправка уведомления
$email = $this->property('email');
Mail::send('octoclub.tutorial::mail.feedback', $data, function($message) use ($email) {
$message->to($email, 'Admin Person');
});
// Проверка успешно ли ушло письмо
if (count(Mail::failures()) == 0){
Flash::success( 'Форма успешно отправлена!' );
} else {
throw new \AjaxException([ 'X_OCTOBER_ERROR_MESSAGE' => 'Произошла ошибка, попробуйте позже' ]);
}
}
Разработка шаблона письма
Давайте создадим теперь наш шаблон письма. Перейдем в настройки админки, на страницу "Шаблоны почты", жмем на кнопку "новый шаблон", и заполняем по примеру:
Код: octoclub.tutorial::mail.feedback
Тема: Новая заявка со страницы предмета
Описание: Отправка уведомления администратору
HTML:
Пришла новая заявка со следующими данными:
* Имя: {{ name }}
* Email: {{ email }}
* {% if phone %}Телефон: {{ phone }}{% endif %}
* Предмет: {{ item_name }}
Все очень просто, и достаточно примитивно.
С помощью твига, вставляем переменные, если телефон заполнен, прикрепляем его тоже.
Пока не ушли из настроек, давайте переключим работу почты в режим тестирования, и сделаем так, чтобы все письма падали в журнал событий, чтобы быстро посмотреть результат. Открываем в настройках страницу "Настройки почты", и в выпадающем списке "метод" указываем "файл журнала".
Разработка верстки формы, подключение AJAX
Вся логика готова. Давайте добавим компонент на CMS страницу предмета через админку, укажем email, и перейдем к верстке формы.
Компонент добавили, ввели необходимый email.
Заметьте что в баре компонентов, под названием страницы, компонент формы идет следом после компонента предмета. Чтобы мы смогли в форме обратиться к переменной {{ item.name }}.
{% component 'OctoClubFeedBack' %}
в коде страницы уже не важно где вставлять, перед или после.
Теперь перейдем к верстке, переходим в папку с компонентами, и в папку /feedback
, открываем файл default.htm
. Удаляем дефолтный шаблон. И пишем верстку.
Получилось примерно так:
<form>
<div class="form-group">
<label for="name">Имя</label>
<input type="text" name="name" id="name" class="form-control" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email" class="form-control" required>
</div>
<div class="form-group">
<label for="phone">Телефон</label>
<input type="text" name="phone" id="phone" class="form-control">
</div>
<input type="hidden" name="item_name" value="{{ item.name }}">
<button type="submit" class="btn btn-primary">Отправить</button>
</form>
Обычная Bootstrap форма.
Теперь давайте добавим туда хандлеры, которые будут обрабатывать форму при отправке. Делается это очень просто, достаточно в тег <form>
добавить пару атрибутов.
<form
data-request="{{ __SELF__ }}::onSend"
data-request-success="$(this).find('input[type=text], input[type=email]').val('');"
data-request-flash>
data-request="{{ __SELF__ }}::onSend"
– указываем хандлер в нашем компоненте, который будет обрабатывать форму.
data-request-success="$(this).find('input[type=text], input[type=email]').val('');"
– очистка формы после успешной отправки формы.
data-request-flash
– добавляет возможность при использовании данной формы отображать уведомления.
Помните, чтобы у вас работала форма и уведомления, вам необходимо включить JS фреймворк OctoberCMS, в шаблон вашей страниы.
{% framework extras %}
Если у вас уже стоит обычный вызов фреймворка {% framework %}
, просто замените его примером выше.
Теперь давайте перейдем на страницу предмета, и проверим отправку формы 3 шагами!
1) Открываем страницу предмета, заполняем форму и отправляем
2) После нажатия на кнопку "Отправить", показывается уведомление и форма сбрасывается.
3) Перейдем в журнал событий в настройках админки, и посмотрим на наше письмо.
Все пришло правильно, и так как мы это захотели!
Вот и все. Вы можете свободно ни в чем себе не отказывая менять или переписывать данный способ обработки формы. Я лишь показал примитивный пример, который поможет новичкам в освоении OctoberCMS.