Last active
January 23, 2023 05:17
-
-
Save sxidsvit/21c86ce4f3d867194139324e51c93dae to your computer and use it in GitHub Desktop.
Отправка формы с помощью AJAX, PHP и PHPMailer. Валидация формы
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HTML-форма | |
// Статья: Вменяемая инструкция к PHPMailer “Отправка писем и файлов на почту | |
// Статья: ”Стилизация и кастомизация File Inputs | |
<form class="form" action="#" method="post" id="sendform" enctype="multipart/form-data"> | |
<fieldset> | |
<div class="first-row"> | |
<div class="first-row_first-block"> | |
<input class="first-block__input" name="location" type="text" placeholder="Местонахождение объекта оценки: *" | |
required /> | |
<input class="first-block__input" name="price" type="text" placeholder="Цена оценки: *" required /> | |
<input class="first-block__input" name="date" type="text" placeholder="Предпочтительная дата оценки: *" | |
required /> | |
</div> | |
<div class="first-row_second-block"> | |
<input class="second-block__input" name="name" type="text" placeholder="Ваше имя: *" required /> | |
<input class="second-block__input" name="tel" type="tel" placeholder="Контактный телефон *" required /> | |
<input class="second-block__input" name="mail" type="email" placeholder="E-mail: *" required /> | |
</div> | |
<textarea class="message-field" name="message">Дополнительная информация</textarea> | |
</div> | |
<div class="second-row"> | |
<div class="second-row_first-block"> | |
<!-- <ul class="upload-files"> | |
<li class="upload-filename">Прикрепляемый файл 1.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 2.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 3.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 4.jpg</li> | |
</ul> | |
<ul class="upload-files"> | |
<li class="upload-filename">Прикрепляемый файл 5.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 6.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 7.jpg</li> | |
<li class="upload-filename">Прикрепляемый файл 8.jpg</li> | |
</ul> --> | |
</div> | |
<div class="btn-wrap"> | |
<input class="file-upload-btn inputfile" name="file[]" type="file" id="file" | |
data-multiple-caption="Выбрано файлов - {count}" multiple> | |
<label for="file">Прикрепить файл</label> | |
<input class="submit-btn" type="submit" name="submit" value="Отправить"> | |
<div class="text-block"> | |
<input type="checkbox" name="policy" id="form-checkbox" class="form-checkbox" required > | |
<label class="form-checkbox__label" for="form-checkbox">Я ознакомил(ся/ась) с <a href="#" | |
class="policy-link"> Политикой</a> и даю согласие на обработку своих персональных данных | |
*</label> | |
<p class="text">Если требуется загрузить больше файлов, присылайте их на электронную почту | |
<a class="email-link" href="mailto:[email protected]">[email protected]</a> | |
</p> | |
</div> | |
</div> | |
</div> | |
</fieldset> | |
</form> | |
//--------------------------------------------------------------------------------------------------------- | |
// mail.php | |
<?php | |
// ini_set('display_errors', 1); | |
// error_reporting(E_ALL); | |
// Файлы phpmailer | |
require 'phpmailer/PHPMailer.php'; | |
require 'phpmailer/SMTP.php'; | |
require 'phpmailer/Exception.php'; | |
// Содержание полей формы которую отправил посетитель сайта | |
$location = trim($_POST['location']); | |
$price = trim($_POST['price']); | |
$date = trim($_POST['date']); | |
$name = trim($_POST['name']); | |
$tel = trim($_POST['tel']); | |
$email = trim($_POST['mail']); | |
$message = trim($_POST['message']); | |
// Вложенные в форму файлы будут обработаны ниже | |
// $mail = new PHPMailer; // Создаем экземпляр мейлера почты | |
$mail = new PHPMailer\PHPMailer\PHPMailer(); | |
$mail->SMTPDebug = 1; // Режим отладки | |
// try { | |
$mail->isSMTP(); // Включаем мейлер в режим SMTP | |
$mail->SMTPAuth = true; // Включаем SMTP аутентификацию | |
$mail->CharSet = 'utf-8'; | |
// Настройки вашей почты (взять у провайдера) | |
$mail->Host = 'mail.adm.tools'; // SMTP сервер | |
$mail->Username = '[email protected]'; // Ваш логин от почты с которой будут отправляться письма | |
$mail->Password = 'asp2017asp'; // Ваш пароль от почты с которой будут отправляться письма | |
$mail->SMTPSecure = 'ssl'; // Протокол шифрования SSL или TLS | |
$mail->Port = 465; // TCP порт для подключения | |
// Получатель письма | |
$mail->setFrom('[email protected]'); // От кого будет уходить письмо? | |
$mail->addAddress('[email protected]'); // Кому будет уходить письмо | |
//$mail->addAddress('[email protected]'); | |
//$mail->addReplyTo('[email protected]', 'Information'); | |
//$mail->addCC('[email protected]'); | |
//$mail->addBCC('[email protected]'); | |
// Тело письма | |
$body = "<b>Местонахождение объекта оценки: </b>" . $location . "<br>"; | |
$body .= "<b>Цена оценки: </b>" . $price . "<br>"; | |
$body .= "<b>Предпочтительная дата оценки: </b>" . $date . "<br>"; | |
$body .= "<b>Имя клиента: </b>" . $name . "<br>"; | |
$body .= "<b>Контактный телефон: </b>" . $tel . "<br>"; | |
$body .= "<b>E-mail: </b>" . $email . "<br>"; | |
$body .= "<b>Дополнительная информация: </b>" . $message . "<br>"; | |
// Прикрипление файлов к письму | |
if (!empty($_FILES['file']['name'][0])) { | |
for ($ct = 0; $ct < count($_FILES['file']['tmp_name']); $ct++) { | |
$uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['file']['name'][$ct])); | |
$filename = $_FILES['file']['name'][$ct]; | |
if (move_uploaded_file($_FILES['file']['tmp_name'][$ct], $uploadfile)) { | |
$mail->addAttachment($uploadfile, $filename); | |
} else { | |
$msg .= 'Неудалось прикрепить файл ' . $uploadfile; | |
} | |
} | |
} | |
// Само письмо | |
$mail->isHTML(true); // Задаём формат письма (HTML) | |
$mail->Subject = 'Заявка с сайта expert-otsenka24.ru'; | |
$mail->Body = $body; | |
if ($mail->send()) { | |
echo 'Письмо отправленно'; | |
} else { | |
echo "Сообщение не было отправлено. Неверно указаны настройки вашей почты"; | |
} | |
// } catch (Exception $e) { | |
// echo "Сообщение не было отправлено. Причина ошибки: {$mail->ErrorInfo}"; | |
// } | |
// ---------------------------------------------------------------------------------------------- | |
// main.js | |
// Как только страничка загрузилась | |
window.onload = function () { | |
// проверяем поддерживает ли браузер FormData | |
if (!window.FormData) { | |
alert("Браузер не поддерживает загрузку файлов на этом сайте"); | |
} | |
} | |
$(document).ready(function () { | |
// Валидация и отправка формы | |
var errorTxt = 'Ошибка отправки'; | |
$.validator.addMethod( | |
"dmyDate", | |
function(value, element) { | |
return value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/); | |
}, | |
"Введите дату в формате день/месяц/год " | |
); | |
$("#sendform").validate({ | |
rules: { | |
location: { | |
required: true, | |
}, | |
price: { | |
required: true, | |
}, | |
date: { | |
required: true, | |
dmyDate: true | |
}, | |
name: { | |
required: true, | |
}, | |
tel: { | |
required: true, | |
}, | |
mail: { | |
required: true, | |
email: true | |
}, | |
policy: { | |
required: true | |
} | |
}, | |
messages: { | |
location: { | |
required: "Это поле обязательно для заполнения", | |
}, | |
price: { | |
required: "Это поле обязательно для заполнения", | |
}, | |
date: { | |
required: "Это поле обязательно для заполнения" | |
}, | |
name: { | |
required: "Это поле обязательно для заполнения", | |
}, | |
tel: { | |
required: "Это поле обязательно для заполнения", | |
}, | |
mail: { | |
required: "Это поле обязательно для заполнения", | |
email: "Введите валидный почтовый адресс" | |
}, | |
"policy": "Нужно ваше согласие на обработку персональных данных" | |
}, | |
submitHandler: function (form) { | |
var myform = document.forms.sendform, | |
formData = new FormData(myform), | |
xhr = new XMLHttpRequest(); | |
xhr.open("POST", "/wp-content/themes/ocenka/mail.php"); | |
xhr.onreadystatechange = function () { | |
if (xhr.readyState == 3) { | |
$("#sendform").html('<p class="thank text-center">Идет отправка формы ...<br></p> '); | |
} | |
if (xhr.readyState == 4) { | |
if (xhr.status == 200) { | |
$("#sendform").html('<p class="thank text-center">Данные отправлены!<Br> Вы получите ответ в ближайшее время<Br></p> '); | |
} | |
if (xhr.status == 500) { | |
$("#sendform").html('<p class="thank text-center">Внутренняя ошибка сервера!<p>'); | |
console.dir(xhr) | |
} | |
} | |
}; | |
xhr.send(formData); | |
console.dir(xhr) | |
} | |
}); // end $("#sendform") | |
// Изменяем текст на кнопке загрузки файлов на их количество или название, если он один | |
var inputs = document.querySelectorAll('.inputfile'); | |
Array.prototype.forEach.call(inputs, function (input) { | |
var label = input.nextElementSibling, | |
labelVal = label.innerHTML; | |
input.addEventListener('change', function (e) { | |
var fileName = ''; | |
if (this.files && this.files.length > 1) { | |
fileName = (this.getAttribute('data-multiple-caption') || '').replace('{count}', this.files.length); | |
} | |
else | |
fileName = e.target.value.split('\\').pop(); | |
if (fileName) | |
label.innerHTML = fileName; | |
else | |
label.innerHTML = labelVal; | |
}); | |
}); // end Array.prototype | |
}); // end $(document).ready | |
// ------------------------------------------------------------------------------------------------------- | |
// send.php | |
<?php | |
// $to = '[email protected]'; | |
$to = '[email protected]'; | |
// error_log(print_r($_POST, 1)); | |
file_put_contents('send-log-post.txt', print_r($_POST, true), FILE_APPEND); | |
if (isset($_POST['submit'])) { | |
$location = trim($_POST['location']); | |
$price = trim($_POST['price']); | |
$date = trim($_POST['date']); | |
$name = trim($_POST['name']); | |
$tel = trim($_POST['tel']); | |
$mail = trim($_POST['mail']); | |
$message = trim($_POST['message']); | |
// error_log(print_r($_POST, 1)); | |
//file_put_contents('send-log-post.txt', print_r($_POST, true), FILE_APPEND); | |
error_log(print_r($_POST, 1)); | |
if (!empty($_FILES['file']['tmp_name']) and $_FILES['file']['error'] == 0) { | |
$filepath = $_FILES['file']['tmp_name']; | |
$filename = $_FILES['file']['name']; | |
// $filetype = $_FILES['file']['type']; | |
} else { | |
$filepath = ''; | |
$filename = ''; | |
// $filetype = ''; | |
} | |
$body = "Местонахождение объекта оценки: " . $location . "\r\n\r\n"; | |
$body .= "Цена оценки:" . $price . "\r\n\r\n"; | |
$body .= "Предпочтительная дата оценки:: " . $date . "\r\n\r\n"; | |
$body .= "Имя клиента: " . $name . "\r\n\r\n"; | |
$body .= "Контактный телефон: " . $tel . "\r\n\r\n"; | |
$body .= "E-mail: " . $mail . "\r\n\r\n"; | |
$body .= "Дополнительная информация: " . $message . "\r\n\r\n"; | |
error_log(print_r($body, 1)); | |
send_mail($to, $body, $mail, $filepath, $filename); | |
} | |
// Вспомогательная функция для отправки почтового сообщения с вложением | |
function send_mail($to, $body, $email, $filepath, $filename) | |
{ | |
$subject = 'Форма с прикреплением файла с сайта expert-otsenka24.ru'; | |
$boundary = "--" . md5(uniqid(time())); // генерируем разделитель | |
$headers = "From: " . $email . "\r\n"; | |
$headers .= "MIME-Version 1.0\r\n"; | |
$headers .= "Content-Type: multipart/mixed; boundary=\"" . $boundary . "\"\r\n"; | |
$multipart = "--" . $boundary . "\r\n"; | |
$multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n"; | |
$multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; | |
$body = $body . "\r\n\r\n"; | |
$multipart .= $body; | |
$file = ''; | |
if (!empty($filepath)) { | |
$fp = fopen($filepath, "r"); | |
if ($fp) { | |
$content = fread($fp, filesize($filepath)); | |
fclose($fp); | |
$file .= "--" . $boundary . "\r\n"; | |
$file .= "Content-Type: application/octet-stream\r\n"; | |
// $file .= "Content-Type: " . $filetype . "\r\n"; | |
// $file .= "Content-Type: image / jpeg \r\n"; | |
$file .= "Content-Disposition: attachment; filename=\"" . $filename . "\"\r\n\r\n"; | |
$file .= "Content-Transfer-Encoding: base64\r\n"; | |
$file .= chunk_split(base64_encode($content)) . "\r\n"; | |
} | |
} | |
$multipart .= $file . "--" . $boundary . "--\r\n"; | |
mail($to, $subject, $multipart, $headers); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment