Доброго времени суток! Спасибо что заглянули на мой блог! Сегодня нам предстоит не легкая работа, если Вы следите за циклом "Создать блог с нуля", то должны знать, что пользовательский модуль контактов у нас не развивался очень давно, не имеет ни капчи ни проверки на корректность ввода информации. Если прикинуть, то по сути придется модуль переписать полностью, и это не учитывая того глюкас капчей который я обнаружил совсем недавно.
Но капча еще подождет, внесенные в нее изменения не слишком глобальны, так что пока поработает в таком режиме.
Я отвлекся =) Так вот, сегодня нам необходимо будет:
Не большая заметка, для тех кто на блоге в первые. Так как этот пост является частью цикла "Создать блог с нуля" то вполне вероятно, что материал изложенный в данном посте не имеет для Вас никакой ценности. Цикл рассчитан на аудиторию которая хочет без лишней теории освоить язык программирования php,
Мы пишем довольно не сложно, и функциональный движок персонального блога. Эти практические статьи можно расценивать как уроки php, так что если Вы заинтересованны в данном цикле, то переходите по ссылке выше, и приступайте к обучению, а именно к написанию своего первого проекта на php
Если Вы планируете задержаться на моем блоге, то обязательно подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы точно не пропустите новые заметки цикла!
Первым делом нам необходимо переделать шаблон (шаблон очень похож на шаблон формы комментариев), а именно:
В общем все очень похоже на форму комментариев, за исключением несколько дополнительных полей, и атрибутов name и id. Вот полный код шаблона
<p style="width:500px;" align="center">Если Вам нужно, по какой то причине связаться со мной, то Вы можете это сделать через форму обратной связи, которую Вы видите ниже.</p><br/>
[_error]
<br/>
<form action="[_action]" method="post" name="form2">
<input class="input" name="author_contact" id="author_contact" onclick="if(document.getElementById('author_contact').value == 'Введите имя*')document.getElementById('author_contact').value = '';" type="text" value="Введите имя*">
<br>
<input class="input" name="email_contact" id="email_contact" onclick="if(document.getElementById('email_contact').value == 'E-mail*')document.getElementById('email_contact').value = '';" type="text" value="E-mail*">
<br>
<input class="input" name="them_contact" id="them_contact" onclick="if(document.getElementById('them_contact').value == 'Тема*')document.getElementById('them_contact').value = '';" type="text" value="Тема*">
<br>
<textarea class="input" name="txt_contact" id="txt_contact" onclick="if(document.getElementById('txt_contact').value == 'Введите текст*')document.getElementById('txt_contact').value = '';" rows="10">Введите текст*</textarea>
<br><br>
<p style="margin:0px;">Если вы человек, то нажмите на картинку "<span style="font-weight:bold;">[_q]</span>"</p>
<br>
<input id="code_comm" name="code_contact" type="hidden" value="">
<table width="160px" height="40px" cellpadding="0" cellspacing="0" border="0px">
<tr>
<td>
<img id="cp1OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(1,'[_code0]');" src="[_img0]" border="0px">
</td>
<td>
<img id="cp2OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(2,'[_code1]');" src="[_img1]" border="0px">
</td>
<td>
<img id="cp3OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(3,'[_code2]');" src="[_img2]" border="0px">
</td>
<td>
<img id="cp4OK" style="position:absolute;display:none;" src="img/okCPha.png" border="0px">
<img style="cursor:pointer;" onclick="capcha(4,'[_code3]');" src="[_img3]" border="0px">
</td>
</tr>
</table>
<br>
<p><input class="sub" type="submit" value="Отправить сообщение"></p>
</form>
Думаю проблем, в понимание, у Вас тут не возникнет. Мы подобный шаблон уже делали!
Прежде чем приступить к написанию функций, необходимо поговорить о ее функционале. Дело в том что функция должна выдавать два вида результатов
Вопрос, как определить какой именно результат должна вывести функция? Раньше условием было пере направления пользователя на страницу с таким адресом
http://имя сайта/index.php?contact=2
При этом страница с формой была по адресу
http://имя сайта/index.php?contact=1
То есть если переменная contact была равна единице, то пользователь видел форму, а если переменная равнялась двум, то пользователь видел сообщение об удачной отправки.
Теперь такой вариант не пройдет, ибо при включенном ЧПУ ссылка будет вот такого вида:
http://имя сайта/contacts.html
И менять ее не красиво =) Именно поэтому я решил использовать cookie.
Cookie (куки) - не большой файл, созданный веб-страничкой, и хранится он на компьютере пользователя.
Если конкретно, куки это эдакая переменная, которая лежит на компе пользователя и доступна даже если загрузится страничка на которой эта переменная не объявляется. Как раз то, что нам нужно!
Я предлагаю следующий алгоритм:
В общем к чему я веду. Прежде чем мы начнем писать функцию вывода формы/сообщения, нам понадобится создать две функции:
Вот код обеих функций, поместите их в файле contact.php, в самом низу
function contactCOOKIE($server_root)//функция создание куки
{
preg_match("/http:\/\/(.*?)\//s",$server_root,$cookieSITE);//чистим переменную с доменом от http://
$cookieSITE = str_replace("www.","",$cookieSITE[1]);//чистим имя домена от www
setcookie("contMESS","YES",time()+300,"/",".".$cookieSITE);//создаем куку, время жизни 5 минут
}
//----------------------------------
function contactCOOKIEdel($server_root)//функция уничтожения куки
{
preg_match("/http:\/\/(.*?)\//s",$server_root,$cookieSITE);//чистим переменную с доменом от http://
$cookieSITE = str_replace("www.","",$cookieSITE[1]);//чистим имя домена от www
setcookie("contMESS","",time()-300,"/",".".$cookieSITE);//назначаем время на минус 5 минут от сейчас
//тем самым кука считается старой и уже не действует
}
Встроенная в php, функция setcookie() позволяет нам создать маленький файл (куку).
Советую почитать подробнее про эту функцию, ибо я про нее знаю лишь поверхностно!
Немного о функциях, код которых я Вам дал. Ничего сложного в них нет. Первая функция (contactCOOKIE()) создает куку, которая будет жить 5 минут. Вторая функция (contactCOOKIEdel()) принудительно делает маленький файл, устаревшим, тем самым кука удаляется.
Функция переписана полностью, поэтому лучше скопируйте ее и замените
function contact($mess,$error,$chpu,$server_root)//функция вывода формы
{
if($mess == 1)//Если пользователь еще не отправлял сообщение
{
$sm_read = file("templates/contacts.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
//Вывод ошибки
if($error != "")//если есть ошибки
{
$error = explode("|",$error);//превращаем строку в массив
$echoERROR .= "<p style='color:red;margin:0px;'>Обнаружены следующие ошибки:</p>";//заголовок
for($i=0;isset($error[$i]);$i++)//цикл формирующий список ошибок
{
if($error[$i] != "")$echoERROR .= "<p style='color:red;margin:0px;'>>$error[$i]</p>";//ошибки
}
$sm_read = str_replace("[_error]",$echoERROR,$sm_read);//вывод ошибок на экран
}
else $sm_read = str_replace("[_error]","",$sm_read);//если ошибок нет, то удаляем код-слово
//Вывод ошибки
//капча
include ("moduls/capcha.php");//подключаем модуль капчи
$cods = capcha();//формируем массив с кодами
for($i=0;$i<4;$i++)//цикл вывода инфы из массива
{
$sm_read = str_replace("[_code".$i."]",$cods[$i][1],$sm_read);//вставляем 4 кода в форму
$sm_read = str_replace("[_img".$i."]",$cods[$i][3],$sm_read);//вставляем 4 изображения в форму
if($cods[$i][5] == "true")$sm_read = str_replace("[_q]",$cods[$i][4],$sm_read);//вклеиваем вопрос в форму
}
//капча
}
if($mess == 2)//Если пользователь уже отправил сообщение
{
$sm_read = "<p align='center'>Ваше сообщение отправлено</p>";//Пользователь увидит следующее сообщение
contactCOOKIEdel($server_root);//функция удаления куки с уведомлением о отправки сообщения
}
if($chpu == 0)$action = "index.php?contact=1";//если чпу отключен, то выводим динамическую ссылку в атрибут action
else $action = "contacts.html";//если чпу включен выводим чпу в атрибут action
$sm_read = str_replace("[_action]",$action,$sm_read);//адрес обработчика
return $sm_read;//Выводим с генерированный html код
}
Параметры функции следующие:
Первая часть функции содержит код вывода формы, так же определение ошибок (если есть) и подключение капчи (в коде есть комментарии)
Вторая часть функции содержит текст уведомления пользователя, так же в этой части запускается функция удаления куки.
Тут я тоже выложу полный код обработчика, если кто не знает, его необходимо поместить в самый верх файла contact.php
//--------------ОБРАБОТЧИК КОНТАКТОВ
$date_day = date("d");//Определяем день
$date_month = date("m");//Определяем месяц
$date_year = date("Y");//Определяем год
$date_time = date("H:i");//Определяем часы и минуты
$date_cont = $date_day."/".$date_month."/".$date_year." ".$date_time;//Склеим все переменные в одну
//получим дату для записи в формате день/месяц/год часы:минуты
//Определяем посланные переменные из формы
if(isset($_POST['author_contact']))$author_contact = $_POST['author_contact'];
if(isset($_POST['email_contact']))$email_contact = $_POST['email_contact'];
if(isset($_POST['them_contact']))$them_contact = $_POST['them_contact'];
if(isset($_POST['txt_contact']))$txt_contact = $_POST['txt_contact'];
if(isset($_POST['code_contact']))$code_contact = $_POST['code_contact'];
if(isset($author_contact) & isset($email_contact) & isset($them_contact) & isset($txt_contact))//Если посланные переменные определены как существующие
{
//Переводим html код (если есть) в каракозябры =)
//В общем то тут несколько лишних строк, но у меня паранойя, поэтому я проверяю ВСЕ переменные
$txt_contact = htmlspecialchars($txt_contact);
$them_contact = htmlspecialchars($them_contact);
//проверка кода
if($code_contact != "")//Если поле было заполнено
{
session_start();//открываем сессию
if(md5($code_contact) != $_SESSION['code'])$error_contact .= "Вы выбрали не ту картинку!|";//Если код не правильный
unset($_SESSION['code']);//уничтожаем код
session_destroy();//уничтожаем сессию
}
else $error_contact .= "Вы не подтвердили, что Вы человек|";//если поле не заполнялось
//проверка поля 'автор'
if($author_contact != "" AND $author_contact != "Введите имя*")//Если поле было заполнено
{
//проверчем корректность ввода имени, только русские и английские буквы, ни каких символов кроме - _ и пробела
if(!preg_match("/^[-_0-9a-zA-Zа-яА-Я ]+$/s",$author_contact))$error_contact .= "Не правильный формат поля 'Введите имя'|";
//поле не должно содержать более 25 символов
if(mb_strlen($author_contact) > 25)$error_contact .= "В поле 'Введите имя' слишком много символов|";
}
else $error_contact .= "Вы не заполнили поле 'Введите имя'|";//если поле не заполнялось
//проверяем заполняли ли поле текст
if($txt_contact == "" OR $txt_contact == "Введите текст*")$error_contact .= "Вы не заполнили поле 'Введите текст'|";
//проверка поля емайл
if($email_contact != "" AND $email_contact != "E-mail*")//если поле было заполнено
{
//проверяем на корректность ввода (по сути отсеиваем не нужные символы в переменной)
if(!preg_match("/^[-_a-zA-Z0-9.]+@[-_a-zA-Z0-9.]+\.[-_a-zA-Z]+$/s",$email_contact))$error_contact .= "Вы ввели некорректный E-mail|";
}
else $error_contact .= "Вы не заполнили поле 'E-mail'|";//если поле не заполнялось
//проверка адреса сайта
if($them_contact != "" AND $them_contact != "Тема*")//Если поле заполнили
{
if(mb_strlen($them_contact) > 250)$error_contact .= "В поле 'Тема' слишком много символов|";
}
else $error_contact .= "Вы не заполнили поле 'Тема'|";//если поле не заполнялось
if(!isset($error_contact))
{
//Избавляемся от кавычки
$them_contact = str_replace("'","'",$them_contact);
$txt_contact = str_replace("'","'",$txt_contact);
$txt_contact = str_replace("\n","<BR>",$txt_contact);//Заменяем переносы строки на тег <BR>
//ДОБАВЛЯЕМ СООБЩЕНИЕ В БАЗУ ДАННЫХ
$result_add_cont = mysql_query ("INSERT INTO mess_admin (login,them,date_g,email,text)
VALUES ('$author_contact','$them_contact','$date_cont','$email_contact','$txt_contact')");
//ДОБАВЛЯЕМ СООБЩЕНИЕ В БАЗУ ДАННЫХ
//ИЛИ
//ООТПРАВЛЯЕМ СООБЩЕНИЕ ПО ПОЧТЕ
//$to = "test@test.ru";//Ваш почтовый адрес
//$txt_contact = $author_contact." <".$email_contact."> Вам пишет: ".$txt_contact;//Приклеиваем к тексту сообщения
//контактную информацию отправителя
//mail($to,$them_contact,$txt_contact);//Собственно сама отправка
//ООТПРАВЛЯЕМ СООБЩЕНИЕ ПО ПОЧТЕ
contactCOOKIE($server_root);//функция которая создаст куку с уведомлением о том что сообщение отправленно
header("location: ".getenv('HTTP_REFERER'));//Перенаправляем пользователя
exit;//к сообщениею об успешной отправки
}
}
//--------------ОБРАБОТЧИК КОНТАКТОВ
Обработчик контактов почти полный аналог обработчика комментариев. Комментировать тут особо нечего, мы уже столько раз писали подобные коды. Единственное, что хочу сказать, так это то, что в обработчике, сразу после отправки сообщения в базу данных, или же на почту (кстати код отвечающий за отправку на почту за комментирован) стоит вызов функции создания куки. В общем то это все, что я хотел сказать.
Нам осталось совсем не много, так что давайте уже заканчивать =)
Открываем файл пользовательский файл index.php и правим в нем подключение модуля
//МОДУЛЬ КОНТАКТЫ
if($contact)//Если существует переменная
{//то
include("moduls/contact.php");//подключаем модуль
if(!isset($error_contact))$error_contact = "";//Если ошибок нет, то заносим в переменную пустоту
if(isset($_COOKIE['contMESS']))$contact = 2;//если существует кука, то выводим меняем значение
//переменной, так пользователь увидит сообщение о удачной отправки
$txt = contact($contact,$error_contact,$chpu,$server_root);//Выводим результат функции в переменную, которая отобразится на экране пользователя
}
//МОДУЛЬ КОНТАКТЫ
Как видите, если кука существует, то переменная contact примет значение - два. После чего пользователь не увидит форму, а увидит сообщение о удачной отправки письма. В противном же случае переменная contact останется равной единице, что приведет к отображению формы.
Открываем шаблон comm_form.html и вырезаем из нее функцию капчи и функцию плавного перемещения к комментарию. Было бы очень плохо оставить эти две функции в шаблоне, поэтому давайте перенесем их в файл js.js
Теперь открываем файл js.js и вставляем в него вырезанные функции
function capcha(v,val)
{
document.getElementById("code_comm").value = "";
for(var i=1;i<=4;i++)document.getElementById("cp"+i+"OK").style.display = "none";
document.getElementById("cp"+v+"OK").style.display = "block";
document.getElementById("code_comm").value = val;
}
//--------------------------------------
function reqcomm(id,author,step)
{
if(step == 0)
{
document.getElementById("recomm").value = id;
document.getElementById("reauthor").innerHTML = author;
document.getElementById("messFROM").style.display = "block";
jQuery.scrollTo('#messFROM',1000);
}
if(step == 1)
{
document.getElementById("recomm").value = id;
document.getElementById("reauthor").innerHTML = author;
document.getElementById("messFROM").style.display = "none";
}
footer();
}
Если не перенести функцию капчи в общий файл с функциями javascript, то капча контактов работать не будет
После проделанной работы, наш модуль контактов будет работать по тому же принципу как модуль комментариев. При этом атрибут action у формы контактов будет принимать двоякое значение, все зависит от того включен режим ЧПУ или нет
Если у Вас что-то не получается, то пользуйтесь формой ниже, я обязательно попробую Вам помочь. Если Вы еще не подписаны на мой блог, то обязательно подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы точно не пропустите новые заметки цикла!
Всего Вам наилучшего! У меня Все!
Исходник |
_______
P.S.: Если Вы сталкивались с вопросом продления лицензии на услуги связи для своей компании, то обратитесь за помощью к людям из ИнфоСвязь Консалтинг, по ссылке www.license-pro.ru/prolong.html
Собственно, я хотел бы задать вопрос. Почему в своих примерах (комментарии/контакты), Вы делали обработку вводимых данных на сервере средствами php, а не js?
Вопрос появился после того, как я закончил с этой статьей, и проверил модуль контактов. Если была допущена ошибка при заполнении формы, например при вводе капчи, все заполненные данные теряются. Это не критично, но все же, не совсем приятно.