Доброго времени суток дорогой читатель Блога RS! Сегодня мы расширим функционал нашего пользовательского модуля комментариев. Поделю этот пост на несколько частей, ибо в планах развить функционал хотя бы до уровня моего рабочего блога. А именно добавить пару новых полей, обезопасить проверками эти поля. Реализовать вывод ошибок, добавить возможность из имени автора делать ссылку на сайт автора, так же необходимо написать капчу, ну и на по следок вывести аватарки с gravatar. Сегодня мы реализуем лишь часть намеченного.
Давайте я опубликую цели на сегодня. Так вот чем мы займемся:
На этом мы пока тормознем. Капчу напишем в следующий раз, если Вам интересна эта информация и блог в целом, то подпишитесь на RSS ленту блога через ридер, или же по почте
Этот пост, как и многие другие на моем блоге, являются продолжением цикла статей "Разработка блога с нуля", поэтому если Вы на блоге впервые, то данный пост Вам может показаться бесполезным, ибо описаны правка файлов которых у Вас нет! Если Вы хотите научится, на практике, создавать свои проекты на php то читайте цикл с самого начала.
Как я уже написал выше, править будем шаблон comm_form.html. Открываем его. Я вывешу вам полностью готовый код шаблона, и поясню что в нем нового
<p>Оставить комментарий</p>
[_error]
<form action="index.php?blog=[_id]#bottom" method="post" name="form">
<input name="id_comm" type="hidden" value="[_id]">
<br>
<input class="input" name="author_comm" id="author_comm" onclick="if(document.getElementById('author_comm').value == 'Автор*')document.getElementById('author_comm').value = ''" type="text" value="Автор*">
<br>
<input class="input" name="email_comm" id="email_comm" onclick="if(document.getElementById('email_comm').value == 'E-Mail* (не публикуется)')document.getElementById('email_comm').value = ''" type="text" value="E-Mail* (не публикуется)">
<br>
<input class="input" name="site_comm" id="site_comm" type="text" value="http://">
<br>
<textarea class="input" name="txt_comm" id="txt_comm" onclick="if(document.getElementById('txt_comm').value == 'Введите текст*')document.getElementById('txt_comm').value = ''" rows="10">Введите текст*</textarea>
<br><br><input class="sub" type="submit" value="Оставить комментарий">
</form>
<a name="bottom"></a>
Давайте по порядку.
В html есть возможность перемещаться по странице с помощью внутренних ссылок, эти внутренние ссылки называют якорем. Вы наверняка видели работу этих якорей. В FAQ'ах, на форумах, гостевых, и даже на блогах во время написание комментария, или переход к определенному комментарию. Посмотрите на шаблон, в самый низ. Вы увидите там ссылку вот такого вида
<a name="bottom"></a>
Если к концу url'а добавить "#" и значение атрибута name ссылки якоря, то есть "bottom", то при переходе по такому url
http://имя_сайта_и_др_get_переменные#bottom
Нас перекинет в ту часть страницы, где расположена эта ссылка-якорь.
Вот как это работает на примере моего блога
При щелчке по такой ссылке с якорем, пользователя переносит сразу к комментария минуя весь текст поста. При этом ссылка
<a href="comm"></a>
стремиться находиться в самом вверху браузера. Таким образом пользователь сразу видит первый комментарий, ему не нужно крутить вертикальный скоролл! Надеюсь понятна суть якорей
onclick="if(document.getElementById('author_comm').value == 'Автор*')document.getElementById('author_comm').value = ''"
Если пользователь кликнул по полю, то идет проверка на наличие в поле текста - "Автор*". Если этот текст есть в поле, то чистим поле. Очень маленький и очень полезный скрипт
Вот как сейчас выглядит форма
Перед тем как мы займемся редактированием модуля нам необходимо создать две новых колонки в базе данных. Заходим в структуру таблицы comm. После author добавляем две новых колонки email и site. Тип у них я сделал varchar 255.
Вот полный код обработчика в модуле comm.php
//--------------ОБРАБОТЧИК КОММЕТАРИЕВ
$date_day = date("d");//Определяем день
$date_month = date("m");//Определяем месяц
$date_year = date("Y");//Определяем год
$date_time = date("H:i");//Определяем часы и минуты
$date_comm = $date_day."/".$date_month."/".$date_year." ".$date_time;//Склеим все переменные в одну
//получим дату для записи в формате день/месяц/год часы:минуты
//Определяем посланные переменные из формы
if(isset($_POST['id_comm']))$id_comm = $_POST['id_comm'];
if(isset($_POST['txt_comm']))$txt_comm = $_POST['txt_comm'];
if(isset($_POST['author_comm']))$author_comm = $_POST['author_comm'];
if(isset($_POST['email_comm']))$email_comm = $_POST['email_comm'];
if(isset($_POST['site_comm']))$site_comm = $_POST['site_comm'];
if(isset($id_comm) & isset($txt_comm) & isset($author_comm))//Если посланные переменные определены как существующие
{
//Переводим html код (если есть) в каракозябры =)
//В общем то тут несколько лишних строк, но у меня паранойя, поэтому я проверяю ВСЕ переменные
$id_comm = htmlspecialchars($id_comm);
$txt_comm = htmlspecialchars($txt_comm);
//проверка поля 'автор'
if($author_comm != "" AND $author_comm != "Автор*")//Если поле было заполнено
{
//проверчем корректность ввода имени, только русские и английские буквы, ни каких символов кроме - _ и пробела
if(!preg_match("/^[-_0-9a-zA-Zа-яА-Я ]+$/s",$author_comm))$error_comm .= "Не правильный формат поля 'Автор'|";
//поле не должно содержать более 25 символов
if(mb_strlen($author_comm) > 25)$error_comm .= "В поле 'Автор' слишком много символов|";
}
else $error_comm .= "Вы не заполнили поле 'Автор'|";//если поле не заполнялось
//проверяем заполняли ли поле текст
if($txt_comm == "" OR $txt_comm == "Введите текст*")$error_comm .= "Вы не заполнили поле 'Текст'|";
//проверка поля емайл
if($email_comm != "" AND $email_comm != "E-Mail* (не публикуется)")//если поле было заполнено
{
//проверяем на корректность ввода (по сути отсеиваем не нужные символы в переменной)
if(!preg_match("/^[-_a-zA-Z0-9]+@[-_a-zA-Z0-9]+\.[-_a-zA-Z]+$/s",$email_comm))$error_comm .= "Вы ввели некорректный E-mail|";
}
else $error_comm .= "Вы не заполнили поле 'E-mail'|";//если поле не заполнялось
//проверка адреса сайта
if($site_comm != "" AND $site_comm != "http://")//Если поле заполнили
{
//проверяем приблизительную корректность адреса (по сути просто отсеиваем не нужные символы в переменной)
if(!preg_match("/^http:\/\/[-_a-zа-я0-9.]+\.[a-zа-я]+$/s",$site_comm))$error_comm .= "Некорректно введенный адрес сайта|";
}
else $site_comm = "";//создаем пустую, безопасную переменную для записи в БД
if(!isset($error_comm))
{
//Избавляемся от кавычки
$id_comm = str_replace("'","'",$id_comm);
$txt_comm = str_replace("'","'",$txt_comm);
$txt_comm = str_replace("\n","<BR>",$txt_comm);//Заменяем переносы строки на тег <BR>
//Добавляем сообщение в базу данных
$result_add_comm = mysql_query ("INSERT INTO comm (author,text,date_comm,blog,email,site)
VALUES ('$author_comm','$txt_comm','$date_comm','$id_comm','$email_comm','$site_comm')");
header("location: index.php?blog=$blog#bottom");//Перенаправляем пользователя
exit;//обратно к форме с комментариями
}
}
//--------------ОБРАБОТЧИК КОММЕТАРИЕВ
По порядку изменения обработчика:
if(isset($_POST['email_comm']))$email_comm = $_POST['email_comm'];
if(isset($_POST['site_comm']))$site_comm = $_POST['site_comm'];
//проверка поля 'автор'
if($author_comm != "" AND $author_comm != "Автор*")//Если поле было заполнено
{
//проверчем корректность ввода имени, только русские и английские буквы, ни каких символов кроме - _ и пробела
if(!preg_match("/^[-_0-9a-zA-Zа-яА-Я ]+$/s",$author_comm))$error_comm .= "Не правильный формат поля 'Автор'|";
//поле не должно содержать более 25 символов
if(mb_strlen($author_comm) > 25)$error_comm .= "В поле 'Автор' слишком много символов|";
}
else $error_comm .= "Вы не заполнили поле 'Автор'|";//если поле не заполнялось
Для начала мы проверим заполнили ли поле вообще. Если нет то создастся переменная error_comm которая будет содержать ошибки обработчика. Если поля заполняли, то мы с помощью регулярного выражения определяем допустимые символы, а именно мы разрешаем русские и английский символы, подчеркивание ( "_" ), тире ( "-" ) и пробел. Все остальные символы не доступны, и если будут обнаружены создастся переменная error_comm с текстом ошибки.
После проверки на корректность ввода пройдет проверка на длину. Имя автора должно быть не длиннее 25 символов. Функция mb_strlen(переменная) позволяет определить сколько символов в переменной. Если в переменой больше 25 символов, то создастся переменная с ошибкой
//проверяем заполняли ли поле текст
if($txt_comm == "" OR $txt_comm == "Введите текст*")$error_comm .= "Вы не заполнили поле 'Текст'|";
В случае если пользователь не написал сообщение, но отправил форму, ему высветится сообщение о ошибке.
//проверка поля емайл
if($email_comm != "" AND $email_comm != "E-Mail* (не публикуется)")//если поле было заполнено
{
//проверяем на корректность ввода (по сути отсеиваем не нужные символы в переменной)
if(!preg_match("/^[-_a-zA-Z0-9]+@[-_a-zA-Z0-9]+\.[-_a-zA-Z]+$/s",$email_comm))$error_comm .= "Вы ввели некорректный E-mail|";
}
else $error_comm .= "Вы не заполнили поле 'E-mail'|";//если поле не заполнялось
Как и в случае с проверкой имени автора, тут первым делом определяется было ли заполнено поле. Если нет то обработчик выдаст ошибку. Если же был заполнен, то с помощью регулярного выражение определяется корректность ящика.
//проверка адреса сайта
if($site_comm != "" AND $site_comm != "http://")//Если поле заполнили
{
//проверяем приблизительную корректность адреса (по сути просто отсеиваем не нужные символы в переменной)
if(!preg_match("/^http:\/\/[-_a-zа-я0-9.]+\.[a-zа-я]+$/s",$site_comm))$error_comm .= "Некорректно введенный адрес сайта|";
}
else $site_comm = "";//создаем пустую, безопасную переменную для записи в БД
Так как адрес сайта это не обязательное поле, то не заполнение его не создаст ошибку. Поэтому проверка на корректность происходит только в случае если сайт пользователь ввел. Если проверка на корректность не пройдена, то создается переменная с ошибкой.
if(!isset($error_comm))
{
...
}
Вообще весь код за комментирован, проблем в освоение новых строк быть не должно.
Мне придется опять выложить Вам полный код этой функции, так что мужайтесь
function comm($blog,$error)//функция вывода комментариев
{
$result_index = mysql_query("SELECT * FROM comm WHERE blog='$blog' ORDER BY id");//Выводим из базы данных все записи где blog равен ID поста
$myrow_index = mysql_fetch_array($result_index);
if($myrow_index != "")//Проверяем есть ли в базе данных записи
{//Если есть...
$sm_read = file("templates/comm.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
do//Цикл do while
{
$edd_tamp = $sm_read;//Так как на придется править шаблон,
//то лучше его сохранить в отдельную переменную, иначе нам придется
//пользоваться функцией file() чаще чем 1 раз, а это нагрузка на сервер
//Замены идентификаторов на переменные из базы данных
//узнаем пустая ли пеерменная которая хранит адрес сайта
if($myrow_index[site] != "")$author = "<a href='".$myrow_index[site]."' rel='nofollow'>".$myrow_index[author]."</a>";//если не пустая формируем ссылку
else $author = $myrow_index[author];//если пустая, то просто сохраняем автора в переменной
$edd_tamp = str_replace("[_text]",$myrow_index[text],$edd_tamp);//Текст
$edd_tamp = str_replace("[_author]",$author,$edd_tamp);//Автор статьи
$edd_tamp = str_replace("[_date_b]",$myrow_index[date_comm],$edd_tamp);//Дата размещения
$comm .= $edd_tamp;// Склеиваем весь с генерированный код в одну переменную
}
while($myrow_index = mysql_fetch_array($result_index));
}
else $comm = "<p align='center'>Комментариев нет, Вы будите первым =)</p>";//Если записей нет, то вывести это сообщение
$form = file("templates/comm_form.html");//подключаем шаблон с формой
$form = implode("",$form);//функция 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>";//ошибки
}
$form = str_replace("[_error]",$echoERROR,$form);//вывод ошибок на экран
}
else $form = str_replace("[_error]","",$form);//если ошибок нет, то удаляем код-слово
//Вывод ошибки
$form = str_replace("[_id]",$blog,$form);//вклеиваем id cтатьи в форму
$comm .= $form;
return $comm;//Выводим с генерированный html код
}
Тут присутсвует несколько маленьких исправление, и одно крупное нововведение. Давайте опять по порядку:
function comm($blog,$error)//функция вывода комментариев
{
...
}
Я думаю Вы догадываетесь зачем она нужна
$result_index = mysql_query("SELECT * FROM comm WHERE blog='$blog' ORDER BY id");//Выводим из базы данных все записи где blog равен ID поста
if($myrow_index[site] != "")$author = "<a href='".$myrow_index[site]."' rel='nofollow'>".$myrow_index[author]."</a>";//если не пустая формируем ссылку
else $author = $myrow_index[author];//если пустая, то просто сохраняем автора в переменной
С помощью условия мы определяем пустая ли переменная, если пустая то создаем переменную author и прописываем в нее данные из базы данных. Если же не пустая, то формируем ссылку. В атрибут href попадает ссылка сайта, которую указал пользователь при отправки комментария. Атрибут rel содержит значение nofollow что позволяет не учитывать ссылку поисковиком. Я думаю Вы как начинающий блоггер знаете про этот атрибут
$edd_tamp = str_replace("[_author]",$author,$edd_tamp);//Автор статьи
//Код-слово теперь заменяется на с генерированную ранее переменную $author
//Вывод ошибки
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>";//ошибки
}
$form = str_replace("[_error]",$echoERROR,$form);//вывод ошибок на экран
}
else $form = str_replace("[_error]","",$form);//если ошибок нет, то удаляем код-слово
//Вывод ошибки
Суть проста. Определяем пустая ли переменная с ошибкой. Если нет, то делаем из нее массив с помощью функции explode("разделитель" переменная). Помните мы в тексте ошибки прописывали в конце разделитель "|"? Этот разделитель позволит теперь нам из переменной сделать массив. Далее циклом заносим ошибки в переменную echoERROR. После окончания этого цикла заменяем кодслово на эту переменную.
Если же переменная с ошибкой пуста, то просто заменяем код-слово на пустоту
Заходим в пользовательский файл index.php и редактируем подключение модуля комментариев
//МОДУЛЬ КОММЕНТОВ
if($blog)
{
include("moduls/comm.php");
if(!isset($error_comm))$error_comm = "";
$comm = comm($blog,$error_comm);//Выводим результат функции в переменную
$txt .= $comm;
}
//МОДУЛЬ КОММЕНТОВ
Если ошибок не было, то создаем переменную с ошибками и заносим туда пустоту. Думаю понятно для чего это нам нужно.
Ну что ж, если я ничего не забыл, то выглядеть это все будет приблизительно так
Что-то каждый такой пост все дается мне сложнее и сложнее. Опять я потратил уйму времени, а рассказал всего ничего
В следующем посте мы напишем капчу для нашей формы, так что не переключайтесь и подпишитесь на RSS ленту блога через ридер, или же по почте
Если есть какие вопросы пользуйтесь формой ниже, я с удовольствием поясню Вам непонятные моменты.
Всего Вам наилучшего! У меня все!
Исходник |
header (Location:) дело в том что если не создать файл .htaccess и не прописать в нем: "php_flag output_buffering On" то везде где стоит строчка header (Location:) будет выдавать ошибку ! особенно у тех кто denwerom пользуется
Может вы и так задумывали, но если что, то можно использовать такой подход:
<input class="input" name="author_comm" id="author_comm" onblur="if(this.value=='') this.value='Автор*'" onfocus="if(this.value=='Автор*') this.value=''"value="Автор*">
=)
Алексей извините что пришлось побеспокоить Вас. До сегодняшнего поста все получалось. Были конечно кое какие косячки, с моей стороны, справлялся сам. Все вроде правильно сделал, 10 раз перепроверил, но все равно выдает это:
>Не правильный формат поля 'Автор'
Спасибо!
Спасибо!