Статья, в которой рассмотрим, как создать форму обратной связи для сайта, используя JavaScript, AJAX, популярный фронтенд фреймворк Bootstrap и PHP. Форма будет работать без перезагрузки страницы. Введённые данные будут отправляться на почту (email).

Загрузка формы обратной связи

Проект по созданию формы обратной связи (для Bootstrap 4) находится на гитхабе по адресу: https://github.com/itchief/simple-feedback-form.

Скачать эту форму можно также с Яндекс Диска по этому URL. Распространяется данная форма под лицензией MIT.

Демо формы обратной связи

Предыдущая версия AJAX формы обратной связи (для Bootstrap 3) доступна по этой ссылке.

Более сложные варианты форм обратной связи:

Файловая структура формы обратной связи

Форма обратной связи имеет следующую структуру:

feedback/
├── captcha/
│   ├── captcha.php
│   ├── oswald.ttf
│   └── background.png
├── css/
│   └── main.css
├── js/
│    ├── main.js
│    └── process-forms.js
├── logs/
│   ├── .htaccess
│   └── logs.txt
├── phpmailer/
│    └── ...
├── process/
│   ├── email.tpl
│   ├── email_client.tpl
│   └── process.php
├── vendors/
│   ├── bootstrap
│   └── jquery
└── index.html

Назначение файлов:

  • captcha.php - скрипт на языке php для генерации капчи;
  • oswald.ttf - шрифт, которой будет использоваться для вывода кода капчи на изображении;
  • background.png - фон, на который будет «накладываться» код капчи;
  • main.css - стили (не Bootstrap) для формы обратной связи;
  • main.js - скрипт, выполняющий инициализацию формы обратной связи;
  • process-forms.js - скрипт, обеспечивающий логику работы формы обратной связи на клиенте (в браузере);
  • logs.txt - текстовый файл, в который будет записываться лог после отправки формы обратной связи;
  • phpmailer - php-библиотека, которую будем использовать для отправки email-сообщений;
  • email.tpl - шаблон email-письма для получателя;
  • email_client.tpl - шаблон email-письма для отправителя;
  • process.php - скрипт, посредством которого будем обрабатывать форму на сервере;
  • index.html - HTML-документ, содержащий форму обратной связи;

В каталоге vendors расположены фреймворк Bootstrap и библиотека jQuery.

Установка формы обратной связи

По умолчанию контактная форма (папка feedback вместе со всем содержимым) должна быть помещена в корневую директорию сайта. Т.е. путь к файлу index.html должен быть таким:

/feedback/index.html  

В проекте используются абсолютные пути к файлам. Это позволяет установить форму обратной связи очень просто, путём простого копирования HTML формы из файла index.html в любое место необходимой страницы сайта.

Настройка файлов при изменении структуры

Если нужно модифицировать структуру формы обратной связи, т.е. изменить расположение файлов, то в этом случае потребуется откорректировать пути в файлах index.html (или там где расположена форма) и process.php. Рассмотрим, как это выполнить более подробно.

Настройка путей к файлам в index.html

В файле index.html путь к php-обработчику формы задаётся с помощью атрибута формы action. Если обработчик перенесён в другое место, то значение данного атрибута необходимо изменить.

<form id="feedbackForm" action="/feedback/process/process.php" novalidate>

В файле index.html ещё устанавливается путь к капче. Если она расположена не по адресу /feedback/captcha/captcha.php, то значения атрибутов src и data-src необходимо откорректировать.

<img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">

Кроме этого к странице, в которой будет использоваться форма, должны быть подключены фреймворк Bootstrap 4 (bootstrap.js, bootstrap.css), библиотека jQuery (jquery.js) и скрипт process-forms.js.

...
<link rel="stylesheet" href="/feedback/vendors/bootstrap/css/bootstrap.min.css">
...  
<script src="/feedback/vendors/jquery/jquery-3.3.1.min.js"></script>
<script src="/feedback/vendors/bootstrap/js/bootstrap.min.js"></script>
<script src="/feedback/js/process-forms.js"></script>

Инициализация формы выполняется следующим образом (в проекте для этой цели используется файл main.js):

//после загрузки DOM
$(function () {
  var form1 = feedbackForm();
  form1.init({
    id: '#feedbackForm'
  });
});

Настройка путей к файлам в process.php

В файле process.php для отправки писем используется библиотка PHPMailer. При модификации структуры проекта проверьте и при необходимости откорректируйте путь к этой библиотеки (PHPMailer), а также ещё к файлу logs.txt.

