Below is sample code tht may solve this problem for the developers to review. It basically uses a dfs
search that ensures all comments below a comment targeted for deletion are also deleted leaving no orphans.
It also does a recalculation of comments eatch time a targeted comment branch is deleted ensuring that the comment
count displayed in the link listings is true and consistant.
----- Replacement snippet for bulk deletion of comments in killspam routine - appears in admin_users.php -----
Code:
if ($_GET['token'] == $_SESSION['token_admin_users_killspam']) {
$user= $db->get_row('SELECT * FROM ' . table_users .' where user_login="'.$_GET["user"].'"');
canIChangeUser($user->user_level);
if ($user) {
//$db->query('UPDATE `' . table_users . '` SET `user_pass` = "63205e60098a9758101eeff9df0912ccaaca6fca3e50cdce3" WHERE `user_login` = "'.$_GET["user"].'"');
$db->query('UPDATE `' . table_users . '` SET `user_pass` = "' . md5(uniqid(rand(), true)) . '" WHERE `user_login` = "'.$_GET["user"].'"');
$db->query('UPDATE `' . table_users . '` SET `user_email` = "blank@blank.com" WHERE `user_login` = "'.$_GET["user"].'"');
$db->query('UPDATE `' . table_links . '` SET `link_status` = "discard" WHERE `link_author` = "'.$_GET["id"].'"');
//$db->query('DELETE FROM `' . table_comments . '` WHERE `comment_user_id` = "'.$_GET["id"].'"');
$comments_spam = $db->get_results("SELECT comment_id FROM `" . table_comments . "` WHERE `comment_user_id` = ".$_GET["id"].";");
$comments_spam_rows = $db->get_var("SELECT comment_id FROM `" . table_comments . "` WHERE `comment_user_id` = ".$_GET["id"].";");
if($comments_spam) {
$comments_stack = new Stack;
foreach($comments_spam as $dbfiltered) {
$link_id = $db->get_var("SELECT comment_link_id FROM `" . table_comments . "` WHERE `comment_id` = ".$dbfiltered->comment_id.";");
$comments_stack->push($dbfiltered->comment_id);
DeleteComments();
if ($link_id) {
$link = new Link;
$link->id=$link_id;
$link->read();
$link->recalc_comments();
$link->store();
$link='';
}
}
$comments_stack = null;
}
// breadcrumbs and page title
$navwhere['text1'] = $main_smarty->get_config_vars('PLIGG_Visual_Header_AdminPanel');
$navwhere['link1'] = getmyurl('admin', '');
$navwhere['text2'] = $main_smarty->get_config_vars('PLIGG_Visual_Header_AdminPanel_1');
$navwhere['link2'] = my_pligg_base . "/admin_users.php";
$navwhere['text3'] = $main_smarty->get_config_vars('PLIGG_Visual_Breadcrumb_User_Disable_2');
$main_smarty->assign('navbar_where', $navwhere);
$main_smarty->assign('posttitle', " / " . $main_smarty->get_config_vars('PLIGG_Visual_Header_AdminPanel'));
// pagename
define('pagename', 'admin_users');
$main_smarty->assign('pagename', pagename);
header("Location: ".my_pligg_base."/admin_users.php");
}
else{showmyerror('userdoesntexist');}
} else {
Show_Invalid_Token(1);
} Code:
if (isset($_GET['action']) && $_GET['action'] == "bulkmod") {
if(isset($_POST['submit'])) {
$comment = array();
foreach ($_POST["comment"] as $k => $v) {
$comment[intval($k)] = $v;
}
$comments_stack = new Stack;
foreach($comment as $key => $value) {
if ($value == "discard") {
$link_id = $db->get_var("SELECT comment_link_id FROM `" . table_comments . "` WHERE `comment_id` = ".$key.";");
$comments_stack->push($key);
DeleteComments();
//$db->query('DELETE FROM `' . table_comments . '` WHERE `comment_id` = "'.$key.'"');
//$db->query('DELETE FROM `' . table_comments . '` WHERE `comment_parent` = "'.$key.'"');
if ($link_id) {
$link = new Link;
$link->id=$link_id;
$link->read();
$link->recalc_comments();
$link->store();
$link='';
}
}
}
$comments_stack = null;
header("Location: ".my_pligg_base."/admin_comments.php");
}
} Code:
// Deletes the entire branch/sub-branch of comments under any root/sub-root comment passed to it
function DeleteComments() {
while ($comments_stack->get_length() > 0) {
$temp_comment_key = $comments_stack->pop();
$comments_children = $db->get_results("SELECT comment_id FROM `" . table_comments . "` WHERE `comment_parent` = ".$temp_comment_key.";");
$comments_children_rows = $db->get_var("SELECT comment_id FROM `" . table_comments . "` WHERE `comment_parent` = ".$temp_comment_key.";");
if($comments_children) {
foreach($comments_children as $dbfiltered) {
$comments_stack->push($dbfiltered->comment_id);
}
}
$db->query('DELETE FROM `' . table_comments . '` WHERE `comment_id` = "'.$temp_comment_key.'"');
DeleteComments();
}
} Code:
/*
This file is part of POOF.
POOF is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
POOF is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with POOF; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* A stack data structure. A stack is a LIFO (Last In First Out) data structure.
* @author Brian Takita <brian.takita@runbox.com>
* @version 1.1
*/
class Stack {
/**
* @var array The Stack data.
* @access private
*/
var $_stack = array();
/**
* Push the argument onto the stack.
* @param mixed $content The element to be pushed onto the stack.
*/
function push($element) {
array_push($this->_stack, &$element);
}
/**
* Pop the Stack.
* @returns mixed The reference to the popped element.
*/
function &pop() {
$element = &$this->top();
array_pop($this->_stack);
return $element;
}
/**
* Returns a reference to the top of the stack.
* @returns mixed A reference to the top of the stack.
*/
function &top() {
$count = count($this->_stack);
// Prevent bad reference pointer
if ($count == 0) {
return null;
}
return $this->_stack[count($this->_stack)-1];
}
/**
* Get the lenght of the Stack.
* @returns int The lenght of the Stack.
*/
function get_length() {
return count($this->_stack);
}
} 



Linear Mode




