Codeigniter

Скрипт модуля - древовидные комментарии. Создание движка на Codeigniter + HMVC. Часть 7

Всем привет. В первую очередь хочу поздравить всех с наступившим Новым Годом! Пожелания можно почитать и оставить комментарий на странице с поздравлениями ;) И пока все гуляют, ходят в гости и едят оливье - мы с вами займемся написанием модуля комментариев. Модуль достаточно сложный, но разобравшись с ним - получите достаточно мощный инструмент обратной связи для вашего сайта.

Что же мы будем делать и что получим в итоге данного урока:

  • Сформированную и продуманную таблицу в бд для комментариев сайта
  • Список комментариев в виде дерева(возможность отвечать на отдельный комментарий)
  • Напишем рекурсивную функцию для вывода комментариев
  • Рендинг комментариев с помощью шаблона
  • Возможность выводить комментарии для любых отдельных модулей(страницы,категории,галереи и т.д.)
  • Отдельный шаблон для вывода формы комментирования
  • Еще один шаблон формы для ответа на комментарий
  • Небольшую защиту от флуда - запрет отправки более 1 комментария в течении 5 минут
  • Уведомление администратора сайта о новом комментарии на почту

Не маленький список задач мы составили, правда? Таблица комментариев mysql - будет очень похожа на таблицу движка ворд-пресс - это я заметил недавно, получив заказ на перенос всех страниц и комментариев со старого сайта клиента на разработанный мною новый! Хотя структура данной таблицы - похожа практически на всех движках;) Давайте приступим:

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `article_id` int(11) unsigned NOT NULL DEFAULT '0',
  `parent_id` int(11) unsigned NOT NULL DEFAULT '0',
  `type` varchar(255) NOT NULL DEFAULT '',
  `name` varchar(60) NOT NULL,
  `email` varchar(100) NOT NULL DEFAULT '',
  `site` varchar(200) NOT NULL DEFAULT '',
  `message` varchar(2000) NOT NULL,
  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `public` int(1) NOT NULL DEFAULT '1',
  `ip` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

По названиям полей - уже догадались что мы указываем:
article_id - ID статьи для которой оставляем комментарий
parent_id - ID родительского комментария, если это ответ
type - здесь указываем тип модуля, для страниц которого оставляем комментарий, в нашем движке пока существуют два типа: page и category
name - имя комментатора
email - почтовый адрес комментатора
site - пользователь может указать свой сайт (по желанию выводить имя в виде ссылки)
message - текст комментария(сейчас задана максимальная длина сообщения 2000 символов)
created - дата создания
public - комментарий опубликован или нет или на утверждении администратором
ip - адрес пользователя

image description

Все предельно просто.
Но что бы можно было запретить или разрешить вывод комментариев на отдельных страницах - понадобится так же добавить ячейку в таблицу pages с названием comments_on.
`comments_on` tinyint(1) DEFAULT NULL.
Если нужно открыть комментирование и выводить комментарии - то задаем единичку. Если не хотите выводить для данной статьи - нолик. Если вы планируете открыть комментарии не только для статей сайта но и для разделов - следует добавить такое же поле и для таблицы category.

Теперь создаем папку с модулем и следующие файлы:
/modules/comments/
/modules/comments/controllers/Comments.php
/modules/comments/libraries/Comments_lib.php
/modules/comments/models/Comments_model.tpl

В папке /themes/site создаем папку для шаблонов "comments" и в ней следующие файлы:
comment_disable.tpl
comment_final.tpl comment_final_reply.tpl comment_form.tpl
comment_reply_form.tpl
comment_index.tpl
comment_render.tpl

Задачу этих файлов можно понять по их названиям). Кстати - система работы модуля очень схожа с модулем формы.

Давайте заполним основной файл модуля Comments.php кодом - и подробнее познакомимся с системой работы:


Многие методы нашего нового класса Comments - точная копия Forms, который мы писали в предыдущей статье - настоятельно рекомендую ознакомится сперва с ним!

По порядку буду вкратце описывать логику всех функций:
get_all_comments($id, $comment_type) - думаю догадались ;) - выборка всех комментариев конкретного модуля для конкретной статьи. Сперва делаем выборку данных. Подсчитываем общее колличество комментариев для вывода числа на сайте. Далее с помощью библиотеки comments_lib и функции _build_comments - строим дерево комментариев. С помощью рекурсивной функции renderCommentList - рендерим все комментарии и помещаем В переменную $data['comments'] готовый html код. Далее этот код помещаем в шаблон comment_index.tpl - тем самым сформировав и передав полностью всю верстку для страницы. Содержание модели и библиотеки комментариев выложим ниже.