Как осуществляется валидация формы

В данной форме валидация осуществляется как на клиенте, так и на сервере.

Скриншот формы с ошибками валидации:

Форма обратной связи - Пример вывод ошибок валидации

На клиенте она осуществляется посредством механизма встроенным в браузер, в связи с этим текст сообщений может немного отличаться.

Установка требований к полям формы обратной связи определяется с помощью атрибутов type, required, minlength, maxlength, pattern и др.

Например, требование к полю name в данном проекте:

<!-- required="required" - обязательное поле -->
<!-- minlength="2" - количество символов не меньше 2 -->
<!-- maxlength="2" - количество символов не больше 30 -->
<input id="name" type="text" name="name" class="form-control" value="" placeholder="Имя" minlength="2" maxlength="30" required="required">

На сервере валидация данных формы осуществляется в файле process.php.

Например, валидация поля name осуществляется с помощью следующего php-кода:

if (isset($_POST['name'])) {
  $name = filter_var($_POST['name'], FILTER_SANITIZE_STRING); // защита от XSS
  $nameLength = mb_strlen($name, 'UTF-8');
  if ($nameLength < 2) {
    $data['name'] = 'Текст должен быть не короче 2 симв. Длина текста сейчас: '. $nameLength .' симв.';
    $data['result'] = 'error';
  } else if ($nameLength > 30) {
    $data['name'] = 'Длина текста не должна превышать 30 симв. (сейчас '. $nameLength .' симв.).';
    $data['result'] = 'error';
  }
} else {
  $data['name'] = 'Заполните это поле.';
  $data['result'] = 'error';
}

Описание формы обратной связи

Скриншот формы:

HTML дизайн формы обратной связи

Форма по умолчанию состоит из трёх основных полей (имени, email-адреса, сообщения), капчи, чекбокса и кнопки "Отправить сообщение".

При необходимости изображение, содержащее код капчи можно обновить (осуществить генерацию нового кода). Выполняется это действие посредством нажатия на соответствующую кнопку в форме.

После заполнения полей формы пользователь может с помощью соответствующей кнопки её отправить на сервер.

Отправка данных на сервер выполняется с помощью JavaScript (AJAX). Но перед тем как их передать серверу по технологии AJAX, он должен их проверить на корректность.

Все действия по обработке формы в браузере, а также обновление страницы после получения ответа от сервера выполняет код JavaScript, находящийся в файле process-forms.js.

Инициализация работы этого скрипта (process-forms.js) осуществляется с помощью кода расположенного в файле main.js.

Основные действия, которые выполняет сценарий JavaScript, расположенный в файле process-forms.js:

  • обновление кода капчи, посредством изменения атрибута src у изображения;
  • валидацию (проверку) полей формы перед отправкой их на сервер;
  • отправку данных формы на сервер методом POST по технологии AJAX;
  • получения ответа от сервера и отображения его результатов на странице;

После отправки формы на сервер, она передаётся для обработки файлу process.php.

Данный файл (process.php) выполняет следующие основные действия:

  • получение данных с отправленной формы;
  • проверку данных формы (полей, капчи) и формирования ассоциативного массива с результатами проверки;
  • в случае успеха проверки даных - отправка email письма получателю и отправителю;
  • отправка JSON ответа веб-браузеру с результатами.

Скриншот формы при её успешной отправки:

Скриншот формы обратной связи при успешной отправки

Принцип работы формы обратной связи представлен на схеме.

Принцип работы формы обратной связи

Код формы обратной связи

HTML код формы обратной связи (файл index.html):

Показать или скрыть код

