Здравствуйте уважаемые читатели Site on! Данный урок станет основоположником небольшого ответвления в разделе PHP. Здесь мы будем рассматривать решения реальных практических задач (так называемые кейсы), которые могут встретиться вам на пути к созданию ваших собственных веб-проектов. Другими словами в статьях данной подкатегории вы сможете найти готовые решения и наработки, которые сразу же можно внедрять в разрабатываемые вами сайты, в том числе и в ваши CMS!
Задание:
Сделать форму обратной связи – callback (обратный звонок), которая будет отправлять сообщение владельцу магазина по электронной почте. Форма должна иметь приятный интерфейс, быть «лёгкой», безопасной и быстро редактируемой под любые нужны. Также необходимо встроить данную форму в шаблон Joomla 2.5 + VirtueMart 2.
P.S. Форма будет работать на любом движке, не только в Joomla, так как сделана на чистом PHP.
Рабочий результат вы можете увидеть на данной странице слева по центру.
Любая подобная форма обязана иметь свой анти-спам, при этом необязательно заставлять своих посетителей вводить трудноразличимые буквы с картинки! О том, как сделать дружелюбную для посетителя проверку на спам, чтобы не потерять конверсию, я напишу в следующей статье, а здесь я в деталях расскажу и выложу заготовки, как сделать приятную форму обратной связи используя PHP, HTML, CSS и немного JS для красивого эффекта.
Начинать нужно с HTML, мы должны создать саму «форму» для формы обратной связи, это делается с помощью тега
<form></form>
Внутри которого указываются поля, заполняемые пользователями, и кнопка «отправить»:
<form method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>">
Имя: <input required="required" maxlength="30" type="text" name="name" />
Телефон: <input required="required" maxlength="30" type="text" name="phone" />
Сообщение: <br /><textarea rows="7" cols="50" required="required" name="message">Пожалуйста, перезвоните на указанный номер.</textarea>
<input type="hidden" name="check" value="fd13vv" />
<br /><input type="submit" value="Отправить!" />
</form>
Разберём каждую строчку более детально! Начнём с первой:
<form method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>">
Здесь мы открываем тег нашей формы и перечисляем необходимые атрибуты тега. Их у нас ровно 2 – это атрибуты method и action.
Значение атрибута method указывает, каким методом будет послан запрос серверу (GET или POST). Нам нужен именно POST, для тех, кто не знает разницы, будет написана отдельная статья про методы в PHP, следите за обновлениями!
В атрибуте action мы должны указать: на какую страницу посылаем наш запрос (или какой скрипт задействуем). В данном случае мы, благодаря PHP, будем каждый раз отрисовывать адрес текущей страницы. В атрибуте action мы могли бы просто напрямую указать PHP скрипт, который бы обрабатывал данные пришедшие с формы, но тогда любой человек (в том числе и хакер) мог бы просмотреть путь до нашего PHP файла и даже попытаться сделать что-нибудь вредоносное. Перечислять все возможные попытки взлома, зная прямой путь к нужному файлу я не вижу смысла, могу только сказать, что если вы не предусмотрели элементарных проверок на стороне сервера (то есть на PHP), злоумышленник может напрямую обращаться к вашему скрипту, который будет постоянно отправлять пустые сообщения вам (или владельцу) на почту. Более подробно о защите от прямого обращения к файлу и как это реализовано в Joomla читайте по ссылке.
Далее идут поля, которые будут заполнять наши посетители – это два поля input и одна textarea. Посмотрим из чего у нас состоят наши инпуты:
<input required="required" maxlength="30" type="text" name="name" />
Первым идёт атрибут required, который, по-моему, считается невалидным внутри тега input, но зацикливаться на валидности глупо, поэтому ничего страшного. Этот атрибут говорит о том, что данное поле обязательно для заполнения, посетитель не сможет отправить свой вопрос, пока не заполнит данное поле. Если поле необязательно, просто не пишете этот атрибут вовсе.
Затем идёт необязательный атрибут – maxlength. С помощью него вы можете указать максимальное количество символов, которое пользователь может ввести в данную форму.
И последний атрибут – name, самый главный и обязательный атрибут. В нём мы записываем имя данного тега. Зачем оно нужно поговорим чуть позже.
Тег textarea служит нам для того, чтобы пользователь мог написать своё сообщение. В отличие от input, здесь пользователь может делать перенос текста на новую строку:
<textarea rows="7" cols="50" required="required" name="message">Пожалуйста, перезвоните на указанный номер.</textarea>
В теге textarea атрибуты rows и cols обозначают размеры нашего поля в строчках (по вертикали) и количестве символов (по горизонтали). Вот такие вот странные и некроссбраузерные единицы измерения :)
Следующим в нашем списке идёт необязательный скрытый input:
<input type="hidden" name="check" value="fd13vv" />
Я его использую, чтобы определить из какой именно формы пришли данные, однако вы можете его не использовать и делать это по-другому. В атрибут value (значение) я записываю первое, что пришло мне в голову (fd13vv), чтобы потом проверять на совпадение с этим значением, скоро вы всё поймёте.
И конечно же, кнопка отправить:
<input type="submit" value="Отправить!" />
Итак, на данном этапе наша форма имеет следующий вид:
Вторым этапом мы должны создать PHP скрипт, который будет получать данные из формы, обрабатывать их и отправлять письмо. Назовём наш файл callback.php
Каким будет алгоритм наших действий? Для начала предлагаю проверить, пришли ли нам все нужные данные, если не пришли, то можно вывести пользователю ошибку, а можно ничего не делать и просто продолжить работу сайта, как ни в чём не бывало. Но так как пользователь (не хакер) и так не сможет отправить нам пустые поля, то нам не для кого выводить ошибку. Проверку делаем с помощью нашего любимого условного оператора в PHP:
if(!empty($_POST['name']) and !empty($_POST['phone']) and !empty($_POST['message'])){
// ...
}
Обратите внимание: здесь мы и используем наш атрибут name и его значения!
Далее логичным шагом будет отфильтровать полученные данные и хотя бы минимально обезопасить себя, а именно вычистим всё от HTML тегов и удалим лишние пробелы:
$name = trim(strip_tags($_POST['name'])); $phone = trim(strip_tags($_POST['phone'])); $message = trim(strip_tags($_POST['message']));
Далее всё зависит от вашей паранойи, так как различных проверок и фильтраций можно придумать до бесконечности. Минимальные требования мы выполнили, теперь можно формировать текст письма и отправлять его:
mail('email@mail.ru', 'Callback', 'Вам написал: '.$name.'<br />Его номер: '.$phone.'<br />Его сообщение: '.$mess,"Content-type:text/html;charset=utf-8");
Для этого мы использовали встроенную функцию PHP – mail(), первое значение обозначает адрес получателя, второе – тему письма, третье – текст письма и четвёртое (необязательное) – кодировку письма. Как видите, при построении текста письма я использовал переменные и конкатенацию.
После отправки письма необходимо перезагрузить страницу:
header("Location: ${_SERVER['REQUEST_URI']}");
die;
Для того чтобы удостовериться что PHP скрипты ещё не перезагруженной страницы не продолжат зря работать, мы использовали языковую конструкцию die.
Если мы хотим вывести сообщение об успешной отправке письма, то должны послать пользователю куку:
setcookie('mail', 'sendmail');
В итоге наш PHP скрипт для обработки формы обратной связи выглядит следующим образом:
<?php
if(!empty($_POST['name']) and !empty($_POST['phone']) and !empty($_POST['message'])){
$name = trim(strip_tags($_POST['name']));
$phone = trim(strip_tags($_POST['phone']));
$message = trim(strip_tags($_POST['message']));
setcookie('mail', 'sendmail');
mail('email@mail.ru', 'Callback', 'Вам написал: '.$name.'<br />Его номер: '.$phone.'<br />Его сообщение: '.$message,"Content-type:text/html;charset=utf-8");
header("Location: ${_SERVER['REQUEST_URI']}");
die;
}
?>
Всё что нам осталось сделать, это прикрутить форму обратной связи к нашему сайту и красиво всё оформить. Я покажу как это сделать на примере сайта на Joomla, для всех остальных сайтов и CMS суть будет точно такая же.
Заходим в главный файл нашего шаблона на Joomla – /templates/шаблон/index.php и как можно ближе к верху, например, сразу после строчки:
defined('_JEXEC') or die;
Вставляем следующий код:
if($_POST['check']=='fd13vv'){
include 'callback.php';
}
Здесь мы проверяем, пришло ли методом POST наше специальное значение из скрытого input, если пришло, значит можем подключать наш файл callback.php, который проверит и отфильтрует всё остальное.
Заметка:
Мы могли бы вставить весь код из файла callback.php в сам шаблон, то есть в index.php Но зачем зря увеличивать вес главного файла, учитывая что наш скрипт будет нужен далеко не каждому посетителю, а только тому кто отправит сообщение. Поэтому не зачем всех остальных заставлять скачивать лишний код.
Кстати говоря, я считаю, что лишних инклудов (include) тоже не стоит плодить, так как подключение файла занимает определённое (пусть и малое) время, всё нужно делать с умом и в меру.
Естественно, закачиваем наш файл callback.php в эту же папку (в корень папки с шаблоном).
Далее сразу после предыдущих строк делаем проверку на куки, которые мы посылаем только после успешной отправки письма:
if(isset($_COOKIE['mail'])){
$thanks = '<p align="center" style="color:green;font-size:26px">Спасибо за Ваше обращение!</p>';
setcookie('mail', "", time() - 3600);
}
Если проверка выдала TRUE, то заносим в переменную текст благодарности и удаляем куку. Затем там, где вы хотите вывести текст благодарности пишете:
<?php
if(!empty($thanks)){
echo $thanks;
}
?>
Осталось лишь красиво преподнести нашу форму. Я не буду растягивать статью объяснениями как работает CSS и JS, а просто выложу вам готовый код.
HTML код я разместил сразу после открывающегося тега body, но по большому счёту его можно вставить в любое место на странице:
<div onclick="openn(this)" id="callback"></div><div id="body-form">
<form method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>">
Имя: <input required="required" maxlength="30" type="text" name="name" />
Телефон: <input required="required" maxlength="30" type="text" name="phone" />
Сообщение: <br /><textarea rows="7" cols="50" required="required" name="message">Пожалуйста, перезвоните на указанный номер.</textarea>
<input type="hidden" name="check" value="fd13vv" />
<br /><input type="submit" value="Отправить!" />
</form>
</div>
Не ругайтесь на то, что я повесил обработку яваскрипта прямо в атрибут тега, это уже совсем другая история :)
Записываем CSS в ваш основной файл стилей (обычно это что-то типа: general.css, template.css, style.css) и не забываем изменить во второй строчке путь до картинки:
#body-form{position:fixed;width:456px;min-height:180px;top:38%;left:-486px;font-size:18px;box-shadow:0 0 15px 0 #000;-moz-box-shadow:0 0 15px 0 #000;-webkit-box-shadow:0 0 15px 0 #000;border-radius:0 7px 7px 0;-khtml-border-radius:0 7px 7px 0;-moz-border-radius:0 7px 7px 0;-webkit-border-radius:0 7px 7px 0;transition:margin-left 0.8s linear;-moz-transition:margin-left 0.8s linear;-webkit-transition:margin-left 0.8s linear;-o-transition:margin-left 0.8s linear;padding:10px;font-style:italic;background:#f5f5f5;z-index:9998;}
#callback{position:fixed;min-width:80px;min-height:200px;cursor:pointer;z-index:9999;top:38%;left:-15px;margin-right:-5px;background:url("/images/articles/php/callback.png") no-repeat;transition:margin-left 0.8s linear;-moz-transition:margin-left 0.8s linear;-webkit-transition:margin-left 0.8s linear;-o-transition:margin-left 0.8s linear;}
.leftOpened{margin-left:486px;} /* если ваша форма будет слева */
.rightOpened{margin-right:486px;} /* если ваша форма будет справа */
JS можно разместить в любом месте на странице или вынести в отдельный файл:
function addClass(el,cls){for(var c=el.className.split(" "),i=c.length-1;i>=0;i--)if(c[i]==cls)return;if(el.className=="")el.className=cls;else el.className+=" "+cls}function hasClass(el,cls){for(var c=el.className.split(" "),i=c.length-1;i>=0;i--)if(c[i]==cls)return true}function removeClass(el,cls){for(var c=el.className.split(" "),i=c.length-1;i>=0;i--)if(c[i]==cls)c.splice(i,1);el.className=c.join(" ")}
function openn(obj){var next=obj.nextSibling;var style=window.getComputedStyle?getComputedStyle(obj,""):obj.currentStyle;if(parseInt(style.left)<0)var open="leftOpened";else var open="rightOpened";if(hasClass(obj,open)){removeClass(obj,open);removeClass(next,open)}else{addClass(obj,open);addClass(next,open)}};
PHP:
<?php
defined('_JEXEC') or die; // добавили защиту Joomla
if(!empty($_POST['name']) and !empty($_POST['phone']) and !empty($_POST['message'])){
$name = trim(strip_tags($_POST['name']));
$phone = trim(strip_tags($_POST['phone']));
$message = trim(strip_tags($_POST['message']));
setcookie('mail', 'sendmail');
mail('email@mail.ru', 'Callback', 'Вам написал: '.$name.'<br />Его номер: '.$phone.'<br />Его сообщение: '.$message,"Content-type:text/html;charset=utf-8");
header("Location: ${_SERVER['REQUEST_URI']}");
die;
}
?>
Незабываем в каждом новом PHP файле первой строчкой подключать защиту Joomla или вашу защиту от прямого обращения к PHP скриптам, конечно, если она у вас есть.
Скачать картинку «обратная связь» вы можете сохранив данный рисунок:
Заметки:
Вы можете изменить положение формы обратной связи, чтобы она была справа, а не слева. Для этого вам нужно отредактировать пару значений в CSS, а также повернуть саму картинку. При этом вам НЕ нужно изменять JS, HTML и PHP.
Если вы хотите из формы обратной связи сделать классический обратный звонок (только имя и телефон), вы можете просто удалить тег textarea, при этом не забудьте удалить проверку на него в файле callback.php.
Поздравляю, вы только что сделали свою собственную стильную форму обратной связи, задействовав при этом всего две строчки JS, пару строк CSS, а также совсем немного PHP и HTML. Если статья вам понравилась, предлагаю подписаться, чтобы не пропустить выход новых статей и кейсов, спасибо за внимание и удачи!
Пожалуйста, прокомментируйте, как Вам моя статья?