PHP скрипт комментариев на Codeigniter 3 + AJAX + jQuery + MySQL

Рекурсивная функция renderCommentList($tree) - генерирует html код каждого отдельного комментария с помощью шаблона comment_render.tpl в блоке <div class="single-comment"> - и помещает дочерние комментарии в блок <div class="multilevel-commtents"> - создавая тем самым готовую удобную для стилизации верстку. Вот как выглядят многоуровневые комментарии:

image description

Далее - функции get_comment_form и get_comment_form_ajax - идентичные по функции, но вторую можно вывести только с помощью аякса. Зачем так делать?

Практически все боты-спамеры парсят сайты на наличие таких вот форм для комментариев. Что бы боты не забивали ваш сайт рекламой и мусором - нужно сделать так, что бы они просто не находили следующие формы на вашем сайте) В данном уроке - будем использовать обычную функцию, но вам рекомендую не выводить код формы а сайте а запускать или выводить верстку по нажатию на кнопку типа - "Оставить комментарий" - асинхронным запросом! Это не 100% защита а от направленной атаки - не защитит совершенно, но может помочь вредным скриптам - не признать ваш сайт для спама.

get_reply_comment_form - отдает код формы для ответа на уже оставленный комментарий. Параметры для данной функции (ID статьи, ID родителя, тип модуля) передаются методом POST с помощью асинхронного запроса jQuery и подставляются в скрытые поля выводимой формы в шаблоне comment_reply_form.tpl.

send_comment и аналог для ответа: send_reply_comment - обрабатывает все переданные в форме данные комментария. Предварительно проверяем - является ли запрос асинхронным иначе выводим ошибку(тоже помогает от массовой отправки спама). Логика функции аналогична send_form - модуля forms. Проверяем введенные данные, проверяем включена ли на сайте капча и правильно ли заполнили поле для нее. Прежде чем поместить все данные в базу - мы проверяем существуют ли в базе комментарии созданные менее 5 минут назад от юзера с таким же IP! Если да, то отдаем ошибку - шаблон comment_disable.tpl (можете указать другие параметры проверки или задать более-менее жесткие условия) После записи данных в базу проверяем включена ли отправка писем с заявками на почту администратору и запускаем функцию отправки _comment_mail - в положительном результате.

_final и _final_reply - это рендер шаблона, где выводим благодарность для пользователя.

_comment_mail - отвечает за отправку сообщения администратору сайта со всеми данными комментария и ссылкой на страницу. Изображение как выглядит данное письмо:

image description

Делаем выборку данных комментария по ID, дальше выбираем данные страницы или категории к которой был оставлен отзыв. Составляем текст письма и отправляем на почту администратору - если включена соответствующая опция в настройках сайта.

Построение дерева комментариев к статьям на PHP (Codeigniter 3) с помощью рекурсии

Дальше - исходный код библиотеки модуля:


Логику работы данной рекурсии мы уже разбирали при создании модуля меню. Функции идентичные.
Модель с запросами Comments_model.php:


Думаю вопросов с данным файлом и запросами ActiveRecords не возникнет и мы пойдем дальше.

Пришло время верстки, стилизации и ява-скрипта.
Файл comment_index.tpl - выводит заголовок с количеством комментариев и блок внутри которого размещаются все данные:


Далее рассмотрим исходный код html который мы генерируем в цикле для каждого комментария:


Как видите - мы выводим блок с уникальным идентификатором post_comment_idкомментария - для обозначения места вывода формы с ответом на отзыв. Изображение(по желания), имя автора текстом или ссылкой на сайт, дата создания и содержание. Ниже текста поместим кнопку "Ответить" - при ее нажатии под отзывом появится новая форма для отправки ответа на данный комментарий.

Дальше разберем форму:


Обычная форма. Скрытое поле - идентификатор статьи, поля для ввода имени, почтового ящика, сайта, комментария и окно для ввода капчи - если она включена. action формы - путь к методу класса отвечающего за отправку комментария. Обратите внимание - что с URI мы так же передаем название модуля, для которого оставляем отзыв - если его не задать - то наш скрипт сохранит данные с типом "pages". В принципе можно задать его в скрытом поле и передать методом POST как остальные данные. На ваше усмотрение в общем.