<div class="card mx-auto mb-4 rounded-0" style="max-width: 35rem;">
  <div class="card-body position-relative">

    <!-- Форма обратной связи -->
    <form id="feedbackForm" action="/feedback/process/process.php" novalidate>
      <div class="form-row">
        <div class="col-sm-6">
          <!-- Имя пользователя -->
          <div class="form-group">
            <label for="name" class="control-label">Имя</label>
            <input id="name" type="text" name="name" class="form-control" value="" placeholder="Имя" minlength="2" maxlength="30" required="required">
            <div class="invalid-feedback"></div>
          </div>
        </div>
        <div class="col-sm-6">
          <!-- Email пользователя -->
          <div class="form-group">
            <label for="email" class="control-label">Email-адрес</label>
            <input id="email" type="email" name="email" required="required" class="form-control" value="" placeholder="Email-адрес">
            <div class="invalid-feedback"></div>
          </div>
        </div>
      </div>
      <!-- Сообщение пользователя -->
      <div class="form-group">
        <label for="message" class="control-label">Сообщение (не менее 20 символов)</label>
        <textarea id="message" name="message" class="form-control" rows="3" placeholder="Сообщение (не менее 20 символов)" minlength="20"
          maxlength="500" required="required"></textarea>
        <div class="invalid-feedback"></div>
      </div>
      <!-- Капча -->
      <div class="form-group captcha">
        <img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">
        <div class="btn btn-light position-relative refresh-captcha">Обновить</div>
        <div class="form-group">
          <label for="captcha" class="control-label">Код, показанный на изображении</label>
          <input type="text" name="captcha" maxlength="6" required="required" id="captcha" class="form-control captcha" placeholder="******"
            autocomplete="off" value="">
          <div class="invalid-feedback"></div>
        </div>
      </div>
      <!-- Пользовательское солашение -->
      <div class="form-group agreement">
        <div class="custom-control custom-checkbox">
          <input type="checkbox" name="agree" class="custom-control-input" id="customCheck">
          <label class="custom-control-label" for="customCheck">Нажимая кнопку, я принимаю условия
            <a href="#">Пользовательского соглашения</a> и даю своё согласие на обработку моих персональных данных, в соответствии
            с Федеральным законом от 27.07.2006 года №152-ФЗ «О персональных данных».</label>
        </div>
      </div>
      <!-- Сообщение при ошибке -->
      <div class="alert alert-danger form-error d-none">
        Исправьте данные и отправьте форму ещё раз.
      </div>
      <!-- Кнопка для отправки формы -->
      <div class="text-right submit">
        <button type="submit" class="btn btn-primary position-relative" disabled="disabled">Отправить сообщение</button>
      </div>
    </form>

    <!-- Сообщение об успешной отправки формы -->
    <div class="form-result-success d-none text-center justify-content-center align-items-center" style="position: absolute;
    top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,.6); color: #fff; font-size: 1.25rem;">
      <div class="alert alert-success rounded-0">Форма успешно отправлена. Нажмите на
        <a class="alert-link" href="#" data-reloadform="#feedbackForm">ссылку</a>, чтобы отправить ещё одно сообщение.</div>
    </div>

  </div>
</div>

JavaScript код (файл process-forms.js):

Показать или скрыть код

'use strict';
var feedbackForm = (function () {
  // переключить во включенное или выключенное состояние кнопку submit
  var _changeStateSubmit = function (element, state) {
    $(element)
      .closest('form')
      .find('[type="submit"]').prop('disabled', state);
  };
  // изменение состояния кнопки submit в зависимости от состояния checkbox agree
  var _changeAgreement = function (element) {
    _changeStateSubmit(element, !element.checked);
  };
  // обновление капчи
  var _refreshCaptcha = function (form) {
    var
      captchaImg = form.find('.img-captcha'),
      captchaSrc = captchaImg.attr('data-src'),
      captchaPrefix = captchaSrc.indexOf('?id') !== -1 ? '&rnd=' : '?rnd=',
      captchaNewSrc = captchaSrc + captchaPrefix + (new Date()).getTime();
    captchaImg.attr('src', captchaNewSrc);
  };
  // изменение состояния элемента формы (success, error, clear)
  var _setStateValidaion = function (input, state, message) {
    input = $(input);
    if (state === 'error') {
      input
        .removeClass('is-valid').addClass('is-invalid')
        .siblings('.invalid-feedback').text(message);
    } else if (state === 'success') {
      input.removeClass('is-invalid').addClass('is-valid');
    } else {
      input.removeClass('is-valid is-invalid');
    }
  };
  // валилация формы
  var _validateForm = function (_$form) {
    var valid = true;
    _$form.find('input,textarea').not('[type="file"],[name="agree"]').each(function () {
      if (this.checkValidity()) {
        _setStateValidaion(this, 'success');
      } else {
        _setStateValidaion(this, 'error', this.validationMessage);
        valid = false;
      }
    });
    return valid;
  };
  var _showForm = function (form, _isCaptcha, _isAgreeCheckbox) {
    if (!form.find('.form-error').hasClass('d-none')) {
      form.find('.form-error').addClass('d-none');
    }
    form.siblings('.form-result-success').addClass('d-none').removeClass('d-flex');
    form[0].reset();
    form.find('input,textarea').each(function () {
      _setStateValidaion(this, 'clear');
    });
    if (_isCaptcha) {
      _refreshCaptcha(form);
    }
    if (_isAgreeCheckbox) {
      _changeStateSubmit(form, true);
    }
  };

  return function () {
    var _defaults = {
      id: '#feedbackForm' // id формы обратной связи
    }
    var
      _form = $(_defaults.id)[0], // форма обратной связи
      _$form = $(_form),
      _action = $(_form).attr('action'),
      _isCaptcha = false,  // имеется ли у формы секция captcha
      _isAgreeCheckbox = false; // имеется ли у формы секция agreement

    // собираем данные для отправки на сервер
    var _collectData = function () {
      var data = new FormData(_form);
      return data;
    };

    // отправка формы
    var _sendForm = function (e) {
      e.preventDefault();
      if (!_validateForm(_$form)) {
        if (_$form.find('.is-invalid').length > 0) {
          _$form.find('.is-invalid')[0].focus();
        }
        return;
      }
      var request = $.ajax({
        type: "POST",
        url: _action,
        data: _collectData(), // данные для отправки на сервер
        contentType: false,
        processData: false,
        cache: false,
        beforeSend: function () {
          _changeStateSubmit(_$form, true);
        }
      })
        .done(_success)
        .fail(_error)
    };
    var _success = function (data) {
      // при успешной отправки формы
      if (data.result === "success") {
        _$form.parent().find('.form-result-success')
          .removeClass('d-none')
          .addClass('d-flex');
        return;
      }
      // если произошли ошибки при отправке
      _$form.find('.form-error').removeClass('d-none');
      _changeStateSubmit(_$form, false);
      // сбрасываем состояние всех input и textarea элементов
      _$form.find('input,textarea').not('[type="file"],[name="agree"]').each(function () {
        _setStateValidaion(this, 'clear');
      });
      // выводим ошибки которые прислал сервер
      for (var error in data) {
        if (!data.hasOwnProperty(error)) {
          continue;
        };
        switch (error) {
          case 'captcha':
            _refreshCaptcha(_$form);
            _setStateValidaion(_$form.find('[name="' + error + '"]'), 'error', data[error]);
            break;
          case 'log':
            $.each(data[error], function (key, value) {
              console.log(value);
            });
            break;
          default:
            _setStateValidaion(_$form.find('[name="' + error + '"]'), 'error', data[error]);
        }
        // устанавливаем фокус на 1 невалидный элемент
        if (_$form.find('.is-invalid').length > 0) {
          _$form.find('.is-invalid')[0].focus();
        }
      }
    };
    var _error = function (request) {
      _$form.find('.form-error').removeClass('d-none');
    };

    // устанавливаем обработчики событий
    var _setupListener = function () {
      $(document).on('change', _defaults.id + ' [name="agree"]', function () {
        _changeAgreement(this);
      });
      $(document).on('submit', _defaults.id, _sendForm);
      $(document).on('click', _defaults.id + ' .refresh-captcha', function (e) {
        e.preventDefault();
        _refreshCaptcha(_$form);
      });
      $(document).on('click', '[data-reloadform="' + _defaults.id + '"]', function (e) {
        e.preventDefault();
        _showForm(_$form, _isCaptcha, _isAgreeCheckbox);
      });
    }

    return {
      init: function (config) {
        _isCaptcha = _$form.find('.captcha').length > 0; // имеется ли у формы секция captcha
        _isAgreeCheckbox = _$form.find('.agreement').length > 0; // имеется ли у формы секция agreement
        $.each(config, function (key, value) {
          _defaults[key] = value;
        });
        _setupListener();
      }
    };
  }
})();

PHP код для формирование изображения, содержащего код капчи (файл captcha.php):

Показать или скрыть код

<?php
session_start();
$id = 'captcha';
if (isset($_GET['id'])) {
  $id = filter_var($_GET['id'], FILTER_SANITIZE_STRING);
}
$captchastring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz';
$captchastring = substr(str_shuffle($captchastring), 0, 6);
$_SESSION[$id] = $captchastring;
$image = imagecreatefrompng(dirname(__FILE__) . '/background.png');
$colour = imagecolorallocate($image, 200, 240, 240);
$font = dirname(__FILE__) . '/oswald.ttf';
$rotate = rand(-10, 10);
imagettftext($image, 18, $rotate, 28, 32, $colour, $font, $captchastring);
header('Content-type: image/png');
imagepng($image);

PHP код, который выполняет обработку формы обратной связи на сервере (файл process.php):

Показать или скрыть код

<?php
header('Content-Type: application/json');
// обработка только ajax запросов (при других запросах завершаем выполнение скрипта)
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
  exit();
}
// обработка данных, посланных только методом POST (при остальных методах завершаем выполнение скрипта)
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  exit();
}
/* 1 ЭТАП - НАСТРОЙКА ПЕРЕМЕННЫХ */
const 
  IS_CHECK_CAPTCHA = true, // проверять капчу
  IS_SEND_MAIL = true, // отправлять письмо получателю
  IS_SEND_MAIL_SENDER = false, // отправлять информационное письмо отправителю
  IS_WRITE_LOG = true, // записывать данные в лог
  MAIL_FROM = 'no-reply@mydomain.ru', // от какого email будет отправляться письмо
  MAIL_FROM_NAME = 'Имя_сайта', // от какого имени будет отправляться письмо
  MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
  MAIL_ADDRESS = 'manager@mydomain.ru', // кому необходимо отправить письмо
  MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения
// 2 ЭТАП - ПОДКЛЮЧЕНИЕ PHPMAILER
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require_once('../phpmailer/src/Exception.php');
require_once('../phpmailer/src/PHPMailer.php');
require_once('../phpmailer/src/SMTP.php');
// 3 ЭТАП - ОТКРЫТИЕ СЕССИИ И ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННОЙ ДЛЯ ХРАНЕНИЯ РЕЗУЛЬТАТОВ ОБРАБОТКИ ФОРМЫ
session_start();
$data['result'] = 'success';
/* 4 ЭТАП - ВАЛИДАЦИЯ ДАННЫХ (ЗНАЧЕНИЙ ПОЛЕЙ ФОРМЫ) */
// проверка поля name
if (isset($_POST['name'])) {
  $name = filter_var($_POST['name'], FILTER_SANITIZE_STRING); // защита от XSS
  $nameLength = mb_strlen($name, 'UTF-8');
  if ($nameLength < 2) {
    $data['name'] = 'Текст должен быть не короче 2 симв. Длина текста сейчас: '. $nameLength .' симв.';
    $data['result'] = 'error';
  } else if ($nameLength > 30) {
    $data['name'] = 'Длина текста не должна превышать 30 симв. (сейчас '. $nameLength .' симв.).';
    $data['result'] = 'error';
  }
} else {
  $data['name'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
// проверка поля email
if (isset($_POST['email'])) {
  if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { // защита от XSS
    $data['email'] = 'Адрес электронной почты не корректный';
    $data['result'] = 'error';
  } else {
    $email = $_POST['email'];
  }
} else {
  $data['email'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
// проверка поля message
if (isset($_POST['message'])) {
  $message = filter_var($_POST['message'], FILTER_SANITIZE_STRING); // защита от XSS
  $messageLength = mb_strlen($message, 'UTF-8');
  if ($messageLength < 20) {
    $data['message'] = 'Текст должен быть не короче 20 симв. Длина текста сейчас: '. $messageLength .' симв.';
    $data['result'] = 'error';
  } else if ($messageLength > 500) {
    $data['message'] = 'Длина текста не должна превышать 500 симв. (сейчас '. $messageLength .' симв.)';
    $data['result'] = 'error';
  }
} else {
  $data['message'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
/* 5 ЭТАП - ПРОВЕРКА КАПЧИ */
if (IS_CHECK_CAPTCHA == true) {
  if (isset($_POST['captcha']) && isset($_SESSION['captcha'])) {
    $captcha = filter_var($_POST['captcha'], FILTER_SANITIZE_STRING); // защита от XSS
    if ($_SESSION['captcha'] != $captcha) { // проверка капчи
      $data['captcha'] = 'Код не соответствует изображению.';
      $data['result'] = 'error';
    }
  } else {
    $data['captcha'] = 'Ошибка при проверке кода';
    $data['result'] = 'error';
  }
}
/* 6 ЭТАП - ОТПРАВКА ПИСЬМА ПОЛУЧАТЕЛЮ */
if ($data['result'] == 'success' && IS_SEND_MAIL == true) {
  // получаем содержимое email шаблона
  $bodyMail = file_get_contents('email.tpl');
  // выполняем замену плейсхолдеров реальными значениями
  $bodyMail = str_replace('%email.title%', MAIL_SUBJECT, $bodyMail);
  $bodyMail = str_replace('%email.nameuser%', isset($name) ? $name : '-', $bodyMail);
  $bodyMail = str_replace('%email.message%', isset($message) ? $message : '-', $bodyMail);
  $bodyMail = str_replace('%email.emailuser%', isset($email) ? $email : '-', $bodyMail);
  $bodyMail = str_replace('%email.date%', date('d.m.Y H:i'), $bodyMail);
  // устанавливаем параметры
    $mail = new PHPMailer;
    $mail->CharSet = 'UTF-8';
    $mail->IsHTML(true);
    $fromName = '=?UTF-8?B?'.base64_encode(MAIL_FROM_NAME).'?=';
    $mail->setFrom(MAIL_FROM, $fromName);
    $mail->Subject = '=?UTF-8?B?'.base64_encode(MAIL_SUBJECT).'?=';
    $mail->Body = $bodyMail;
    $mail->addAddress(MAIL_ADDRESS);
    // отправляем письмо
    if (!$mail->send()) {
      $data['result'] = 'error';
    }
}
/* 7 ЭТАП - ОТПРАВКА ИНФОРМАЦИОННОГО ПИСЬМА ОТПРАВИТЕЛЮ */
if ($data['result'] == 'success' && IS_SEND_MAIL_SENDER == true) {
  try {
    // очистка всех адресов и прикреплёных файлов
    $mail->clearAllRecipients();
    $mail->clearAttachments();
    // получаем содержимое email шаблона
    $bodyMail = file_get_contents('email_client.tpl'); 
    // выполняем замену плейсхолдеров реальными значениями
    $bodyMail = str_replace('%email.title%', MAIL_SUBJECT, $bodyMail);
    $bodyMail = str_replace('%email.nameuser%', isset($name) ? $name : '-', $bodyMail);
    $bodyMail = str_replace('%email.date%', date('d.m.Y H:i'), $bodyMail);
    // устанавливаем параметры
    $mail->Subject = MAIL_SUBJECT_CLIENT;
    $mail->Body = $bodyMail;
    $mail->addAddress($email);
    // отправляем письмо
    $mail->send();
  } catch(Exception $e) {

  }
}
/* 8 ЭТАП - ЗАПИСЫВАЕМ ДАННЫЕ В ЛОГ */
if ($data['result'] == 'success' && IS_WRITE_LOG) {
  try {  
    $name = isset($name) ? $name : '-';
    $email = isset($email) ? $email : '-';
    $message = isset($message) ? $message : '-';
    $output = "---------------------------------" . "\n";
    $output .= date("d-m-Y H:i:s") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
    $output .= "Сообщение: " . $message . "\n";
    file_put_contents(dirname(dirname(__FILE__)) . '/logs/logs.txt', $output, FILE_APPEND | LOCK_EX);
  } catch(Exception $e) {

  }
}
/* ФИНАЛЬНЫЙ ЭТАП - ВОЗВРАЩАЕМ РЕЗУЛЬТАТЫ РАБОТЫ */
echo json_encode($data);

Как удалить из формы капчу и пользовательское соглашение

Для удаления капчи из формы достаточно выполнить 2 действия:

  • удалить блок "Капча" из HTML-формы;
  • установить константе IS_CHECK_CAPTCHA в файле process.php значение false.

Для удаления пользовательского соглашения из формы достаточно его удалить из HTML-формы обратной связи.

Настройка process.php (почта, капча и др.)

Настройка формы на стороне сервера осуществляется посредством редактирования значений констант в файле process.php:

const 
  IS_CHECK_CAPTCHA = true, // проверять капчу
  IS_SEND_MAIL = true, // отправлять письмо получателю
  IS_SEND_MAIL_SENDER = false, // отправлять информационное письмо отправителю
  IS_WRITE_LOG = true, // записывать данные в лог
  MAIL_FROM = 'no-reply@mydomain.ru', // от какого email будет отправляться письмо
  MAIL_FROM_NAME = 'Имя_сайта', // от какого имени будет отправляться письмо
  MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
  MAIL_ADDRESS = 'manager@mydomain.ru', // кому необходимо отправить письмо
  MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения

Для отправки сообщений библиотека PHPMailer использует php-функцию mail(). Поэтому убедитесь в том, она поддерживается тарифным планом хостинга и включена в настройках.

Если сообщения отправлять на почту не нужно, то константам IS_SEND_MAIL и IS_SEND_MAIL_SENDER необходимо установить значение false.