function doboard($board) { global $global_locale, $config, $main_js, $options; $config['mask_db_error'] = false; if (!$options['api']) { $config['api']['enabled'] = false; } echo "Opening board /{$board['uri']}/...\n"; // Reset locale to global locale $config['locale'] = $global_locale; init_locale($config['locale'], 'error'); openBoard($board['uri']); $config['try_smarter'] = false; if ($config['file_script'] != $main_js && $options['js']) { // different javascript file echo "(/{$board['uri']}/) Generating Javascript file...\n"; buildJavascript(); } if ($options['indexes']) { echo "(/{$board['uri']}/) Creating index pages...\n"; buildIndex(); } if ($options['postmarkup']) { $query = query(sprintf("SELECT `id` FROM ``posts_%s``", $board['uri'])) or error(db_error()); while ($post = $query->fetch()) { echo "(/{$board['uri']}/) Rebuilding #{$post['id']}...\n"; rebuildPost($post['id']); } } if ($options['threads']) { $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); while ($post = $query->fetch()) { echo "(/{$board['uri']}/) Rebuilding #{$post['id']}...\n"; @buildThread($post['id']); } } }
function deletePost($id, $error_if_doesnt_exist = true, $rebuild_after = true) { global $board, $config; // Select post and replies (if thread) in one query $query = prepare(sprintf("SELECT `id`,`thread`,`files` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); if ($query->rowCount() < 1) { if ($error_if_doesnt_exist) { error($config['error']['invalidpost']); } else { return false; } } $ids = array(); // Delete posts and maybe replies while ($post = $query->fetch(PDO::FETCH_ASSOC)) { event('delete', $post); if (!$post['thread']) { // Delete thread HTML page @file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['id'])); @file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $post['id'])); @file_unlink($board['dir'] . $config['dir']['res'] . sprintf('%d.json', $post['id'])); $antispam_query = prepare('DELETE FROM ``antispam`` WHERE `board` = :board AND `thread` = :thread'); $antispam_query->bindValue(':board', $board['uri']); $antispam_query->bindValue(':thread', $post['id']); $antispam_query->execute() or error(db_error($antispam_query)); } elseif ($query->rowCount() == 1) { // Rebuild thread $rebuild =& $post['thread']; } if ($post['files']) { // Delete file foreach (json_decode($post['files']) as $i => $f) { if (isset($f->file, $f->thumb) && $f->file !== 'deleted') { @file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['img'] . $f->file); @file_unlink($config['dir']['img_root'] . $board['dir'] . $config['dir']['thumb'] . $f->thumb); } } } $ids[] = (int) $post['id']; } $query = prepare(sprintf("DELETE FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); $query = prepare("SELECT `board`, `post` FROM ``cites`` WHERE `target_board` = :board AND (`target` = " . implode(' OR `target` = ', $ids) . ") ORDER BY `board`"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if ($board['uri'] != $cite['board']) { if (!isset($tmp_board)) { $tmp_board = $board['uri']; } openBoard($cite['board']); } rebuildPost($cite['post']); } if (isset($tmp_board)) { openBoard($tmp_board); } $query = prepare("DELETE FROM ``cites`` WHERE (`target_board` = :board AND (`target` = " . implode(' OR `target` = ', $ids) . ")) OR (`board` = :board AND (`post` = " . implode(' OR `post` = ', $ids) . "))"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); if (isset($rebuild) && $rebuild_after) { buildThread($rebuild); buildIndex(); } return true; }
} if (!$options['quiet']) { echo "Creating index pages...\n"; } buildIndex(); if ($options['quick']) { continue; } // do no more if ($options['full']) { $query = query(sprintf("SELECT `id` FROM ``posts_%s``", $board['uri'])) or error(db_error()); while ($post = $query->fetch()) { if (!$options['quiet']) { echo "Rebuilding #{$post['id']}...\n"; } rebuildPost($post['id']); } } $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); while ($post = $query->fetch()) { if (!$options['quiet']) { echo "Rebuilding #{$post['id']}...\n"; } buildThread($post['id']); } } if (!$options['quiet']) { printf("Complete! Took %g seconds\n", microtime(true) - $start); } unset($board); modLog('Rebuilt everything using tools/rebuild.php');
$query->bindValue(':uri', $board['uri'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); if ($config['cache']['enabled']) { cache::delete('board_' . $board['uri']); cache::delete('all_boards'); } $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); while ($cite = $query->fetch()) { if ($board['uri'] != $cite['board']) { if (!isset($tmp_board)) { $tmp_board = $board; } openBoard($cite['board']); rebuildPost($cite['post']); } } if (isset($tmp_board)) { $board = $tmp_board; } $query = prepare("DELETE FROM `cites` WHERE `board` = :board OR `target_board` = :board"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); $query = prepare("DELETE FROM `antispam` WHERE `board` = :board"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); $_board = $board; rebuildThemes('boards'); $board = $_board; header('Location: ?/', true, $config['redirect_http']);
function mod_edit_post($board, $edit_raw_html, $postID) { global $config, $mod; if (!openBoard($board)) { error($config['error']['noboard']); } if (!hasPermission($config['mod']['editpost'], $board)) { error($config['error']['noaccess']); } if ($edit_raw_html && !hasPermission($config['mod']['rawhtml'], $board)) { error($config['error']['noaccess']); } $security_token = make_secure_link_token($board . '/edit' . ($edit_raw_html ? '_raw' : '') . '/' . $postID); $query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id', $board)); $query->bindValue(':id', $postID); $query->execute() or error(db_error($query)); if (!($post = $query->fetch(PDO::FETCH_ASSOC))) { error($config['error']['404']); } if (isset($_POST['name'], $_POST['email'], $_POST['subject'], $_POST['body'])) { if ($edit_raw_html) { $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body` = :body, `body_nomarkup` = :body_nomarkup WHERE `id` = :id', $board)); } else { $query = prepare(sprintf('UPDATE ``posts_%s`` SET `name` = :name, `email` = :email, `subject` = :subject, `body_nomarkup` = :body WHERE `id` = :id', $board)); } $query->bindValue(':id', $postID); $query->bindValue('name', $_POST['name']); $query->bindValue(':email', $_POST['email']); $query->bindValue(':subject', $_POST['subject']); $query->bindValue(':body', $_POST['body']); if ($edit_raw_html) { $body_nomarkup = $_POST['body'] . "\n<tinyboard raw html>1</tinyboard>"; $query->bindValue(':body_nomarkup', $body_nomarkup); } $query->execute() or error(db_error($query)); if ($edit_raw_html) { modLog("Edited raw HTML of post #{$postID}"); } else { modLog("Edited post #{$postID}"); rebuildPost($postID); } buildIndex(); rebuildThemes('post', $board); header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $postID) . '#' . $postID, true, $config['redirect_http']); } else { if ($config['minify_html']) { $post['body_nomarkup'] = str_replace("\n", '
', utf8tohtml($post['body_nomarkup'])); $post['body'] = str_replace("\n", '
', utf8tohtml($post['body'])); $post['body_nomarkup'] = str_replace("\r", '', $post['body_nomarkup']); $post['body'] = str_replace("\r", '', $post['body']); $post['body_nomarkup'] = str_replace("\t", '	', $post['body_nomarkup']); $post['body'] = str_replace("\t", '	', $post['body']); } mod_page(_('Edit post'), 'mod/edit_post_form.html', array('token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post)); } }
function mod_report_clean($global_reports, $board, $unclean, $post, $global, $local) { global $config, $mod; if (!openBoard($board)) { error($config['error']['noboard']); } $query_global = ""; $query_global_mod = ""; if ($global) { if (!hasPermission($config['mod']['clean_global'], $board)) { error($config['error']['noaccess']); } $query_global = "`clean_global` = :clean"; $query_global_mod = "`clean_global_mod_id` = :mod"; } $query_local = ""; $query_local_mod = ""; if ($local) { if (!hasPermission($config['mod']['clean'], $board)) { error($config['error']['noaccess']); } $query_local = "`clean_local` = :clean"; $query_local_mod = "`clean_local_mod_id` = :mod"; } // Marking this post as "Clean" (report immune?) if (!$unclean) { // Attempt to find a `post_clean` row for this content. $query = prepare("SELECT * FROM `post_clean` WHERE `board_id` = :board AND `post_id` = :post"); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); // If the $clean object doesn't exist we need to insert a row for this post. if (!($cleanRecord = $query->fetch(PDO::FETCH_ASSOC))) { $query = prepare("INSERT INTO `post_clean` (`post_id`, `board_id`) VALUES ( :post, :board )"); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); if ($query->rowCount() == 0) { error("The database failed to create a record for this content in `post_clean` to record clean status."); } $cleanRecord = true; } } else { // Attempt to find a `post_clean` row for this content. $query = prepare("SELECT * FROM `post_clean` WHERE `board_id` = :board AND `post_id` = :post"); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); if (!($cleanRecord = $query->fetch(PDO::FETCH_ASSOC))) { error($config['error']['404']); } } // Update the `post_clean` row represented by $clean. if ($cleanRecord) { // Build our query based on the URI arguments. if ($global && $local) { $query = prepare("UPDATE `post_clean` SET {$query_global}, {$query_global_mod}, {$query_local}, {$query_local_mod} WHERE `board_id` = :board AND `post_id` = :post"); } else { if ($global) { $query = prepare("UPDATE `post_clean` SET {$query_global}, {$query_global_mod} WHERE `board_id` = :board AND `post_id` = :post"); } else { $query = prepare("UPDATE `post_clean` SET {$query_local}, {$query_local_mod} WHERE `board_id` = :board AND `post_id` = :post"); } } $query->bindValue(':clean', !$unclean); $query->bindValue(':mod', $unclean ? NULL : $mod['id']); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); // Finally, run a query to tidy up our records. if ($unclean) { // Query is removing clean status from content. // Remove any clean records that are now null. $cleanup = prepare("DELETE FROM `post_clean` WHERE `clean_local` = FALSE AND `clean_global` = FALSE"); $query->execute() or error(db_error($query)); } else { // Content is clean, auto-handle all reports. // If this is a total clean, we don't need to update records first. if (!($global && $local)) { $query = prepare("UPDATE `reports` SET `" . ($local ? "local" : "global") . "` = FALSE WHERE `board` = :board AND `post` = :post"); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); // If we didn't hit anything, this content doesn't have reports, so don't run the delete query. $require_delete = $query->rowCount() > 0; if ($require_delete) { $query = prepare("DELETE FROM `reports` WHERE `local` = FALSE and `global` = FALSE"); $query->execute() or error(db_error($query)); } } else { $query = prepare("DELETE FROM `reports` WHERE `board` = :board AND `post` = :post"); $query->bindValue(':board', $board); $query->bindValue(':post', $post); $query->execute() or error(db_error($query)); } } // Log the action. // Having clear wording of ths log is very important because of the nature of clean status. $log_action = $unclean ? "Closed" : "Re-opened"; $log_scope = $local && $global ? "local and global" : ($local ? "local" : "global"); modLog("{$log_action} reports for post #{$post} in {$log_scope}.", $board); if ($config['cache']['enabled']) { cache::delete("post_clean_{$board}_{$post}"); } rebuildPost($post); } // Redirect if ($global_reports) { header('Location: ?/reports/global', true, $config['redirect_http']); } else { header('Location: ?/reports', true, $config['redirect_http']); } }
function mod_edit_board($boardName) { global $board, $config; if (!openBoard($boardName)) { error($config['error']['noboard']); } if (!hasPermission($config['mod']['manageboards'], $board['uri'])) { error($config['error']['noaccess']); } if (isset($_POST['title'], $_POST['subtitle'])) { if (isset($_POST['delete'])) { if (!hasPermission($config['mod']['manageboards'], $board['uri'])) { error($config['error']['deleteboard']); } $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); $query->execute() or error(db_error($query)); modLog('Deleted board: ' . sprintf($config['board_abbreviation'], $board['uri']), false); // Delete entire board directory rrmdir($board['uri'] . '/'); // Delete posting table $query = query(sprintf('DROP TABLE IF EXISTS `posts_%s`', $board['uri'])) or error(db_error()); // Clear reports $query = prepare('DELETE FROM `reports` WHERE `board` = :id'); $query->bindValue(':id', $board['uri'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); // Delete from table $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board"); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if ($board['uri'] != $cite['board']) { if (!isset($tmp_board)) { $tmp_board = $board; } openBoard($cite['board']); rebuildPost($cite['post']); } } $query = prepare('DELETE FROM `cites` WHERE `board` = :board OR `target_board` = :board'); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); $query = prepare('DELETE FROM `antispam` WHERE `board` = :board'); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); } else { $query = prepare('UPDATE `boards` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); $query->bindValue(':title', $_POST['title']); $query->bindValue(':subtitle', $_POST['subtitle']); $query->execute() or error(db_error($query)); } if ($config['cache']['enabled']) { cache::delete('board_' . $board['uri']); cache::delete('all_boards'); } rebuildThemes('boards'); header('Location: ?/', true, $config['redirect_http']); } else { mod_page(sprintf('%s: ' . $config['board_abbreviation'], _('Edit board'), $board['uri']), 'mod/board.html', array('board' => $board)); } }
function deletePost($id, $error_if_doesnt_exist = true, $rebuild_after = true) { global $board, $config; // Select post and replies (if thread) in one query $query = prepare(sprintf("SELECT `id`,`thread`,`thumb`,`file` FROM `posts_%s` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); if ($query->rowCount() < 1) { if ($error_if_doesnt_exist) { error($config['error']['invalidpost']); } else { return false; } } // Delete posts and maybe replies while ($post = $query->fetch()) { if (!$post['thread']) { // Delete thread HTML page file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['id'])); } elseif ($query->rowCount() == 1) { // Rebuild thread $rebuild =& $post['thread']; } if ($post['thumb']) { // Delete thumbnail file_unlink($board['dir'] . $config['dir']['thumb'] . $post['thumb']); } if ($post['file']) { // Delete file file_unlink($board['dir'] . $config['dir']['img'] . $post['file']); } } $query = prepare(sprintf("DELETE FROM `posts_%s` WHERE `id` = :id OR `thread` = :id", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board AND `target` = :id"); $query->bindValue(':board', $board['uri']); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); while ($cite = $query->fetch()) { if ($board['uri'] != $cite['board']) { if (!isset($tmp_board)) { $tmp_board = $board['uri']; } openBoard($cite['board']); } rebuildPost($cite['post']); } if (isset($tmp_board)) { openBoard($tmp_board); } $query = prepare("DELETE FROM `cites` WHERE (`target_board` = :board AND `target` = :id) OR (`board` = :board AND `post` = :id)"); $query->bindValue(':board', $board['uri']); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); if (isset($rebuild) && $rebuild_after) { buildThread($rebuild); } return true; }