function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = (int) $thread; if ($thread < 1) { return false; } if (!preg_match('/^' . $config['board_regex'] . '$/u', $b)) { return false; } if (Cache::get("thread_exists_" . $b . "_" . $thread) == "no") { return false; } $query = prepare(sprintf("SELECT MAX(`id`) AS `max` FROM ``posts_%s``", $b)); if (!$query->execute()) { return false; } $s = $query->fetch(PDO::FETCH_ASSOC); $max = $s['max']; if ($thread > $max) { return false; } $query = prepare(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL", $b)); $query->bindValue(':id', $thread); if (!$query->execute() || !$query->fetch(PDO::FETCH_ASSOC)) { Cache::set("thread_exists_" . $b . "_" . $thread, "no"); return false; } if ($slugcheck == 50) { // Should we really generate +50 page? Maybe there are not enough posts anyway global $request; $r = str_replace("+50", "", $request); $r = substr($r, 1); // Cut the slash if (file_exists($r)) { return false; } } if (!openBoard($b)) { return false; } buildThread($thread); return true; }
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');
} // build thread buildThread($newID); buildIndex(); // trigger themes rebuildThemes('post'); openBoard($boardName); if ($shadow) { // lock thread $query = prepare(sprintf("UPDATE `posts_%s` SET `locked` = 1 WHERE `id` = :id", $board['uri'])); $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); $post = array('mod' => true, 'subject' => '', 'email' => '', 'name' => $config['mod']['shadow_name'], 'capcode' => $config['mod']['shadow_capcode'], 'trip' => '', 'body' => sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID), 'password' => '', 'has_file' => false, 'thread' => $postID, 'op' => false); markup($post['body']); $botID = post($post); buildThread($postID); header('Location: ?/' . sprintf($config['board_path'], $boardName) . $config['dir']['res'] . sprintf($config['file_page'], $postID) . '#' . $botID, true, $config['redirect_http']); } else { deletePost($postID); buildIndex(); openBoard($targetBoard); header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . sprintf($config['file_page'], $newID), true, $config['redirect_http']); } } else { $body = '<fieldset><legend>Move thread</legend>' . '<form action="?/' . $boardName . '/move/' . $postID . '" method="post">' . '<table>'; $boards = listBoards(); if (count($boards) <= 1) { error(_('No board to move to; there is only one.')); } $__boards = ''; foreach ($boards as &$_board) {
// Encode and set cookie setcookie($config['cookies']['js'], json_encode($js), 0, $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, false, false); } $root = $post['mod'] ? $config['root'] . $config['file_mod'] . '?/' : $config['root']; if ($noko) { $redirect = $root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['op'] ? $id : $post['thread']) . (!$post['op'] ? '#' . $id : ''); if (!$post['op'] && isset($_SERVER['HTTP_REFERER'])) { $regex = array('board' => str_replace('%s', '(\\w{1,8})', preg_quote($config['board_path'], '/')), 'page' => str_replace('%d', '(\\d+)', preg_quote($config['file_page'], '/')), 'page50' => str_replace('%d', '(\\d+)', preg_quote($config['file_page50'], '/')), 'res' => preg_quote($config['dir']['res'], '/')); if (preg_match('/\\/' . $regex['board'] . $regex['res'] . $regex['page50'] . '([?&].*)?$/', $_SERVER['HTTP_REFERER'])) { $redirect = $root . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $post['op'] ? $id : $post['thread']) . (!$post['op'] ? '#' . $id : ''); } } } else { $redirect = $root . $board['dir'] . $config['file_index']; } buildThread($post['op'] ? $id : $post['thread']); if ($config['syslog']) { _syslog(LOG_INFO, 'New post: /' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['op'] ? $id : $post['thread']) . (!$post['op'] ? '#' . $id : '')); } if (!$post['mod']) { header('X-Associated-Content: "' . $redirect . '"'); } if (!isset($_POST['json_response'])) { header('Location: ' . $redirect, true, $config['redirect_http']); } else { header('Content-Type: text/json; charset=utf-8'); echo json_encode(array('redirect' => $redirect, 'noko' => $noko, 'id' => $id)); } if ($config['try_smarter'] && $post['op']) { $build_pages = range(1, $config['max_pages']); }
function mod_rebuild() { global $config, $twig; if (!hasPermission($config['mod']['rebuild'])) { error($config['error']['noaccess']); } if (isset($_POST['rebuild'])) { @set_time_limit($config['mod']['rebuild_timelimit']); $log = array(); $boards = listBoards(); $rebuilt_scripts = array(); if (isset($_POST['rebuild_cache'])) { if ($config['cache']['enabled']) { $log[] = 'Flushing cache'; Cache::flush(); } $log[] = 'Clearing template cache'; load_twig(); $twig->clearCacheFiles(); } if (isset($_POST['rebuild_themes'])) { $log[] = 'Regenerating theme files'; rebuildThemes('all'); } if (isset($_POST['rebuild_javascript'])) { $log[] = 'Rebuilding <strong>' . $config['file_script'] . '</strong>'; buildJavascript(); $rebuilt_scripts[] = $config['file_script']; } foreach ($boards as $board) { if (!(isset($_POST['boards_all']) || isset($_POST['board_' . $board['uri']]))) { continue; } openBoard($board['uri']); $config['try_smarter'] = false; if (isset($_POST['rebuild_index'])) { buildIndex(); $log[] = '<strong>' . sprintf($config['board_abbreviation'], $board['uri']) . '</strong>: Creating index pages'; } if (isset($_POST['rebuild_javascript']) && !in_array($config['file_script'], $rebuilt_scripts)) { $log[] = '<strong>' . sprintf($config['board_abbreviation'], $board['uri']) . '</strong>: Rebuilding <strong>' . $config['file_script'] . '</strong>'; buildJavascript(); $rebuilt_scripts[] = $config['file_script']; } if (isset($_POST['rebuild_thread'])) { $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $log[] = '<strong>' . sprintf($config['board_abbreviation'], $board['uri']) . '</strong>: Rebuilding thread #' . $post['id']; buildThread($post['id']); } } } mod_page(_('Rebuild'), 'mod/rebuilt.html', array('logs' => $log)); return; } mod_page(_('Rebuild'), 'mod/rebuild.html', array('boards' => listBoards(), 'token' => make_secure_link_token('rebuild'))); }
function mod_8_settings($b) { global $config, $mod; //if ($b === 'infinity' && $mod['type'] !== ADMIN) // error('Settings temporarily disabled for this board.'); if (!in_array($b, $mod['boards']) and $mod['boards'][0] != '*') { error($config['error']['noaccess']); } if (!hasPermission($config['mod']['edit_settings'], $b)) { error($config['error']['noaccess']); } if (!openBoard($b)) { error("Could not open board!"); } $possible_languages = array_diff(scandir('inc/locale/'), array('..', '.', '.tx', 'README.md')); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $board_type = $_POST['board_type']; $imgboard = $board_type == 'imgboard'; $txtboard = $board_type == 'txtboard'; $fileboard = $board_type == 'fileboard'; $title = $_POST['title']; $subtitle = $_POST['subtitle']; $country_flags = isset($_POST['country_flags']) ? 'true' : 'false'; $field_disable_name = isset($_POST['field_disable_name']) ? 'true' : 'false'; $enable_embedding = isset($_POST['enable_embedding']) ? 'true' : 'false'; $force_image_op = $imgboard && isset($_POST['force_image_op']) ? 'true' : 'false'; $disable_images = $txtboard ? 'true' : 'false'; $poster_ids = isset($_POST['poster_ids']) ? 'true' : 'false'; $show_sages = isset($_POST['show_sages']) ? 'true' : 'false'; $auto_unicode = isset($_POST['auto_unicode']) ? 'true' : 'false'; $strip_combining_chars = isset($_POST['strip_combining_chars']) ? 'true' : 'false'; $allow_roll = isset($_POST['allow_roll']) ? 'true' : 'false'; $image_reject_repost = isset($_POST['image_reject_repost']) ? 'true' : 'false'; $image_reject_repost_in_thread = isset($_POST['image_reject_repost_in_thread']) ? 'true' : 'false'; $early_404 = isset($_POST['early_404']) ? 'true' : 'false'; $allow_delete = isset($_POST['allow_delete']) ? 'true' : 'false'; $allow_flash = $imgboard && isset($_POST['allow_flash']) ? '$config[\'allowed_ext_files\'][] = \'swf\';' : ''; $allow_pdf = $imgboard && isset($_POST['allow_pdf']) ? '$config[\'allowed_ext_files\'][] = \'pdf\';' : ''; $code_tags = isset($_POST['code_tags']) ? '$config[\'additional_javascript\'][] = \'js/code_tags/run_prettify.js\';$config[\'markup\'][] = array("/\\[code\\](.+?)\\[\\/code\\]/ms", "<code><pre class=\'prettyprint\' style=\'display:inline-block\'>\\$1</pre></code>");' : ''; $katex = isset($_POST['katex']) ? '$config[\'katex\'] = true;$config[\'additional_javascript\'][] = \'js/katex/katex.min.js\'; $config[\'markup\'][] = array("/\\[tex\\](.+?)\\[\\/tex\\]/ms", "<span class=\'tex\'>\\$1</span>"); $config[\'additional_javascript\'][] = \'js/katex-enable.js\';' : ''; $user_flags = isset($_POST['user_flags']) ? "if (file_exists('{$b}/flags.php')) { include 'flags.php'; }\n" : ''; $captcha = isset($_POST['captcha']) ? 'true' : 'false'; $force_subject_op = isset($_POST['force_subject_op']) ? 'true' : 'false'; $force_flag = isset($_POST['force_flag']) ? 'true' : 'false'; $tor_posting = isset($_POST['tor_posting']) ? 'true' : 'false'; $tor_image_posting = isset($_POST['tor_image_posting']) ? 'true' : 'false'; $robot_enable = isset($_POST['robot_enable']) ? 'true' : 'false'; $new_thread_capt = isset($_POST['new_thread_capt']) ? 'true' : 'false'; $oekaki = ($imgboard || $fileboard) && isset($_POST['oekaki']) ? 'true' : 'false'; $view_bumplock = isset($_POST['view_bumplock']) ? '-1' : 'MOD'; if ($tor_image_posting === 'true' && isset($_POST['meta_noindex'])) { error('Please index your board to enable this.'); } if ($_POST['locale'] !== 'en' && in_array($_POST['locale'], $possible_languages)) { $locale = "\$config['locale'] = '{$_POST['locale']}.UTF-8';"; } else { $locale = ''; } if (isset($_POST['max_images']) && (int) $_POST['max_images'] && (int) $_POST['max_images'] <= 5) { $_POST['max_images'] = (int) $_POST['max_images']; $multiimage = "\$config['max_images'] = {$_POST['max_images']};\n\t\t\t\t\t \$config['additional_javascript'][] = 'js/multi-image.js';"; } else { $multiimage = ''; } if (isset($_POST['custom_assets'])) { $assets = "\$config['custom_assets'] = true;\n\t\t\t\t \$config['spoiler_image'] = 'static/assets/{$b}/spoiler.png';\n\t\t\t\t \$config['image_deleted'] = 'static/assets/{$b}/deleted.png';\n\t\t\t\t \$config['no_file_image'] = 'static/assets/{$b}/no-file.png';\n\t\t\t\t"; } else { $assets = ''; } $file_board = ''; if ($fileboard) { $force_image_op = true; $file_board = "\$config['threads_per_page'] = 30;\n\t\t\t\t\t \$config['file_board'] = true;\n\t\t\t\t\t \$config['threads_preview'] = 0;\n\t\t\t\t \$config['threads_preview_sticky'] = 0;\n\t\t\t\t\t \$config['allowed_ext_files'] = array();\n"; if (isset($_POST['allowed_type'])) { foreach ($_POST['allowed_type'] as $val) { if (in_array($val, $config['fileboard_allowed_types'])) { $file_board .= "\$config['allowed_ext_files'][] = '{$val}';\n"; } } } if (isset($_POST['allowed_ext_op'])) { $file_board .= "\$config['allowed_ext_op'] = \$config['allowed_ext_files'];\n"; if (isset($_POST['allowed_ext_op_video'])) { $file_board .= "\$config['allowed_ext_op'][] = 'webm';\n\t\t\t\t\t\t\t\t\$config['allowed_ext_op'][] = 'mp4';\n"; } } if (isset($_POST['tag_id'])) { $file_board .= "\$config['allowed_tags'] = array();\n"; foreach ($_POST['tag_id'] as $id => $v) { $file_board .= "\$config['allowed_tags']["; $file_board .= 'base64_decode("'; $file_board .= base64_encode($_POST['tag_id'][$id]); $file_board .= '")'; $file_board .= "] = "; $file_board .= 'base64_decode("'; $file_board .= base64_encode($_POST['tag_desc'][$id]); $file_board .= '")'; $file_board .= ";\n"; } } } $anal_filenames = $fileboard && isset($_POST['anal_filenames']) ? "\$config['filename_func'] = 'filename_func';\n" : ''; $anonymous = base64_encode($_POST['anonymous']); $blotter = base64_encode(purify_html(html_entity_decode($_POST['blotter']))); $add_to_config = @file_get_contents($b . '/extra_config.php'); $replace = ''; if (isset($_POST['replace'])) { if (sizeof($_POST['replace']) > 200 || sizeof($_POST['with']) > 200) { error(_('Sorry, max 200 wordfilters allowed.')); } if (count($_POST['replace']) == count($_POST['with'])) { foreach ($_POST['replace'] as $i => $r) { if ($r !== '') { $w = $_POST['with'][$i]; if (strlen($w) > 255) { error(sprintf(_('Sorry, %s is too long. Max replacement is 255 characters'), utf8tohtml($w))); } $replace .= '$config[\'wordfilters\'][] = array(base64_decode(\'' . base64_encode($r) . '\'), base64_decode(\'' . base64_encode($w) . '\'));'; } } } if (is_billion_laughs($_POST['replace'], $_POST['with'])) { error(_('Wordfilters may not wordfilter previous wordfilters. For example, if a filters to bb and b filters to cc, that is not allowed.')); } } if (isset($_POST['hour_max_threads']) && (int) $_POST['hour_max_threads'] > 0 && (int) $_POST['hour_max_threads'] < 101) { $hour_max_threads = (int) $_POST['hour_max_threads']; } else { $hour_max_threads = 'false'; } if (isset($_POST['max_pages'])) { $mp = (int) $_POST['max_pages']; if ($mp > 25 || $mp < 1) { $max_pages = 15; } else { $max_pages = $mp; } } else { $max_pages = 15; } if (isset($_POST['reply_limit'])) { $rl = (int) $_POST['reply_limit']; if ($rl > 750 || $rl < 250 || $rl % 25) { $reply_limit = 250; } else { $reply_limit = $rl; } } else { $reply_limit = 250; } if (isset($_POST['max_newlines'])) { $mn = (int) $_POST['max_newlines']; if ($mn < 20 || $mn > 300) { $max_newlines = 0; } else { $max_newlines = $mn; } } else { $max_newlines = 0; } if (isset($_POST['min_body'])) { $mb = (int) $_POST['min_body']; if ($mb < 0 || $mb > 1024) { $min_body = 0; } else { $min_body = $mb; } } else { $min_body = 0; } if (!(strlen($title) < 40)) { error('Invalid title'); } if (!(strlen($subtitle) < 200)) { error('Invalid subtitle'); } $query = prepare('UPDATE ``boards`` SET `title` = :title, `subtitle` = :subtitle, `indexed` = :indexed, `public_bans` = :public_bans, `public_logs` = :public_logs, `8archive` = :8archive WHERE `uri` = :uri'); $query->bindValue(':title', $title); $query->bindValue(':subtitle', $subtitle); $query->bindValue(':uri', $b); $query->bindValue(':indexed', !isset($_POST['meta_noindex'])); $query->bindValue(':public_bans', isset($_POST['public_bans'])); $query->bindValue(':public_logs', (int) $_POST['public_logs']); $query->bindValue(':8archive', isset($_POST['8archive'])); $query->execute() or error(db_error($query)); $config_file = <<<EOT <?php \$config['country_flags'] = {$country_flags}; \$config['field_disable_name'] = {$field_disable_name}; \$config['enable_embedding'] = {$enable_embedding}; \$config['force_image_op'] = {$force_image_op}; \$config['disable_images'] = {$disable_images}; \$config['poster_ids'] = {$poster_ids}; \$config['show_sages'] = {$show_sages}; \$config['auto_unicode'] = {$auto_unicode}; \$config['strip_combining_chars'] = {$strip_combining_chars}; \$config['allow_roll'] = {$allow_roll}; \$config['image_reject_repost'] = {$image_reject_repost}; \$config['image_reject_repost_in_thread'] = {$image_reject_repost_in_thread}; \$config['early_404'] = {$early_404}; \$config['allow_delete'] = {$allow_delete}; \$config['anonymous'] = base64_decode('{$anonymous}'); \$config['blotter'] = base64_decode('{$blotter}'); \$config['stylesheets']['Custom'] = 'board/{$b}.css'; \$config['default_stylesheet'] = array('Custom', \$config['stylesheets']['Custom']); \$config['captcha']['enabled'] = {$captcha}; \$config['force_subject_op'] = {$force_subject_op}; \$config['force_flag'] = {$force_flag}; \$config['tor_posting'] = {$tor_posting}; \$config['tor_image_posting'] = {$tor_image_posting}; \$config['robot_enable'] = {$robot_enable}; \$config['new_thread_capt'] = {$new_thread_capt}; \$config['hour_max_threads'] = {$hour_max_threads}; \$config['reply_limit'] = {$reply_limit}; \$config['max_pages'] = {$max_pages}; \$config['max_newlines'] = {$max_newlines}; \$config['oekaki'] = {$oekaki}; \$config['min_body'] = {$min_body}; \$config['mod']['view_bumplock'] = {$view_bumplock}; {$code_tags} {$katex} {$replace} {$multiimage} {$allow_flash} {$allow_pdf} {$user_flags} {$assets} {$locale} {$anal_filenames} {$file_board} if (\$config['disable_images']) \t\$config['max_pages'] = 10000; {$add_to_config} EOT; // Clean up our CSS...no more expression() or off-site URLs. $clean_css = preg_replace('/expression\\s*\\(/', '', $_POST['css']); $matched = array(); preg_match_all("#{$config['link_regex']}#im", $clean_css, $matched); if (isset($matched[0])) { foreach ($matched[0] as $match) { $match_okay = false; foreach ($config['allowed_offsite_urls'] as $allowed_url) { if (strpos($match, $allowed_url) !== false && strpos($match, '#') === false && strpos($match, '?') === false && strpos($match, ';') === false) { $match_okay = true; } } if ($match_okay !== true) { error(sprintf(_("Off-site link \"%s\" is not allowed in the board stylesheet"), $match)); } } } //Filter out imports from sites with potentially unsafe content $match_imports = '@import[^;]*'; $matched = array(); preg_match_all("#{$match_imports}#im", $clean_css, $matched); $unsafe_import_urls = array('https://a.pomf.se/'); if (isset($matched[0])) { foreach ($matched[0] as $match) { $match_okay = true; foreach ($unsafe_import_urls as $unsafe_import_url) { if (strpos($match, $unsafe_import_url) !== false && strpos($match, '#') === false) { $match_okay = false; } } if ($match_okay !== true) { error(sprintf(_("Potentially unsafe import \"%s\" is not allowed in the board stylesheet"), $match)); } } } $query = query('SELECT `uri`, `title`, `subtitle` FROM ``boards`` WHERE `8archive` = TRUE'); file_write('8archive.json', json_encode($query->fetchAll(PDO::FETCH_ASSOC))); file_write($b . '/config.php', $config_file); file_write('stylesheets/board/' . $b . '.css', $clean_css); $_config = $config; unset($config['wordfilters']); // Faster than openBoard and bypasses cache...we're trusting the PHP output // to be safe enough to run with every request, we can eval it here. eval(str_replace('flags.php', "{$b}/flags.php", preg_replace('/^\\<\\?php$/m', '', $config_file))); // czaks: maybe reconsider using it, now that config is cached? // be smarter about rebuilds...only some changes really require us to rebuild all threads if ($_config['captcha']['enabled'] != $config['captcha']['enabled'] || $_config['new_thread_capt'] != $config['new_thread_capt'] || $_config['captcha']['extra'] != $config['captcha']['extra'] || $_config['blotter'] != $config['blotter'] || $_config['field_disable_name'] != $config['field_disable_name'] || $_config['show_sages'] != (isset($config['show_sages']) && $config['show_sages'])) { buildIndex(); $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $b)) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { buildThread($post['id']); } } modLog('Edited board settings', $b); } $query = prepare('SELECT * FROM boards WHERE uri = :board'); $query->bindValue(':board', $b); $query->execute() or error(db_error($query)); $board = $query->fetchAll()[0]; // Clean the cache if ($config['cache']['enabled']) { cache::delete('board_' . $board['uri']); cache::delete('all_boards'); cache::delete('config_' . $board['uri']); cache::delete('events_' . $board['uri']); unlink('tmp/cache/locale_' . $board['uri']); } $css = @file_get_contents('stylesheets/board/' . $board['uri'] . '.css'); mod_page(_('Board configuration'), 'mod/settings.html', array('board' => $board, 'css' => prettify_textarea($css), 'token' => make_secure_link_token('settings/' . $board['uri']), 'languages' => $possible_languages, 'allowed_urls' => $config['allowed_offsite_urls'])); }
if ($is_an_image && $post['thumb'] != 'spoiler') { $post['thumb'] = substr_replace($post['thumb'], '', 0, mb_strlen($board['dir'] . $config['dir']['thumb'])); } } $id = post($post, $OP); if (isset($post['tracked_cites'])) { foreach ($post['tracked_cites'] as $cite) { $query = prepare('INSERT INTO `cites` VALUES (:board, :post, :target_board, :target)'); $query->bindValue(':board', $board['uri']); $query->bindValue(':post', $id, PDO::PARAM_INT); $query->bindValue(':target_board', $cite[0]); $query->bindValue(':target', $cite[1], PDO::PARAM_INT); $query->execute() or error(db_error($query)); } } buildThread($OP ? $id : $post['thread']); if (!$OP && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || numPosts($post['thread']) < $config['reply_limit'])) { bumpThread($post['thread']); } if ($OP) { clean(); } buildIndex(); if (isset($_SERVER['HTTP_REFERER'])) { // Tell Javascript that we posted successfully if (isset($_COOKIE[$config['cookies']['js']])) { $js = json_decode($_COOKIE[$config['cookies']['js']]); } else { $js = (object) array(); } // Tell it to delete the cached post for referer
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']); } } }
$post['file_thumb'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']; } else { $post['has_file'] = false; } $replies[] = $post; } openBoard($targetBoard); foreach ($replies as &$post) { post($post, false); if ($post['has_file']) { $clone($post['file_src'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']); $clone($post['file_thumb'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']); } } // build thread buildThread($newID); buildIndex(); // trigger themes rebuildThemes('post'); openBoard($boardName); if ($shadow) { // lock thread $query = prepare(sprintf("UPDATE `posts_%s` SET `locked` = 1 WHERE `id` = :id", $board['uri'])); $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); $post = array('mod' => true, 'subject' => '', 'email' => '', 'name' => $config['mod']['shadow_name'], 'capcode' => $config['mod']['shadow_capcode'], 'trip' => '', 'body' => sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID), 'password' => '', 'has_file' => false, 'thread' => $postID); markup($post['body']); $botID = post($post, false); header('Location: ?/' . sprintf($config['board_path'], $boardName) . $config['dir']['res'] . sprintf($config['file_page'], $postID) . '#' . $botID, true, $config['redirect_http']); } else { deletePost($postID);
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; }