Вывод комментариев в древовидной структуре используя модель хранения вложенных сильев Nested Sets
Вывод комментариев в древовидной структуре используя модель хранения вложенных сильев Nested Sets.
Многие по наивности полагают что настоящая задача больно сложная, не буду их разубеждать, вот решение какое было ввергнуто в бытие за два с половиной часа воскресным ввечеру.
Для решения задачи использовать будем класс dbtree
LTER TABLE `dle_comments`
ADD `ns_level` INT(11) DEFAULT NULL;
ALTER TABLE `dle_comments`
ADD `ns_right` BIGINT(20) NOT NULL DEFAULT 0;
ALTER TABLE `dle_comments`
ADD `ns_left` BIGINT(20) NOT NULL DEFAULT 0;
1. Файл: show.full.php — изменяем запрос для получения комментариев:
$comments->query = «SELECT » . PREFIX . «_comments.id,
post_id, » . PREFIX . «_comments.user_id, date, autor as gast_name,
» . PREFIX . «_comments.email as gast_email, text, ip, is_register, name,ns_level, » . USERPREFIX . «_users.email, news_num, comm_num, user_group, reg_date, signature, foto, fullname, land, icq, xfields FROM » . PREFIX . «_comments
LEFT JOIN » . USERPREFIX . «_users ON » . PREFIX . «_comments.user_id=» . USERPREFIX . «_users.user_id
WHERE » . PREFIX . «_comments.post_id = ‘$news_id'» . $where_approve . » ORDER BY » . PREFIX . «_comments.ns_right DESC «;
2. Файл: comments.class.php — убираем лимит из запроса
#Было
#$sql_result = $this->db->query($this->query . » LIMIT » . $this->cstart . «,» . $this->comments_per_pages);
#Стало
$sql_result = $this->db->query($this->query);
3.Файл: modules/addcomments.php — изменяем добавление комментариев с учетом новых требование.
// перед
//if ($update_comments) {
//добавляем
$_ns_id = (int) $_REQUEST[’ns_parent_id’];
if ($_ns_id)
$update_comments = false;
//после $comments = $db->safesql($comments);
//добавляем
require_once ROOT_DIR . ‘/engine/classes/dbtree/db_mysql.class.php’;
require_once ROOT_DIR . ‘/engine/classes/dbtree/dbtree.class.php’;
$_db = new _db(DBHOST, DBUSER, DBPASS, DBNAME);
$dbtree = new dbtree(PREFIX . ‘_comments’, ‘ns’, $_db);
if ($_ns_id) {
$dbtree->Insert($_ns_id, array(
‘and’ => array(‘parent_id’ => «post_id='» . $post_id . «‘»)
), array(
‘post_id’ => $post_id,
‘user_id’ => $member_id[‘user_id’],
‘date’ => $time,
‘autor’ => $name,
‘text’ => $comments,
‘ip’ => $_IP,
‘is_register’ => 1,
‘approve’ => $where_approve
));
} else {
if ($is_logged)
$db->query(«INSERT INTO » . PREFIX . «_comments
(post_id, user_id, date, autor, email, text, ip, is_register, approve) values
(‘$post_id’, ‘$member_id[user_id]’, ‘$time’, ‘$name’, ‘$mail’, ‘$comments’, ‘$_IP’, ‘1’, ‘$where_approve’)»);
else
$db->query(«INSERT INTO » . PREFIX . «_comments (post_id, date, autor, email, text, ip, is_register, approve) values (‘$post_id’, ‘$time’, ‘$name’, ‘$mail’, ‘$comments’, ‘$_IP’, ‘0’, ‘$where_approve’)»);
}
//прежние запросы комментируем или удаляем
// if ($is_logged)
// $db->query(«INSERT INTO » . PREFIX . «_comments
// (post_id, user_id, date, autor, email, text, ip, is_register, approve) values
// (‘$post_id’, ‘$member_id[user_id]’, ‘$time’, ‘$name’, ‘$mail’, ‘$comments’, ‘$_IP’, ‘1’, ‘$where_approve’)»);
// else
// $db->query(«INSERT INTO » . PREFIX . «_comments (post_id, date, autor, email, text, ip, is_register, approve) values (‘$post_id’, ‘$time’, ‘$name’, ‘$mail’, ‘$comments’, ‘$_IP’, ‘0’, ‘$where_approve’)»);
4. Файл: ajax/addcomments.php — добавляем лимит в запрос на получение комментария.
$comments->query = «SELECT » . PREFIX . «_comments.id, post_id, » . PREFIX . «_comments.user_id, date, autor as gast_name,
» . PREFIX . «_comments.email as gast_email, text, ip, is_register, name,
» . USERPREFIX . «_users.email, news_num, comm_num, user_group, reg_date, signature, foto, fullname, land, icq, xfields
FROM » . PREFIX . «_comments LEFT JOIN » . USERPREFIX . «_users
ON » . PREFIX . «_comments.user_id=» . USERPREFIX . «_users.user_id
WHERE » . PREFIX . «_comments.post_id = ‘$post_id’ order by id DESC LIMIT 1»;
5. .classes/js/dle_js.js — добавляем функцию отправки ответа.
function add_answer(parent_id){
var button = {};
var a=document.getElementById(«dle-comments-form»);
if(dle_wysiwyg==»yes»){
document.getElementById(«comments»).value=$(«#comments»).html();
var b=»wysiwyg»
}else b=»»;
button[dle_p_send]=function(){
ShowLoading(«»);
$.post(dle_root+
«engine/ajax/addcomments.php»,{
post_id:a.post_id.value,
comments: $(‘#review’).val(),
name:a.name.value,
mail:a.mail.value,
editor_mode:b,
skin:dle_skin,
ns_parent_id: parent_id,
allow_subscribe: ‘0’
},function(b){
if(a.sec_code)a.sec_code.value=»»,reload();
HideLoading(«»);
RunAjaxJS(«answer-«+parent_id,b);
b!=»error»&&document.getElementById(«blind-animation»)&&($(«html»+(!$.browser.opera?»,body»:»»)).animate({
scrollTop:$(«#dle-ajax-comments»).offset().top-70
},1100),setTimeout(function(){
$(«#blind-animation»).show(«blind»,
{},1500)
},1100))
})
$(this).dialog(«close»);
};
$(«#d-popup»).remove();
var div = $(‘<div id=»d-popup» style=»display:none»></div>’),
frm = $(‘<form name=»answer»><textarea id=»review» rows=»6″ cols=»» name=»review» style=»width:98%»></textarea></form>’)
$(«body»).append(div);
$(div).append(frm)
$(«#d-popup»).dialog({
autoOpen: true,
width: 690,
height: 270,
resize:false,
buttons: button,
open: function(){
}
});
}
6. в шаблон cjmments.tpl добавляем уровень вложенности, ссылку на добавление ответа и элемент разметки для размещения вновь добавленного ответа к комментарию.
<div class=»bcomment» style=»padding-left:{level}0px !important»>
………….
<span class=»reply»><a href=»javascript:add_answer(‘{id}’)»><b>Ответить</b></a></span>
…………..
<div id=»answer-{id}» style=»padding-left:{level}9px !important»></div>
В прикрепленном архиве все необходимое для тестирования.
p.s. класс _db был изменен под использование с mysqlL.
p.s.s. работоспособность образца зависит от прямых рук.
Автор: DG