diff --git a/inc/config.php b/inc/config.php index ec90df46..1b45da14 100644 --- a/inc/config.php +++ b/inc/config.php @@ -999,6 +999,9 @@ // persistent spammers and ban evaders. Again, a little more database load. $config['ban_cidr'] = true; + // Enable the moving of single replies + $config['move_replies'] = false; + // How often (minimum) to purge the ban list of expired bans (which have been seen). Only works when // $config['cache'] is enabled and working. $config['purge_bans'] = 60 * 60 * 12; // 12 hours diff --git a/inc/display.php b/inc/display.php index e2d23215..b78639d6 100644 --- a/inc/display.php +++ b/inc/display.php @@ -349,9 +349,14 @@ class Post { if (!empty($this->file) && $this->file != "deleted" && $this->file != null && $this->thumb != 'spoiler' && hasPermission($config['mod']['spoilerimage'], $board['uri'], $this->mod) && $config['spoiler_images']) $built .= ' ' . secure_link_confirm($config['mod']['link_spoilerimage'], 'Spoiler File', 'Are you sure you want to spoiler this file?', $board['uri'] . '/spoiler/' . $this->id); + // Move post + if (hasPermission($config['mod']['move'], $board['uri'], $this->mod) && $config['move_replies']) + $built .= ' ' . $config['mod']['link_move'] . ''; + // Edit post if (hasPermission($config['mod']['editpost'], $board['uri'], $this->mod)) $built .= ' ' . $config['mod']['link_editpost'] . ''; + if (!empty($built)) $built = '' . $built . ''; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 8b0c400e..4f876b45 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1002,6 +1002,99 @@ function mod_bumplock($board, $unbumplock, $post) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } +function mod_move_reply($originBoard, $postID) { + global $board, $config, $mod; + + if (!openBoard($originBoard)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['move'], $originBoard)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `id` = :id', $originBoard)); + $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['board'])) { + $targetBoard = $_POST['board']; + + if ($_POST['target_thread']) { + $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `id` = :id', $targetBoard)); + $query->bindValue(':id', $_POST['target_thread']); + $query->execute() or error(db_error($query)); // If it fails, thread probably does not exist + $post['op'] = false; + $post['thread'] = $_POST['target_thread']; + } + else { + $post['op'] = true; + } + + if ($post['file']) { + $post['has_file'] = true; + $post['width'] = &$post['filewidth']; + $post['height'] = &$post['fileheight']; + + $file_src = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']; + $file_thumb = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']; + } else { + $post['has_file'] = false; + } + + // allow thread to keep its same traits (stickied, locked, etc.) + $post['mod'] = true; + + if (!openBoard($targetBoard)) + error($config['error']['noboard']); + + // create the new post + $newID = post($post); + + if ($post['has_file']) { + // move the image + rename($file_src, sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']); + rename($file_thumb, sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']); + } + + buildIndex(); + + // trigger themes + rebuildThemes($post['op'] ? 'post-thread' : 'post'); + // mod log + modLog("Moved post #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); + + // return to original board + openBoard($originBoard); + + // delete original post + deletePost($postID); + buildIndex(); + + // open target board for redirect + openBoard($targetBoard); + + // Find new thread on our target board + $query = prepare(sprintf('SELECT thread FROM `posts_%s` WHERE `id` = :id', $targetBoard)); + $query->bindValue(':id', $newID); + $query->execute() or error(db_error($query)); + $post = $query->fetch(PDO::FETCH_ASSOC); + + // redirect + header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $newID) . '#' . $newID, true, $config['redirect_http']); + } + + else { + $boards = listBoards(); + + $security_token = make_secure_link_token($originBoard . '/move_reply/' . $postID); + + mod_page(_('Move reply'), 'mod/move_reply.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); + + } + +} + function mod_move($originBoard, $postID) { global $board, $config, $mod; @@ -1115,8 +1208,8 @@ function mod_move($originBoard, $postID) { if ($post['has_file']) { // copy image - $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']); + copy($post['file_src'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']); + copy($post['file_thumb'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']); } foreach ($post['tracked_cites'] as $cite) { diff --git a/mod.php b/mod.php index 0e98c4eb..f1ce6d04 100644 --- a/mod.php +++ b/mod.php @@ -65,6 +65,7 @@ $pages = array( '/ban' => 'secure_POST ban', // new ban '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread + '/(\%b)/move_reply/(\d+)' => 'secure_POST move_reply', // move reply '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post '/(\%b)/delete/(\d+)' => 'secure delete', // delete post '/(\%b)/deletefile/(\d+)' => 'secure deletefile', // delete file from post