Форма ответа на комментарий - отличается лишь заданием дополнительного скрытого поля в теле и оберткой кода данной формы - блоком с классом "reply_form":


image description

Шаблоны comment_final.tpl и comment_disable.tpl - обычная верстка:



Ну что же. Необходимо добавить щепотку соли из стилей:


image description

Отлично! Давайте украсим наш уникальный модуль - кусочками ява-скрипта ;)


Рассмотрим данный код по ближе. По нажатию на кнопку "ответить" в первую очередь проверяем - нет ли у кнопки класса opened и если есть - то прячем и удаляем блок с классом reply_form с сайта и убираем класс opened с кнопки. Иначе - добавляем класс opened для нажатой кнопки и обьявляем переменные article_id, comment_id, comment_type и comment_block_id. Каждой переменной присваиваем значения аналогичного по ее названию атрибута data. Другими словами: мы задали для каждой кнопки "Ответить" 4 атрибута: тип модуля, ID статьи и ID комментария(родителя). Эти атрибуты сохраняем в переменные, объединяем в обьект и отправляем методом ajax на сервер. Ответом - получаем html код блока с формой для ответа, и этот полученный код вставляем в конце блока с комментарием на который хотим дать ответ! Вот и все. Очень простой и чистый код.

Остальные две функции - это валидация полей формы с помощью отличного скрипта bootstrapValidator - который мы так же разбирали в статье формы обратной связи. Если не читали статью - то немедленно перейдите к ее изучению. В ней мы подробно разбираем данный скрипт и его работу. Наш бутстрап валидатор позволяет на ходу проверять ошибки при заполнении формы и в случае их отсутствия посылает асинхронный запрос на сервер и выводит ответ в блок с формой ответа, заменяя ее.

Ну модуль то мы написали, таблицу pages изменили добавив новое поле comments_on. А код вывода комментариев и формы не задали в шаблоне page_full.tpl . Проверим включены ли комментарии для данной страницы и выведем все ответы и форму для ответа в под содержанием статьи вот так:


Вот и все на сегодня. Как всегда посмотреть работу скрипта вы можете в демо-версии движка. Не забыл я и про исходники сайта с модулем comments. Всех еще раз с праздниками и легкого кодинга вам, дорогие друзья. Жду много ваших положительных отзывов ;-)

5796 Просмотров Комментариев: 13

Николай

Ответить

Спасибо, как раз то что я искал. Сейчас буду пилить :)

Артём

Ответить

Вот и коммент с ответом

asd

Ответить

asd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asdasd asd

easysystem.pro

Ответить

Test

Os

Ответить

спасибо

Александр

Ответить

Спасибо за информацию! Выводы для себя сделал.

Вадим

Ответить

Отличная статья!

Геннадий

Ответить

Действительно, отличная статья! Спасибо!

Виктор

Ответить

Функционал программы впечатляет. Принял решение поменять у себя на сайте программу комментирования статей и остановился на вашей. Чтобы избавиться от спама надо принять дополнительные меры, допускать до оставления комментариев только зарегистрированных пользователей, тем более, что интеграция сайта с социальными сетями позволяет это сделать. Спасибо разработчикам.

Александр

Ответить

В структуре вашего движка в каталоге comon/models есть модель Main_model, почему то я не могу её загрузить через $this->load->model('comon/main_model'); Как это правильно зделать?

Немец Гофман

Ответить

Спасибо за вашу работу, очень впечатляет. Пробую у себя на сайт . Коментарии вроде работают, но при каждом вложеннии коментария, форма для ввода текста становится всё меньше. Выглядит как-то убого. Не подскажите как сделать форму во всю доступную величину. Спасибо.

Стас

Ответить

У меня тоже возникли проблемы с корректным отображением формы комментирования на сайте, долго пытался разобраться, но в итоге так и не вышло ничего. Нашел решение с помощью сервиса готовых комментариев getrate.me. Быстрая установка плюс специальная административная панель модерирования комментариев.

Erik

Ответить

А как быть с codeigniter 2? Если переделать под codeigniter 2 скрипт работать будет?

« Предыдущая статьяСоздание движка на Codeigniter 3 + HMVC. Часть 6. Пишем модуль обратной связи - forms Следующая статья »Создание движка на Codeigniter 3 + HMVC. Часть 8. Пишем модуль карусели (слайдера) - slider