Skip to content

Instantly share code, notes, and snippets.

@itchief
Created February 6, 2021 13:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itchief/de1703e86c41c89527bd7c3b5e636905 to your computer and use it in GitHub Desktop.
Save itchief/de1703e86c41c89527bd7c3b5e636905 to your computer and use it in GitHub Desktop.
process.php for feedback-form
<?php
/*
* Форма обратной связи (https://itchief.ru/lessons/php/feedback-form-for-website)
* Copyright 2016-2020 Alexander Maltsev
* Licensed under MIT (https://github.com/itchief/feedback-form/blob/master/LICENSE)
*/
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_WRITE_LOG = true, // записывать данные в лог
UPLOAD_NAME = 'uploads', // имя директории для загрузки файлов
MAX_FILE_SIZE = 524288, // максимальный размер файла (в байтах)
ALLOWED_EXTENSIONS = array('jpg', 'jpeg', 'bmp', 'gif', 'png'); // разрешённые расширения файлов
$uploadPath = dirname(dirname(__FILE__)) . '/' . UPLOAD_NAME . '/'; // директория для хранения загруженных файлов
$startPath = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . '/';
function log_write($message)
{
if (IS_WRITE_LOG === false) {
return;
}
$output = date('d.m.Y H:i:s') . PHP_EOL . $message . PHP_EOL . '-------------------------' . PHP_EOL;
file_put_contents(dirname(dirname(__FILE__)) . '/logs/logs.txt', $output, FILE_APPEND | LOCK_EX);
}
/* 3 ЭТАП - ОТКРЫТИЕ СЕССИИ И ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННОЙ ДЛЯ ХРАНЕНИЯ РЕЗУЛЬТАТОВ ОБРАБОТКИ ФОРМЫ */
session_start();
$data['result'] = 'success';
/* 4 ЭТАП - ВАЛИДАЦИЯ ДАННЫХ (ЗНАЧЕНИЙ ПОЛЕЙ ФОРМЫ) */
// проверка поля name (оно должно быть обязательно заполнено и иметь длину в диапазоне от 2 до 30 символов)
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';
log_write('Не пройдена валидация поля: name! Его длина равна ' . $nameLength . ' симв.');
} else if ($nameLength > 30) {
$data['name'] = 'Длина текста не должна превышать 30 симв. (сейчас ' . $nameLength . ' симв.).';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: name! Его длина равна ' . $nameLength . ' симв.');
}
} else {
$data['name'] = 'Заполните это поле.';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: name! Оно не заполнено!');
}
// проверка поля email (оно должно присутствовать и иметь корректное значение)
if (isset($_POST['email'])) {
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { // защита от XSS
$data['email'] = 'Адрес электронной почты не корректный';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: email! Оно имеет не корретное значение!');
} else {
$email = $_POST['email'];
}
} else {
$data['email'] = 'Заполните это поле.';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: email! Оно не заполнено!');
}
// проверка поля message (это поле должно присутствовать и иметь длину в диапазоне от 20 до 500 символов)
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';
log_write('Не пройдена валидация поля: message! Его длина равна ' . $messageLength . ' симв.');
} else if ($messageLength > 500) {
$data['message'] = 'Длина текста не должна превышать 500 симв. (сейчас ' . $messageLength . ' симв.)';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: message! Его длина равна ' . $messageLength . ' симв.');
}
} else {
$data['message'] = 'Заполните это поле.';
$data['result'] = 'error';
log_write('Не пройдена валидация поля: name! Оно не заполнено!');
}
/* 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';
log_write('Не пройдена валидация поля: captcha! Указанный код ' . $captcha . ' не соответствует сгенерированному на сервере ' . $_SESSION['captcha']);
}
} else {
$data['captcha'] = 'Ошибка при проверке кода.';
$data['result'] = 'error';
log_write('Произошла ошибка при проверке капчи!');
}
}
/* 6 ЭТАП - ВАЛИДАЦИЯ ФАЙЛОВ */
if (isset($_FILES['attachment'])) {
// перебор массива $_FILES['attachment']
foreach ($_FILES['attachment']['error'] as $key => $error) {
// если файл был успешно загружен на сервер (ошибок не возникло), то...
if ($error == UPLOAD_ERR_OK) {
// получаем имя файла
$fileName = $_FILES['attachment']['name'][$key];
// получаем расширение файла в нижнем регистре
$fileExtension = mb_strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
// получаем размер файла
$fileSize = $_FILES['attachment']['size'][$key];
// результат проверки расширения файла
$resultCheckExtension = true;
// проверяем расширение загруженного файла
if (!in_array($fileExtension, ALLOWED_EXTENSIONS)) {
$resultCheckExtension = false;
$data['attachment'][$key] = 'Файл имеет не разрешённый тип.';
$data['result'] = 'error';
log_write('Произошла ошибка! Файл ' . $fileName . ' имеет не разрешённый тип.');
}
// проверяем размер файла
if ($resultCheckExtension && ($fileSize > MAX_FILE_SIZE)) {
$data['attachment'][$key] = 'Размер файла превышает допустимый.';
$data['result'] = 'error';
log_write('Произошла ошибка! Файл ' . $fileName . ' имеет не разрешённый размер.');
}
} else {
$data['attachment'][$key] = 'Ошибка при загрузке файла.';
$data['result'] = 'error';
log_write('Произошла ошибка при загрузке файла на сервер!');
}
}
// если ошибок валидации не возникло, то переместим файл в директорию $uploadPath
if ($data['result'] == 'success') {
// переменная для хранения имён файлов
$attachments = array();
// перемещение файлов в директорию $uploadPath
foreach ($_FILES['attachment']['name'] as $key => $attachment) {
// получаем имя файла
$fileName = basename($_FILES['attachment']['name'][$key]);
// получаем расширение файла в нижнем регистре
$fileExtension = mb_strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
// временное имя файла на сервере
$fileTmp = $_FILES['attachment']['tmp_name'][$key];
// создаём уникальное имя
$fileNewName = uniqid('upload_', true) . '.' . $fileExtension;
// перемещаем файл в директорию
if (!move_uploaded_file($fileTmp, $uploadPath . $fileNewName)) {
// ошибка при перемещении файла
$data['attachment'][$key] = 'Ошибка при загрузке файла.';
$data['result'] = 'error';
log_write('Произошла ошибка при перемещении файла в директорию, определяемою переменной $uploadPath!');
} else {
$attachments[] = $uploadPath . $fileNewName;
}
}
}
}
if ($data['result'] == 'success') {
$fileNamePart = '../forms/' . date('Y.m.d') . '-' . $email;
//$fileName = $_SERVER['DOCUMENT_ROOT'] . '/feedback/forms/' . date('Y.m.d') . '-' . $email;
$i = 1;
while (file_exists($fileNamePart . '-' . $i . '.txt')) {
$i++;
}
$fileName = $fileNamePart . '-' . $i . '.txt';
$text = 'Имя: ' . (isset($name) ? $name : '-') . PHP_EOL;
$text .= 'Email: ' . (isset($email) ? $email : '-') . PHP_EOL;
$text .= 'Сообщение: ' . (isset($message) ? $message : '-') . PHP_EOL;
if (isset($attachments)) {
$text .= 'Файлы:' . PHP_EOL;
foreach ($attachments as $attachment) {
$text .= $attachment . PHP_EOL;
}
}
file_put_contents($fileName, $text, FILE_APPEND | LOCK_EX);
}
/* 9 ЭТАП - ЗАПИСЫВАЕМ ДАННЫЕ В ЛОГ */
if ($data['result'] == 'success' && IS_WRITE_LOG) {
$output = 'Имя пользователя: ' . (isset($name) ? $name : '-') . PHP_EOL;
$output .= 'Адрес email: ' . (isset($email) ? $email : '-') . PHP_EOL;
$output .= 'Сообщение: ' . (isset($message) ? $message : '-') . PHP_EOL;
if (isset($attachments)) {
$output .= 'Файлы:' . PHP_EOL;
foreach ($attachments as $attachment) {
$output .= $attachment . PHP_EOL;
}
}
log_write('Письмо успешно отправлено!' . PHP_EOL . $output);
}
/* ФИНАЛЬНЫЙ ЭТАП - ВОЗВРАЩАЕМ РЕЗУЛЬТАТЫ РАБОТЫ В ФОРМАТЕ JSON */
echo json_encode($data);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment