|
|
@ -1575,6 +1575,232 @@ function mod_move($originBoard, $postID) { |
|
|
|
mod_page(_('Move thread'), 'mod/move.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); |
|
|
|
} |
|
|
|
|
|
|
|
function mod_merge($originBoard, $postID) { |
|
|
|
global $board, $config, $mod, $pdo; |
|
|
|
|
|
|
|
if (!openBoard($originBoard)) |
|
|
|
error($config['error']['noboard']); |
|
|
|
|
|
|
|
if (!hasPermission($config['mod']['merge'], $originBoard)) |
|
|
|
error($config['error']['noaccess']); |
|
|
|
|
|
|
|
$query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL', $originBoard)); |
|
|
|
$query->bindValue(':id', $postID); |
|
|
|
$query->execute() or error(db_error($query)); |
|
|
|
if (!$post = $query->fetch(PDO::FETCH_ASSOC)) |
|
|
|
error($config['error']['404']); |
|
|
|
$sourceOp = ""; |
|
|
|
if ($post['thread']){ |
|
|
|
$sourceOp = $post['thread']; |
|
|
|
} |
|
|
|
else{ |
|
|
|
$sourceOp = $post['id']; |
|
|
|
} |
|
|
|
$newpost = ""; |
|
|
|
$boards = listBoards(); |
|
|
|
|
|
|
|
if (isset($_POST['board'])) { |
|
|
|
$targetBoard = $_POST['board']; |
|
|
|
$targetOp = ""; |
|
|
|
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 |
|
|
|
if (!$newpost = $query->fetch(PDO::FETCH_ASSOC)){ |
|
|
|
error($config['error']['404']); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if ($newpost['thread']){ |
|
|
|
$targetOp = $newpost['thread']; |
|
|
|
} |
|
|
|
else{ |
|
|
|
$targetOp = $newpost['id']; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ($targetBoard === $originBoard){ |
|
|
|
// Just update the thread id for all posts in the original thread to new op |
|
|
|
$query = prepare(sprintf('UPDATE ``posts_%s`` SET `thread` = :newthread WHERE `id` = :oldthread OR `thread` = :oldthread', $originBoard)); |
|
|
|
$query->bindValue(':newthread', $targetOp, PDO::PARAM_INT); |
|
|
|
$query->bindValue(':oldthread', $sourceOp, PDO::PARAM_INT); |
|
|
|
$query->execute() or error(db_error($query)); |
|
|
|
// build index |
|
|
|
buildIndex(); |
|
|
|
|
|
|
|
// build new thread |
|
|
|
buildThread($targetOp); |
|
|
|
|
|
|
|
// trigger themes |
|
|
|
rebuildThemes('post', $targetBoard); |
|
|
|
modLog("Merged thread with #${sourceOp} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${targetOp})", $originBoard); |
|
|
|
|
|
|
|
// redirect |
|
|
|
header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($newpost) . '#' . $targetOp, true, $config['redirect_http']); |
|
|
|
} |
|
|
|
else { |
|
|
|
// Move thread to new board without shadow thread and then update the thread id for all posts in that thread to new op |
|
|
|
// indicate that the post is a thread |
|
|
|
if (count($boards) <= 1) |
|
|
|
error(_('Impossible to merge thread to different board; there is only one board.')); |
|
|
|
$post['op'] = true; |
|
|
|
|
|
|
|
if ($post['files']) { |
|
|
|
$post['files'] = json_decode($post['files'], TRUE); |
|
|
|
$post['has_file'] = true; |
|
|
|
foreach ($post['files'] as $i => &$file) { |
|
|
|
if ($file['file'] === 'deleted') |
|
|
|
continue; |
|
|
|
$file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; |
|
|
|
$file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['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 thread |
|
|
|
$newID = post($post); |
|
|
|
|
|
|
|
$op = $post; |
|
|
|
$op['id'] = $newID; |
|
|
|
|
|
|
|
if ($post['has_file']) { |
|
|
|
// copy image |
|
|
|
foreach ($post['files'] as $i => &$file) { |
|
|
|
if ($file['file'] !== 'deleted') |
|
|
|
$clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); |
|
|
|
if (isset($file['thumb']) && !in_array($file['thumb'], array('spoiler', 'deleted', 'file'))) |
|
|
|
$clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// go back to the original board to fetch replies |
|
|
|
openBoard($originBoard); |
|
|
|
|
|
|
|
$query = prepare(sprintf('SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id`', $originBoard)); |
|
|
|
$query->bindValue(':id', $postID, PDO::PARAM_INT); |
|
|
|
$query->execute() or error(db_error($query)); |
|
|
|
|
|
|
|
$replies = array(); |
|
|
|
|
|
|
|
while ($post = $query->fetch(PDO::FETCH_ASSOC)) { |
|
|
|
$post['mod'] = true; |
|
|
|
$post['thread'] = $newID; |
|
|
|
|
|
|
|
if ($post['files']) { |
|
|
|
$post['files'] = json_decode($post['files'], TRUE); |
|
|
|
$post['has_file'] = true; |
|
|
|
foreach ($post['files'] as $i => &$file) { |
|
|
|
$file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; |
|
|
|
$file['thumb_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']; |
|
|
|
} |
|
|
|
} else { |
|
|
|
$post['has_file'] = false; |
|
|
|
} |
|
|
|
|
|
|
|
$replies[] = $post; |
|
|
|
} |
|
|
|
|
|
|
|
$newIDs = array($postID => $newID); |
|
|
|
|
|
|
|
openBoard($targetBoard); |
|
|
|
|
|
|
|
foreach ($replies as &$post) { |
|
|
|
$query = prepare('SELECT `target` FROM ``cites`` WHERE `target_board` = :board AND `board` = :board AND `post` = :post'); |
|
|
|
$query->bindValue(':board', $originBoard); |
|
|
|
$query->bindValue(':post', $post['id'], PDO::PARAM_INT); |
|
|
|
$query->execute() or error(db_error($query)); |
|
|
|
|
|
|
|
// correct >>X links |
|
|
|
while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { |
|
|
|
if (isset($newIDs[$cite['target']])) { |
|
|
|
$post['body_nomarkup'] = preg_replace( |
|
|
|
'/(>>(>\/' . preg_quote($originBoard, '/') . '\/)?)' . preg_quote($cite['target'], '/') . '/', |
|
|
|
'>>' . $newIDs[$cite['target']], |
|
|
|
$post['body_nomarkup']); |
|
|
|
|
|
|
|
$post['body'] = $post['body_nomarkup']; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$post['body'] = $post['body_nomarkup']; |
|
|
|
|
|
|
|
$post['op'] = false; |
|
|
|
$post['tracked_cites'] = markup($post['body'], true); |
|
|
|
|
|
|
|
if ($post['has_file']) { |
|
|
|
// copy image |
|
|
|
foreach ($post['files'] as $i => &$file) { |
|
|
|
$clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); |
|
|
|
$clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); |
|
|
|
} |
|
|
|
} |
|
|
|
// insert reply |
|
|
|
$newIDs[$post['id']] = $newPostID = post($post); |
|
|
|
|
|
|
|
if (!empty($post['tracked_cites'])) { |
|
|
|
$insert_rows = array(); |
|
|
|
foreach ($post['tracked_cites'] as $cite) { |
|
|
|
$insert_rows[] = '(' . |
|
|
|
$pdo->quote($board['uri']) . ', ' . $newPostID . ', ' . |
|
|
|
$pdo->quote($cite[0]) . ', ' . (int)$cite[1] . ')'; |
|
|
|
} |
|
|
|
query('INSERT INTO ``cites`` VALUES ' . implode(', ', $insert_rows)) or error(db_error()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
modLog("Moved thread #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); |
|
|
|
|
|
|
|
// build new thread |
|
|
|
buildThread($newID); |
|
|
|
|
|
|
|
clean(); |
|
|
|
buildIndex(); |
|
|
|
|
|
|
|
// trigger themes |
|
|
|
rebuildThemes('post', $targetBoard); |
|
|
|
|
|
|
|
$newboard = $board; |
|
|
|
|
|
|
|
// return to original board |
|
|
|
openBoard($originBoard); |
|
|
|
|
|
|
|
deletePost($postID); |
|
|
|
buildIndex(); |
|
|
|
|
|
|
|
openBoard($targetBoard); |
|
|
|
// Just update the thread id for all posts in the original thread to new op |
|
|
|
$query = prepare(sprintf('UPDATE ``posts_%s`` SET `thread` = :newthread WHERE `id` = :oldthread OR `thread` = :oldthread', $targetBoard)); |
|
|
|
$query->bindValue(':newthread', $targetOp, PDO::PARAM_INT); |
|
|
|
$query->bindValue(':oldthread', $newID, PDO::PARAM_INT); |
|
|
|
$query->execute() or error(db_error($query)); |
|
|
|
// build index |
|
|
|
buildIndex(); |
|
|
|
|
|
|
|
// build new thread |
|
|
|
buildThread($targetOp); |
|
|
|
|
|
|
|
// trigger themes |
|
|
|
rebuildThemes('post', $targetBoard); |
|
|
|
modLog("Merged thread with #${newID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${targetOp})", $targetBoard); |
|
|
|
|
|
|
|
// redirect |
|
|
|
header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($newpost) . '#' . $targetOp, true, $config['redirect_http']); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$security_token = make_secure_link_token($originBoard . '/merge/' . $postID); |
|
|
|
|
|
|
|
mod_page(_('Merge thread'), 'mod/merge.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); |
|
|
|
} |
|
|
|
|
|
|
|
function mod_ban_post($board, $delete, $post, $token = false) { |
|
|
|
global $config, $mod; |
|
|
|
|
|
|
|