PageRenderTime 62ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/moderate.php

https://bitbucket.org/gencer/punbb
PHP | 1742 lines | 1215 code | 396 blank | 131 comment | 213 complexity | 340de138ab18051a67fe261c8b396d19 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Provides various mass-moderation tools to moderators.
  4. *
  5. * @copyright (C) 2008-2012 PunBB, partially based on code (C) 2008-2009 FluxBB.org
  6. * @license http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
  7. * @package PunBB
  8. */
  9. if (!defined('FORUM_ROOT'))
  10. define('FORUM_ROOT', './');
  11. require FORUM_ROOT.'include/common.php';
  12. ($hook = get_hook('mr_start')) ? eval($hook) : null;
  13. // Load the misc.php language file
  14. require FORUM_ROOT.'lang/'.$forum_user['language'].'/misc.php';
  15. // This particular function doesn't require forum-based moderator access. It can be used
  16. // by all moderators and admins.
  17. if (isset($_GET['get_host']))
  18. {
  19. if (!$forum_user['is_admmod'])
  20. message($lang_common['No permission']);
  21. $_get_host = $_GET['get_host'];
  22. if (!is_string($_get_host))
  23. message($lang_common['Bad request']);
  24. ($hook = get_hook('mr_view_ip_selected')) ? eval($hook) : null;
  25. // Is get_host an IP address or a post ID?
  26. if (preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $_get_host) || preg_match('/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/', $_get_host))
  27. $ip = $_get_host;
  28. else
  29. {
  30. $get_host = intval($_get_host);
  31. if ($get_host < 1)
  32. message($lang_common['Bad request']);
  33. $query = array(
  34. 'SELECT' => 'p.poster_ip',
  35. 'FROM' => 'posts AS p',
  36. 'WHERE' => 'p.id='.$get_host
  37. );
  38. ($hook = get_hook('mr_view_ip_qr_get_poster_ip')) ? eval($hook) : null;
  39. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  40. $ip = $forum_db->result($result);
  41. if (!$ip)
  42. message($lang_common['Bad request']);
  43. }
  44. ($hook = get_hook('mr_view_ip_pre_output')) ? eval($hook) : null;
  45. message(sprintf($lang_misc['Hostname lookup'], $ip, @gethostbyaddr($ip), '<a href="'.forum_link($forum_url['admin_users']).'?show_users='.$ip.'">'.$lang_misc['Show more users'].'</a>'));
  46. }
  47. // All other functions require moderator/admin access
  48. $fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;
  49. if ($fid < 1)
  50. message($lang_common['Bad request']);
  51. // Get some info about the forum we're moderating
  52. $query = array(
  53. 'SELECT' => 'f.forum_name, f.redirect_url, f.num_topics, f.moderators, f.sort_by',
  54. 'FROM' => 'forums AS f',
  55. 'JOINS' => array(
  56. array(
  57. 'LEFT JOIN' => 'forum_perms AS fp',
  58. 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$forum_user['g_id'].')'
  59. )
  60. ),
  61. 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid
  62. );
  63. ($hook = get_hook('mr_qr_get_forum_data')) ? eval($hook) : null;
  64. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  65. $cur_forum = $forum_db->fetch_assoc($result);
  66. if (!$cur_forum)
  67. message($lang_common['Bad request']);
  68. // Make sure we're not trying to moderate a redirect forum
  69. if ($cur_forum['redirect_url'] != '')
  70. message($lang_common['Bad request']);
  71. // Setup the array of moderators
  72. $mods_array = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
  73. ($hook = get_hook('mr_pre_permission_check')) ? eval($hook) : null;
  74. if ($forum_user['g_id'] != FORUM_ADMIN && ($forum_user['g_moderator'] != '1' || !array_key_exists($forum_user['username'], $mods_array)))
  75. message($lang_common['No permission']);
  76. // Get topic/forum tracking data
  77. if (!$forum_user['is_guest'])
  78. $tracked_topics = get_tracked_topics();
  79. // Did someone click a cancel button?
  80. if (isset($_POST['cancel']))
  81. redirect(forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name']))), $lang_common['Cancel redirect']);
  82. // All topic moderation features require a topic id in GET
  83. if (isset($_GET['tid']))
  84. {
  85. ($hook = get_hook('mr_post_actions_selected')) ? eval($hook) : null;
  86. $tid = intval($_GET['tid']);
  87. if ($tid < 1)
  88. message($lang_common['Bad request']);
  89. // Fetch some info about the topic
  90. $query = array(
  91. 'SELECT' => 't.subject, t.poster, t.first_post_id, t.posted, t.num_replies',
  92. 'FROM' => 'topics AS t',
  93. 'WHERE' => 't.id='.$tid.' AND t.moved_to IS NULL'
  94. );
  95. ($hook = get_hook('mr_post_actions_qr_get_topic_info')) ? eval($hook) : null;
  96. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  97. $cur_topic = $forum_db->fetch_assoc($result);
  98. if (!$cur_topic)
  99. message($lang_common['Bad request']);
  100. // User pressed the cancel button
  101. if (isset($_POST['delete_posts_cancel']))
  102. redirect(forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject']))), $lang_common['Cancel redirect']);
  103. // Delete one or more posts
  104. if (isset($_POST['delete_posts']) || isset($_POST['delete_posts_comply']))
  105. {
  106. ($hook = get_hook('mr_delete_posts_form_submitted')) ? eval($hook) : null;
  107. $posts = isset($_POST['posts']) && !empty($_POST['posts']) ? $_POST['posts'] : array();
  108. $posts = array_map('intval', (is_array($posts) ? $posts : explode(',', $posts)));
  109. if (empty($posts))
  110. message($lang_misc['No posts selected']);
  111. if (isset($_POST['delete_posts_comply']))
  112. {
  113. if (!isset($_POST['req_confirm']))
  114. redirect(forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject']))), $lang_common['No confirm redirect']);
  115. ($hook = get_hook('mr_confirm_delete_posts_form_submitted')) ? eval($hook) : null;
  116. // Verify that the post IDs are valid
  117. $query = array(
  118. 'SELECT' => 'COUNT(p.id)',
  119. 'FROM' => 'posts AS p',
  120. 'WHERE' => 'p.id IN('.implode(',', $posts).') AND p.id!='.$cur_topic['first_post_id'].' AND p.topic_id='.$tid
  121. );
  122. ($hook = get_hook('mr_confirm_delete_posts_qr_verify_post_ids')) ? eval($hook) : null;
  123. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  124. if ($forum_db->result($result) != count($posts))
  125. message($lang_common['Bad request']);
  126. // Delete the posts
  127. $query = array(
  128. 'DELETE' => 'posts',
  129. 'WHERE' => 'id IN('.implode(',', $posts).')'
  130. );
  131. ($hook = get_hook('mr_confirm_delete_posts_qr_delete_posts')) ? eval($hook) : null;
  132. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  133. if (!defined('FORUM_SEARCH_IDX_FUNCTIONS_LOADED'))
  134. require FORUM_ROOT.'include/search_idx.php';
  135. strip_search_index($posts);
  136. sync_topic($tid);
  137. sync_forum($fid);
  138. $forum_flash->add_info($lang_misc['Delete posts redirect']);
  139. ($hook = get_hook('mr_confirm_delete_posts_pre_redirect')) ? eval($hook) : null;
  140. redirect(forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject']))), $lang_misc['Delete posts redirect']);
  141. }
  142. // Setup form
  143. $forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] = 0;
  144. $forum_page['form_action'] = forum_link($forum_url['moderate_topic'], array($fid, $tid));
  145. $forum_page['hidden_fields'] = array(
  146. 'csrf_token' => '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />',
  147. 'posts' => '<input type="hidden" name="posts" value="'.implode(',', $posts).'" />'
  148. );
  149. // Setup breadcrumbs
  150. $forum_page['crumbs'] = array(
  151. array($forum_config['o_board_title'], forum_link($forum_url['index'])),
  152. array($cur_forum['forum_name'], forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name'])))),
  153. array($cur_topic['subject'], forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject'])))),
  154. $lang_misc['Delete posts']
  155. );
  156. ($hook = get_hook('mr_confirm_delete_posts_pre_header_load')) ? eval($hook) : null;
  157. define('FORUM_PAGE', 'dialogue');
  158. require FORUM_ROOT.'header.php';
  159. // START SUBST - <!-- forum_main -->
  160. ob_start();
  161. ($hook = get_hook('mr_confirm_delete_posts_output_start')) ? eval($hook) : null;
  162. ?>
  163. <div class="main-head">
  164. <h2 class="hn"><span><?php echo $lang_misc['Confirm post delete'] ?></span></h2>
  165. </div>
  166. <div class="main-content main-frm">
  167. <form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
  168. <div class="hidden">
  169. <?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
  170. </div>
  171. <?php ($hook = get_hook('mr_confirm_delete_posts_pre_fieldset')) ? eval($hook) : null; ?>
  172. <fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
  173. <legend class="group-legend"><strong><?php echo $lang_misc['Delete posts'] ?></strong></legend>
  174. <?php ($hook = get_hook('mr_confirm_delete_posts_pre_confirm_checkbox')) ? eval($hook) : null; ?>
  175. <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
  176. <div class="sf-box checkbox">
  177. <span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="req_confirm" value="1" checked="checked" /></span>
  178. <label for="fld<?php echo $forum_page['fld_count'] ?>"><span><?php echo $lang_common['Please confirm'] ?></span> <?php echo $lang_misc['Confirm post delete'] ?>.</label>
  179. </div>
  180. </div>
  181. <?php ($hook = get_hook('mr_confirm_delete_posts_pre_fieldset_end')) ? eval($hook) : null; ?>
  182. </fieldset>
  183. <?php ($hook = get_hook('mr_confirm_delete_posts_fieldset_end')) ? eval($hook) : null; ?>
  184. <div class="frm-buttons">
  185. <span class="submit primary caution"><input type="submit" name="delete_posts_comply" value="<?php echo $lang_common['Delete'] ?>" /></span>
  186. <span class="cancel"><input type="submit" name="cancel" value="<?php echo $lang_common['Cancel'] ?>" formnovalidate /></span>
  187. </div>
  188. </form>
  189. </div>
  190. <?php
  191. $forum_id = $fid;
  192. ($hook = get_hook('mr_confirm_delete_posts_end')) ? eval($hook) : null;
  193. $tpl_temp = forum_trim(ob_get_contents());
  194. $tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
  195. ob_end_clean();
  196. // END SUBST - <!-- forum_main -->
  197. require FORUM_ROOT.'footer.php';
  198. }
  199. else if (isset($_POST['split_posts']) || isset($_POST['split_posts_comply']))
  200. {
  201. ($hook = get_hook('mr_split_posts_form_submitted')) ? eval($hook) : null;
  202. $posts = isset($_POST['posts']) && !empty($_POST['posts']) ? $_POST['posts'] : array();
  203. $posts = array_map('intval', (is_array($posts) ? $posts : explode(',', $posts)));
  204. if (empty($posts))
  205. message($lang_misc['No posts selected']);
  206. if (isset($_POST['split_posts_comply']))
  207. {
  208. if (!isset($_POST['req_confirm']))
  209. redirect(forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject']))), $lang_common['No confirm redirect']);
  210. // Load the post.php language file
  211. require FORUM_ROOT.'lang/'.$forum_user['language'].'/post.php';
  212. ($hook = get_hook('mr_confirm_split_posts_form_submitted')) ? eval($hook) : null;
  213. // Verify that the post IDs are valid
  214. $query = array(
  215. 'SELECT' => 'COUNT(p.id)',
  216. 'FROM' => 'posts AS p',
  217. 'WHERE' => 'p.id IN('.implode(',', $posts).') AND p.id!='.$cur_topic['first_post_id'].' AND p.topic_id='.$tid
  218. );
  219. ($hook = get_hook('mr_confirm_split_posts_qr_verify_post_ids')) ? eval($hook) : null;
  220. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  221. if ($forum_db->result($result) != count($posts))
  222. message($lang_common['Bad request']);
  223. $new_subject = isset($_POST['new_subject']) ? forum_trim($_POST['new_subject']) : '';
  224. if ($new_subject == '')
  225. message($lang_post['No subject']);
  226. else if (utf8_strlen($new_subject) > FORUM_SUBJECT_MAXIMUM_LENGTH)
  227. message(sprintf($lang_post['Too long subject'], FORUM_SUBJECT_MAXIMUM_LENGTH));
  228. // Get data from the new first post
  229. $query = array(
  230. 'SELECT' => 'p.id, p.poster, p.posted',
  231. 'FROM' => 'posts AS p',
  232. 'WHERE' => 'p.id = '.min($posts)
  233. );
  234. ($hook = get_hook('mr_confirm_split_posts_qr_get_first_post_data')) ? eval($hook) : null;
  235. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  236. $first_post_data = $forum_db->fetch_assoc($result);
  237. // Create the new topic
  238. $query = array(
  239. 'INSERT' => 'poster, subject, posted, first_post_id, forum_id',
  240. 'INTO' => 'topics',
  241. 'VALUES' => '\''.$forum_db->escape($first_post_data['poster']).'\', \''.$forum_db->escape($new_subject).'\', '.$first_post_data['posted'].', '.$first_post_data['id'].', '.$fid
  242. );
  243. ($hook = get_hook('mr_confirm_split_posts_qr_add_topic')) ? eval($hook) : null;
  244. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  245. $new_tid = $forum_db->insert_id();
  246. // Move the posts to the new topic
  247. $query = array(
  248. 'UPDATE' => 'posts',
  249. 'SET' => 'topic_id='.$new_tid,
  250. 'WHERE' => 'id IN('.implode(',', $posts).')'
  251. );
  252. ($hook = get_hook('mr_confirm_split_posts_qr_move_posts')) ? eval($hook) : null;
  253. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  254. // Sync last post data for the old topic, the new topic, and the forum itself
  255. sync_topic($new_tid);
  256. sync_topic($tid);
  257. sync_forum($fid);
  258. $forum_flash->add_info($lang_misc['Split posts redirect']);
  259. ($hook = get_hook('mr_confirm_split_posts_pre_redirect')) ? eval($hook) : null;
  260. redirect(forum_link($forum_url['topic'], array($new_tid, sef_friendly($new_subject))), $lang_misc['Split posts redirect']);
  261. }
  262. // Setup form
  263. $forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] = 0;
  264. $forum_page['form_action'] = forum_link($forum_url['moderate_topic'], array($fid, $tid));
  265. $forum_page['hidden_fields'] = array(
  266. 'csrf_token' => '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />',
  267. 'posts' => '<input type="hidden" name="posts" value="'.implode(',', $posts).'" />'
  268. );
  269. // Setup breadcrumbs
  270. $forum_page['crumbs'] = array(
  271. array($forum_config['o_board_title'], forum_link($forum_url['index'])),
  272. array($cur_forum['forum_name'], forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name'])))),
  273. array($cur_topic['subject'], forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject'])))),
  274. $lang_misc['Split posts']
  275. );
  276. ($hook = get_hook('mr_confirm_split_posts_pre_header_load')) ? eval($hook) : null;
  277. define('FORUM_PAGE', 'dialogue');
  278. require FORUM_ROOT.'header.php';
  279. // START SUBST - <!-- forum_main -->
  280. ob_start();
  281. ($hook = get_hook('mr_confirm_split_posts_output_start')) ? eval($hook) : null;
  282. ?>
  283. <div class="main-head">
  284. <h2 class="hn"><span><?php echo $lang_misc['Confirm post split'] ?></span></h2>
  285. </div>
  286. <div class="main-content main-frm">
  287. <form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
  288. <div class="hidden">
  289. <?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
  290. </div>
  291. <?php ($hook = get_hook('mr_confirm_split_posts_pre_fieldset')) ? eval($hook) : null; ?>
  292. <fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
  293. <legend class="group-legend"><strong><?php echo $lang_misc['Split posts'] ?></strong></legend>
  294. <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
  295. <?php ($hook = get_hook('mr_confirm_split_posts_pre_subject')) ? eval($hook) : null; ?>
  296. <div class="sf-box text required">
  297. <label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_misc['New subject'] ?></span></label><br />
  298. <span class="fld-input"><input type="text" id="fld<?php echo $forum_page['fld_count'] ?>" name="new_subject" size="<?php echo FORUM_SUBJECT_MAXIMUM_LENGTH ?>" maxlength="<?php echo FORUM_SUBJECT_MAXIMUM_LENGTH ?>" required /></span>
  299. </div>
  300. <?php ($hook = get_hook('mr_confirm_split_posts_pre_confirm_checkbox')) ? eval($hook) : null; ?>
  301. <div class="sf-box checkbox">
  302. <span class="fld-input"><input type="checkbox" id="fld<?php echo ++$forum_page['fld_count'] ?>" name="req_confirm" value="1" checked="checked" /></span>
  303. <label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_common['Please confirm'] ?></span> <?php echo $lang_misc['Confirm topic split'] ?>.</label>
  304. </div>
  305. </div>
  306. <?php ($hook = get_hook('mr_confirm_split_posts_pre_fieldset_end')) ? eval($hook) : null; ?>
  307. </fieldset>
  308. <?php ($hook = get_hook('mr_confirm_split_posts_fieldset_end')) ? eval($hook) : null; ?>
  309. <div class="frm-buttons">
  310. <span class="submit primary"><input type="submit" name="split_posts_comply" value="<?php echo $lang_common['Split'] ?>" /></span>
  311. <span class="cancel"><input type="submit" name="cancel" value="<?php echo $lang_common['Cancel'] ?>" formnovalidate /></span>
  312. </div>
  313. </form>
  314. </div>
  315. <?php
  316. $forum_id = $fid;
  317. ($hook = get_hook('mr_confirm_split_posts_end')) ? eval($hook) : null;
  318. $tpl_temp = forum_trim(ob_get_contents());
  319. $tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
  320. ob_end_clean();
  321. // END SUBST - <!-- forum_main -->
  322. require FORUM_ROOT.'footer.php';
  323. }
  324. // Show the moderate topic view
  325. // Load the viewtopic.php language file
  326. require FORUM_ROOT.'lang/'.$forum_user['language'].'/topic.php';
  327. // Used to disable the Split and Delete buttons if there are no replies to this topic
  328. $forum_page['button_status'] = ($cur_topic['num_replies'] == 0) ? ' disabled="disabled"' : '';
  329. // Determine the post offset (based on $_GET['p'])
  330. $forum_page['num_pages'] = ceil(($cur_topic['num_replies'] + 1) / $forum_user['disp_posts']);
  331. $forum_page['page'] = (!isset($_GET['p']) || !is_numeric($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $forum_page['num_pages']) ? 1 : intval($_GET['p']);
  332. $forum_page['start_from'] = $forum_user['disp_posts'] * ($forum_page['page'] - 1);
  333. $forum_page['finish_at'] = min(($forum_page['start_from'] + $forum_user['disp_posts']), ($cur_topic['num_replies'] + 1));
  334. $forum_page['items_info'] = generate_items_info($lang_misc['Posts'], ($forum_page['start_from'] + 1), ($cur_topic['num_replies'] + 1));
  335. // Generate paging links
  336. $forum_page['page_post']['paging'] = '<p class="paging"><span class="pages">'.$lang_common['Pages'].'</span> '.paginate($forum_page['num_pages'], $forum_page['page'], $forum_url['moderate_topic'], $lang_common['Paging separator'], array($fid, $tid)).'</p>';
  337. // Navigation links for header and page numbering for title/meta description
  338. if ($forum_page['page'] < $forum_page['num_pages'])
  339. {
  340. $forum_page['nav']['last'] = '<link rel="last" href="'.forum_sublink($forum_url['moderate_topic'], $forum_url['page'], $forum_page['num_pages'], array($fid, $tid)).'" title="'.$lang_common['Page'].' '.$forum_page['num_pages'].'" />';
  341. $forum_page['nav']['next'] = '<link rel="next" href="'.forum_sublink($forum_url['moderate_topic'], $forum_url['page'], ($forum_page['page'] + 1), array($fid, $tid)).'" title="'.$lang_common['Page'].' '.($forum_page['page'] + 1).'" />';
  342. }
  343. if ($forum_page['page'] > 1)
  344. {
  345. $forum_page['nav']['prev'] = '<link rel="prev" href="'.forum_sublink($forum_url['moderate_topic'], $forum_url['page'], ($forum_page['page'] - 1), array($fid, $tid)).'" title="'.$lang_common['Page'].' '.($forum_page['page'] - 1).'" />';
  346. $forum_page['nav']['first'] = '<link rel="first" href="'.forum_link($forum_url['moderate_topic'], array($fid, $tid)).'" title="'.$lang_common['Page'].' 1" />';
  347. }
  348. if ($forum_config['o_censoring'] == '1')
  349. $cur_topic['subject'] = censor_words($cur_topic['subject']);
  350. // Setup form
  351. $forum_page['form_action'] = forum_link($forum_url['moderate_topic'], array($fid, $tid));
  352. // Setup breadcrumbs
  353. $forum_page['crumbs'] = array(
  354. array($forum_config['o_board_title'], forum_link($forum_url['index'])),
  355. array($cur_forum['forum_name'], forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name'])))),
  356. array($cur_topic['subject'], forum_link($forum_url['topic'], array($tid, sef_friendly($cur_topic['subject'])))),
  357. $lang_topic['Moderate topic']
  358. );
  359. // Setup main heading
  360. $forum_page['main_title'] = sprintf($lang_misc['Moderate topic head'], forum_htmlencode($cur_topic['subject']));
  361. $forum_page['main_head_options']['select_all'] = '<span '.(empty($forum_page['main_head_options']) ? ' class="first-item"' : '').'><span class="select-all js_link" data-check-form="mr-post-actions-form">'.$lang_misc['Select all'].'</span></span>';
  362. $forum_page['main_foot_options']['select_all'] = '<span '.(empty($forum_page['main_foot_options']) ? ' class="first-item"' : '').'><span class="select-all js_link" data-check-form="mr-post-actions-form">'.$lang_misc['Select all'].'</span></span>';
  363. if ($forum_page['num_pages'] > 1)
  364. $forum_page['main_head_pages'] = sprintf($lang_common['Page info'], $forum_page['page'], $forum_page['num_pages']);
  365. ($hook = get_hook('mr_post_actions_pre_header_load')) ? eval($hook) : null;
  366. define('FORUM_PAGE', 'modtopic');
  367. require FORUM_ROOT.'header.php';
  368. // START SUBST - <!-- forum_main -->
  369. ob_start();
  370. ($hook = get_hook('mr_post_actions_output_start')) ? eval($hook) : null;
  371. ?>
  372. <div class="main-head">
  373. <?php
  374. if (!empty($forum_page['main_head_options']))
  375. echo "\n\t\t".'<p class="options">'.implode(' ', $forum_page['main_head_options']).'</p>';
  376. ?>
  377. <h2 class="hn"><span><?php echo $forum_page['items_info'] ?></span></h2>
  378. </div>
  379. <form id="mr-post-actions-form" class="newform" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
  380. <div class="main-content main-topic">
  381. <div class="hidden">
  382. <input type="hidden" name="csrf_token" value="<?php echo generate_form_token($forum_page['form_action']) ?>" />
  383. </div>
  384. <?php
  385. if (!defined('FORUM_PARSER_LOADED'))
  386. require FORUM_ROOT.'include/parser.php';
  387. $forum_page['item_count'] = 0; // Keep track of post numbers
  388. // Retrieve the posts (and their respective poster)
  389. $query = array(
  390. 'SELECT' => 'u.title, u.num_posts, g.g_id, g.g_user_title, p.id, p.poster, p.poster_id, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by',
  391. 'FROM' => 'posts AS p',
  392. 'JOINS' => array(
  393. array(
  394. 'INNER JOIN' => 'users AS u',
  395. 'ON' => 'u.id=p.poster_id'
  396. ),
  397. array(
  398. 'INNER JOIN' => 'groups AS g',
  399. 'ON' => 'g.g_id=u.group_id'
  400. )
  401. ),
  402. 'WHERE' => 'p.topic_id='.$tid,
  403. 'ORDER BY' => 'p.id',
  404. 'LIMIT' => $forum_page['start_from'].','.$forum_user['disp_posts']
  405. );
  406. ($hook = get_hook('mr_post_actions_qr_get_posts')) ? eval($hook) : null;
  407. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  408. while ($cur_post = $forum_db->fetch_assoc($result))
  409. {
  410. ($hook = get_hook('mr_post_actions_loop_start')) ? eval($hook) : null;
  411. ++$forum_page['item_count'];
  412. $forum_page['post_ident'] = array();
  413. $forum_page['message'] = array();
  414. $forum_page['user_ident'] = array();
  415. $cur_post['username'] = $cur_post['poster'];
  416. // Generate the post heading
  417. $forum_page['post_ident']['num'] = '<span class="post-num">'.forum_number_format($forum_page['start_from'] + $forum_page['item_count']).'</span>';
  418. if ($cur_post['poster_id'] > 1)
  419. $forum_page['post_ident']['byline'] = '<span class="post-byline">'.sprintf((($cur_post['id'] == $cur_topic['first_post_id']) ? $lang_topic['Topic byline'] : $lang_topic['Reply byline']), (($forum_user['g_view_users'] == '1') ? '<a title="'.sprintf($lang_topic['Go to profile'], forum_htmlencode($cur_post['username'])).'" href="'.forum_link($forum_url['user'], $cur_post['poster_id']).'">'.forum_htmlencode($cur_post['username']).'</a>' : '<strong>'.forum_htmlencode($cur_post['username']).'</strong>')).'</span>';
  420. else
  421. $forum_page['post_ident']['byline'] = '<span class="post-byline">'.sprintf((($cur_post['id'] == $cur_topic['first_post_id']) ? $lang_topic['Topic byline'] : $lang_topic['Reply byline']), '<strong>'.forum_htmlencode($cur_post['username']).'</strong>').'</span>';
  422. $forum_page['post_ident']['link'] = '<span class="post-link"><a class="permalink" rel="bookmark" title="'.$lang_topic['Permalink post'].'" href="'.forum_link($forum_url['post'], $cur_post['id']).'">'.format_time($cur_post['posted']).'</a></span>';
  423. if ($cur_post['edited'] != '')
  424. $forum_page['post_ident']['edited'] = '<span class="post-edit">'.sprintf($lang_topic['Last edited'], forum_htmlencode($cur_post['edited_by']), format_time($cur_post['edited'])).'</span>';
  425. ($hook = get_hook('mr_row_pre_item_ident_merge')) ? eval($hook) : null;
  426. // Generate the checkbox field
  427. if ($cur_post['id'] != $cur_topic['first_post_id'])
  428. $forum_page['item_select'] = '<p class="item-select"><input type="checkbox" id="fld'.$cur_post['id'].'" name="posts[]" value="'.$cur_post['id'].'" /> <label for="fld'.$cur_post['id'].'">'.$lang_misc['Select post'].' '.forum_number_format($forum_page['start_from'] + $forum_page['item_count']).'</label></p>';
  429. // Generate author identification
  430. $forum_page['author_ident']['username'] = '<li class="username">'.(($cur_post['poster_id'] > '1') ? '<a title="'.sprintf($lang_topic['Go to profile'], forum_htmlencode($cur_post['username'])).'" href="'.forum_link($forum_url['user'], $cur_post['poster_id']).'">'.forum_htmlencode($cur_post['username']).'</a>' : '<strong>'.forum_htmlencode($cur_post['username']).'</strong>').'</li>';
  431. $forum_page['author_ident']['usertitle'] = '<li class="usertitle"><span>'.get_title($cur_post).'</span></li>';
  432. // Give the post some class
  433. $forum_page['item_status'] = array(
  434. 'post',
  435. ($forum_page['item_count'] % 2 != 0) ? 'odd' : 'even'
  436. );
  437. if ($forum_page['item_count'] == 1)
  438. $forum_page['item_status']['firstpost'] = 'firstpost';
  439. if (($forum_page['start_from'] + $forum_page['item_count']) == $forum_page['finish_at'])
  440. $forum_page['item_status']['lastpost'] = 'lastpost';
  441. if ($cur_post['id'] == $cur_topic['first_post_id'])
  442. $forum_page['item_status']['topicpost'] = 'topicpost';
  443. else
  444. $forum_page['item_status']['replypost'] = 'replypost';
  445. // Generate the post title
  446. if ($cur_post['id'] == $cur_topic['first_post_id'])
  447. $forum_page['item_subject'] = sprintf($lang_topic['Topic title'], $cur_topic['subject']);
  448. else
  449. $forum_page['item_subject'] = sprintf($lang_topic['Reply title'], $cur_topic['subject']);
  450. $forum_page['item_subject'] = forum_htmlencode($forum_page['item_subject']);
  451. // Perform the main parsing of the message (BBCode, smilies, censor words etc)
  452. $forum_page['message']['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
  453. ($hook = get_hook('mr_post_actions_row_pre_display')) ? eval($hook) : null;
  454. ?>
  455. <div class="<?php echo implode(' ', $forum_page['item_status']) ?>">
  456. <div id="p<?php echo $cur_post['id'] ?>" class="posthead">
  457. <h3 class="hn post-ident"><?php echo implode(' ', $forum_page['post_ident']) ?></h3>
  458. <?php ($hook = get_hook('mr_post_actions_pre_item_select')) ? eval($hook) : null; ?>
  459. <?php if (isset($forum_page['item_select'])) echo "\t\t\t\t".$forum_page['item_select']."\n" ?>
  460. <?php ($hook = get_hook('mr_post_actions_new_post_head_option')) ? eval($hook) : null; ?>
  461. </div>
  462. <div class="postbody">
  463. <div class="post-author">
  464. <ul class="author-ident">
  465. <?php echo implode("\n\t\t\t\t\t\t", $forum_page['author_ident'])."\n" ?>
  466. </ul>
  467. <?php ($hook = get_hook('mr_post_actions_new_user_ident_data')) ? eval($hook) : null; ?>
  468. </div>
  469. <div class="post-entry">
  470. <h4 class="entry-title"><?php echo $forum_page['item_subject'] ?></h4>
  471. <div class="entry-content">
  472. <?php echo implode("\n\t\t\t\t\t\t\t", $forum_page['message'])."\n" ?>
  473. </div>
  474. <?php ($hook = get_hook('mr_post_actions_new_post_entry_data')) ? eval($hook) : null; ?>
  475. </div>
  476. </div>
  477. </div>
  478. <?php
  479. }
  480. ?>
  481. </div>
  482. <?php
  483. $forum_page['mod_options'] = array(
  484. 'del_posts' => '<span class="submit first-item"><input type="submit" name="delete_posts" value="'.$lang_misc['Delete posts'].'" /></span>',
  485. 'split_posts' => '<span class="submit"><input type="submit" name="split_posts" value="'.$lang_misc['Split posts'].'" /></span>',
  486. 'del_topic' => '<span><a href="'.forum_link($forum_url['delete'], $cur_topic['first_post_id']).'">'.$lang_misc['Delete whole topic'].'</a></span>'
  487. );
  488. ($hook = get_hook('mr_post_actions_pre_mod_options')) ? eval($hook) : null;
  489. ?>
  490. <div class="main-options mod-options gen-content">
  491. <p class="options"><?php echo implode(' ', $forum_page['mod_options']) ?></p>
  492. </div>
  493. </form>
  494. <div class="main-foot">
  495. <?php
  496. if (!empty($forum_page['main_foot_options']))
  497. echo "\n\t\t".'<p class="options">'.implode(' ', $forum_page['main_foot_options']).'</p>';
  498. ?>
  499. <h2 class="hn"><span><?php echo $forum_page['items_info'] ?></span></h2>
  500. </div>
  501. <?php
  502. $forum_id = $fid;
  503. // Init JS helper for select-all
  504. $forum_loader->add_js('PUNBB.common.addDOMReadyEvent(PUNBB.common.initToggleCheckboxes);', array('type' => 'inline'));
  505. ($hook = get_hook('mr_post_actions_end')) ? eval($hook) : null;
  506. $tpl_temp = forum_trim(ob_get_contents());
  507. $tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
  508. ob_end_clean();
  509. // END SUBST - <!-- forum_main -->
  510. require FORUM_ROOT.'footer.php';
  511. }
  512. // Move one or more topics
  513. if (isset($_REQUEST['move_topics']) || isset($_POST['move_topics_to']))
  514. {
  515. if (isset($_POST['move_topics_to']))
  516. {
  517. ($hook = get_hook('mr_confirm_move_topics_form_submitted')) ? eval($hook) : null;
  518. $topics = isset($_POST['topics']) && !empty($_POST['topics']) ? explode(',', $_POST['topics']) : array();
  519. $topics = array_map('intval', $topics);
  520. $move_to_forum = isset($_POST['move_to_forum']) ? intval($_POST['move_to_forum']) : 0;
  521. if (empty($topics) || $move_to_forum < 1)
  522. message($lang_common['Bad request']);
  523. // Fetch the forum name for the forum we're moving to
  524. $query = array(
  525. 'SELECT' => 'f.forum_name',
  526. 'FROM' => 'forums AS f',
  527. 'WHERE' => 'f.id='.$move_to_forum
  528. );
  529. ($hook = get_hook('mr_confirm_move_topics_qr_get_move_to_forum_name')) ? eval($hook) : null;
  530. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  531. $move_to_forum_name = $forum_db->result($result);
  532. if (!$move_to_forum_name)
  533. message($lang_common['Bad request']);
  534. // Verify that the topic IDs are valid
  535. $query = array(
  536. 'SELECT' => 'COUNT(t.id)',
  537. 'FROM' => 'topics AS t',
  538. 'WHERE' => 't.id IN('.implode(',', $topics).') AND t.forum_id='.$fid
  539. );
  540. ($hook = get_hook('mr_confirm_move_topics_qr_verify_topic_ids')) ? eval($hook) : null;
  541. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  542. if ($forum_db->result($result) != count($topics))
  543. message($lang_common['Bad request']);
  544. // Delete any redirect topics if there are any (only if we moved/copied the topic back to where it where it was once moved from)
  545. $query = array(
  546. 'DELETE' => 'topics',
  547. 'WHERE' => 'forum_id='.$move_to_forum.' AND moved_to IN('.implode(',', $topics).')'
  548. );
  549. ($hook = get_hook('mr_confirm_move_topics_qr_delete_redirect_topics')) ? eval($hook) : null;
  550. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  551. // Move the topic(s)
  552. $query = array(
  553. 'UPDATE' => 'topics',
  554. 'SET' => 'forum_id='.$move_to_forum,
  555. 'WHERE' => 'id IN('.implode(',', $topics).')'
  556. );
  557. ($hook = get_hook('mr_confirm_move_topics_qr_move_topics')) ? eval($hook) : null;
  558. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  559. // Should we create redirect topics?
  560. if (isset($_POST['with_redirect']))
  561. {
  562. foreach ($topics as $cur_topic)
  563. {
  564. // Fetch info for the redirect topic
  565. $query = array(
  566. 'SELECT' => 't.poster, t.subject, t.posted, t.last_post',
  567. 'FROM' => 'topics AS t',
  568. 'WHERE' => 't.id='.$cur_topic
  569. );
  570. ($hook = get_hook('mr_confirm_move_topics_qr_get_redirect_topic_data')) ? eval($hook) : null;
  571. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  572. $moved_to = $forum_db->fetch_assoc($result);
  573. // Create the redirect topic
  574. $query = array(
  575. 'INSERT' => 'poster, subject, posted, last_post, moved_to, forum_id',
  576. 'INTO' => 'topics',
  577. 'VALUES' => '\''.$forum_db->escape($moved_to['poster']).'\', \''.$forum_db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid
  578. );
  579. ($hook = get_hook('mr_confirm_move_topics_qr_add_redirect_topic')) ? eval($hook) : null;
  580. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  581. }
  582. }
  583. sync_forum($fid); // Synchronize the forum FROM which the topic was moved
  584. sync_forum($move_to_forum); // Synchronize the forum TO which the topic was moved
  585. $forum_page['redirect_msg'] = (count($topics) > 1) ? $lang_misc['Move topics redirect'] : $lang_misc['Move topic redirect'];
  586. $forum_flash->add_info($forum_page['redirect_msg']);
  587. ($hook = get_hook('mr_confirm_move_topics_pre_redirect')) ? eval($hook) : null;
  588. redirect(forum_link($forum_url['forum'], array($move_to_forum, sef_friendly($move_to_forum_name))), $forum_page['redirect_msg']);
  589. }
  590. if (isset($_POST['move_topics']))
  591. {
  592. $topics = isset($_POST['topics']) && is_array($_POST['topics']) ? $_POST['topics'] : array();
  593. $topics = array_map('intval', $topics);
  594. if (empty($topics))
  595. message($lang_misc['No topics selected']);
  596. if (count($topics) == 1)
  597. {
  598. $topics = $topics[0];
  599. $action = 'single';
  600. }
  601. else
  602. $action = 'multiple';
  603. }
  604. else
  605. {
  606. $topics = intval($_GET['move_topics']);
  607. if ($topics < 1)
  608. message($lang_common['Bad request']);
  609. $action = 'single';
  610. }
  611. if ($action == 'single')
  612. {
  613. // Fetch the topic subject
  614. $query = array(
  615. 'SELECT' => 't.subject',
  616. 'FROM' => 'topics AS t',
  617. 'WHERE' => 't.id='.$topics
  618. );
  619. ($hook = get_hook('mr_move_topics_qr_get_topic_to_move_subject')) ? eval($hook) : null;
  620. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  621. $subject = $forum_db->result($result);
  622. if (!$subject)
  623. {
  624. message($lang_common['Bad request']);
  625. }
  626. }
  627. // Get forums we can move the post into
  628. $query = array(
  629. 'SELECT' => 'c.id AS cid, c.cat_name, f.id AS fid, f.forum_name',
  630. 'FROM' => 'categories AS c',
  631. 'JOINS' => array(
  632. array(
  633. 'INNER JOIN' => 'forums AS f',
  634. 'ON' => 'c.id=f.cat_id'
  635. ),
  636. array(
  637. 'LEFT JOIN' => 'forum_perms AS fp',
  638. 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$forum_user['g_id'].')'
  639. )
  640. ),
  641. 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL AND f.id!='.$fid,
  642. 'ORDER BY' => 'c.disp_position, c.id, f.disp_position'
  643. );
  644. ($hook = get_hook('mr_move_topics_qr_get_target_forums')) ? eval($hook) : null;
  645. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  646. $forum_list = array();
  647. while ($cur_sel_forum = $forum_db->fetch_assoc($result))
  648. {
  649. $forum_list[] = $cur_sel_forum;
  650. }
  651. if (empty($forum_list))
  652. {
  653. message($lang_misc['Nowhere to move']);
  654. }
  655. // Setup form
  656. $forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] = 0;
  657. $forum_page['form_action'] = forum_link($forum_url['moderate_forum'], $fid);
  658. $forum_page['hidden_fields'] = array(
  659. 'csrf_token' => '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />',
  660. 'topics' => '<input type="hidden" name="topics" value="'.($action == 'single' ? $topics : implode(',', $topics)).'" />'
  661. );
  662. // Setup breadcrumbs
  663. $forum_page['crumbs'][] = array($forum_config['o_board_title'], forum_link($forum_url['index']));
  664. $forum_page['crumbs'][] = array($cur_forum['forum_name'], forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name']))));
  665. if ($action == 'single')
  666. $forum_page['crumbs'][] = array($subject, forum_link($forum_url['topic'], array($topics, sef_friendly($subject))));
  667. else
  668. $forum_page['crumbs'][] = array($lang_misc['Moderate forum'], forum_link($forum_url['moderate_forum'], $fid));
  669. $forum_page['crumbs'][] = ($action == 'single') ? $lang_misc['Move topic'] : $lang_misc['Move topics'];
  670. //Setup main heading
  671. $forum_page['main_title'] = end($forum_page['crumbs']).' '.$lang_misc['To new forum'];
  672. ($hook = get_hook('mr_move_topics_pre_header_load')) ? eval($hook) : null;
  673. define('FORUM_PAGE', 'dialogue');
  674. require FORUM_ROOT.'header.php';
  675. // START SUBST - <!-- forum_main -->
  676. ob_start();
  677. ($hook = get_hook('mr_move_topics_output_start')) ? eval($hook) : null;
  678. ?>
  679. <div class="main-head">
  680. <h2 class="hn"><span><?php echo end($forum_page['crumbs']).' '.$lang_misc['To new forum'] ?></span></h2>
  681. </div>
  682. <div class="main-content main-frm">
  683. <form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
  684. <div class="hidden">
  685. <?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
  686. </div>
  687. <?php ($hook = get_hook('mr_move_topics_pre_fieldset')) ? eval($hook) : null; ?>
  688. <fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
  689. <legend class="group-legend"><strong><?php echo $lang_misc['Move topic'] ?></strong></legend>
  690. <?php ($hook = get_hook('mr_move_topics_pre_move_to_forum')) ? eval($hook) : null; ?>
  691. <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
  692. <div class="sf-box select">
  693. <label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_misc['Move to'] ?></span></label><br />
  694. <span class="fld-input"><select id="fld<?php echo $forum_page['fld_count'] ?>" name="move_to_forum">
  695. <?php
  696. $forum_page['cur_category'] = 0;
  697. foreach ($forum_list as $cur_forum)
  698. {
  699. ($hook = get_hook('mr_move_topics_forum_loop_start')) ? eval($hook) : null;
  700. if ($cur_forum['cid'] != $forum_page['cur_category']) // A new category since last iteration?
  701. {
  702. if ($forum_page['cur_category'])
  703. echo "\t\t\t\t".'</optgroup>'."\n";
  704. echo "\t\t\t\t".'<optgroup label="'.forum_htmlencode($cur_forum['cat_name']).'">'."\n";
  705. $forum_page['cur_category'] = $cur_forum['cid'];
  706. }
  707. if ($cur_forum['fid'] != $fid)
  708. echo "\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.forum_htmlencode($cur_forum['forum_name']).'</option>'."\n";
  709. ($hook = get_hook('mr_move_topics_forum_loop_end')) ? eval($hook) : null;
  710. }
  711. ?>
  712. </optgroup>
  713. </select></span>
  714. </div>
  715. </div>
  716. <?php ($hook = get_hook('mr_move_topics_pre_redirect_checkbox')) ? eval($hook) : null; ?>
  717. <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
  718. <div class="sf-box checkbox">
  719. <span class="fld-input"><input type="checkbox" id="fld<?php echo (++$forum_page['fld_count']) ?>" name="with_redirect" value="1"<?php if ($action == 'single') echo ' checked="checked"' ?> /></span>
  720. <label for="fld<?php echo $forum_page['fld_count'] ?>"><?php echo ($action == 'single') ? $lang_misc['Leave redirect'] : $lang_misc['Leave redirects'] ?></label>
  721. </div>
  722. </div>
  723. <?php ($hook = get_hook('mr_move_topics_pre_fieldset_end')) ? eval($hook) : null; ?>
  724. </fieldset>
  725. <?php ($hook = get_hook('mr_move_topics_fieldset_end')) ? eval($hook) : null; ?>
  726. <div class="frm-buttons">
  727. <span class="submit primary"><input type="submit" name="move_topics_to" value="<?php echo $lang_misc['Move'] ?>" /></span>
  728. <span class="cancel"><input type="submit" name="cancel" value="<?php echo $lang_common['Cancel'] ?>" formnovalidate /></span>
  729. </div>
  730. </form>
  731. </div>
  732. <?php
  733. $forum_id = $fid;
  734. ($hook = get_hook('mr_move_topics_end')) ? eval($hook) : null;
  735. $tpl_temp = forum_trim(ob_get_contents());
  736. $tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
  737. ob_end_clean();
  738. // END SUBST - <!-- forum_main -->
  739. require FORUM_ROOT.'footer.php';
  740. }
  741. // Merge topics
  742. else if (isset($_POST['merge_topics']) || isset($_POST['merge_topics_comply']))
  743. {
  744. $topics = isset($_POST['topics']) && !empty($_POST['topics']) ? $_POST['topics'] : array();
  745. $topics = array_map('intval', (is_array($topics) ? $topics : explode(',', $topics)));
  746. if (empty($topics))
  747. message($lang_misc['No topics selected']);
  748. if (count($topics) == 1)
  749. message($lang_misc['Merge error']);
  750. if (isset($_POST['merge_topics_comply']))
  751. {
  752. ($hook = get_hook('mr_confirm_merge_topics_form_submitted')) ? eval($hook) : null;
  753. // Verify that the topic IDs are valid
  754. $query = array(
  755. 'SELECT' => 'COUNT(t.id), MIN(t.id)',
  756. 'FROM' => 'topics AS t',
  757. 'WHERE' => 't.id IN('.implode(',', $topics).') AND t.moved_to IS NULL AND t.forum_id='.$fid
  758. );
  759. ($hook = get_hook('mr_confirm_merge_topics_qr_verify_topic_ids')) ? eval($hook) : null;
  760. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  761. list($num_topics, $merge_to_tid) = $forum_db->fetch_row($result);
  762. if ($num_topics != count($topics))
  763. message($lang_common['Bad request']);
  764. // Make any redirect topics point to our new, merged topic
  765. $query = array(
  766. 'UPDATE' => 'topics',
  767. 'SET' => 'moved_to='.$merge_to_tid,
  768. 'WHERE' => 'moved_to IN('.implode(',', $topics).')'
  769. );
  770. // Should we create redirect topics?
  771. if (isset($_POST['with_redirect']))
  772. $query['WHERE'] .= ' OR (id IN('.implode(',', $topics).') AND id != '.$merge_to_tid.')';
  773. ($hook = get_hook('mr_confirm_merge_topics_qr_fix_redirect_topics')) ? eval($hook) : null;
  774. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  775. // Merge the posts into the topic
  776. $query = array(
  777. 'UPDATE' => 'posts',
  778. 'SET' => 'topic_id='.$merge_to_tid,
  779. 'WHERE' => 'topic_id IN('.implode(',', $topics).')'
  780. );
  781. ($hook = get_hook('mr_confirm_merge_topics_qr_merge_posts')) ? eval($hook) : null;
  782. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  783. // Delete any subscriptions
  784. $query = array(
  785. 'DELETE' => 'subscriptions',
  786. 'WHERE' => 'topic_id IN('.implode(',', $topics).') AND topic_id != '.$merge_to_tid
  787. );
  788. ($hook = get_hook('mr_confirm_merge_topics_qr_delete_subscriptions')) ? eval($hook) : null;
  789. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  790. if (!isset($_POST['with_redirect']))
  791. {
  792. // Delete the topics that have been merged
  793. $query = array(
  794. 'DELETE' => 'topics',
  795. 'WHERE' => 'id IN('.implode(',', $topics).') AND id != '.$merge_to_tid
  796. );
  797. ($hook = get_hook('mr_confirm_merge_topics_qr_delete_merged_topics')) ? eval($hook) : null;
  798. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  799. }
  800. // Synchronize the topic we merged to and the forum where the topics were merged
  801. sync_topic($merge_to_tid);
  802. sync_forum($fid);
  803. $forum_flash->add_info($lang_misc['Merge topics redirect']);
  804. ($hook = get_hook('mr_confirm_merge_topics_pre_redirect')) ? eval($hook) : null;
  805. redirect(forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name']))), $lang_misc['Merge topics redirect']);
  806. }
  807. // Setup form
  808. $forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] = 0;
  809. $forum_page['form_action'] = forum_link($forum_url['moderate_forum'], $fid);
  810. $forum_page['hidden_fields'] = array(
  811. 'csrf_token' => '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />',
  812. 'topics' => '<input type="hidden" name="topics" value="'.implode(',', $topics).'" />'
  813. );
  814. // Setup breadcrumbs
  815. $forum_page['crumbs'] = array(
  816. array($forum_config['o_board_title'], forum_link($forum_url['index'])),
  817. array($cur_forum['forum_name'], forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name'])))),
  818. array($lang_misc['Moderate forum'], forum_link($forum_url['moderate_forum'], $fid)),
  819. $lang_misc['Merge topics']
  820. );
  821. ($hook = get_hook('mr_merge_topics_pre_header_load')) ? eval($hook) : null;
  822. define('FORUM_PAGE', 'dialogue');
  823. require FORUM_ROOT.'header.php';
  824. // START SUBST - <!-- forum_main -->
  825. ob_start();
  826. ($hook = get_hook('mr_merge_topics_output_start')) ? eval($hook) : null;
  827. ?>
  828. <div class="main-head">
  829. <h2 class="hn"><span><?php echo $lang_misc['Confirm topic merge'] ?></span></h2>
  830. </div>
  831. <div class="main-content main-frm">
  832. <form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
  833. <div class="hidden">
  834. <?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
  835. </div>
  836. <?php ($hook = get_hook('mr_merge_topics_pre_fieldset')) ? eval($hook) : null; ?>
  837. <fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
  838. <legend class="group-legend"><strong><?php echo $lang_misc['Merge topics'] ?></strong></legend>
  839. <?php ($hook = get_hook('mr_merge_topics_pre_redirect_checkbox')) ? eval($hook) : null; ?>
  840. <div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
  841. <div class="sf-box checkbox">
  842. <span class="fld-input"><input type="checkbox" id="fld<?php echo (++$forum_page['fld_count']) ?>" name="with_redirect" value="1" /></span>
  843. <label for="fld<?php echo $forum_page['fld_count'] ?>"><span><?php echo $lang_misc['Redirect topic'] ?></span> <?php echo $lang_misc['Leave merge redirects'] ?></label>
  844. </div>
  845. </div>
  846. <?php ($hook = get_hook('mr_merge_topics_pre_fieldset_end')) ? eval($hook) : null; ?>
  847. </fieldset>
  848. <?php ($hook = get_hook('mr_merge_topics_fieldset_end')) ? eval($hook) : null; ?>
  849. <div class="frm-buttons">
  850. <span class="submit primary"><input type="submit" name="merge_topics_comply" value="<?php echo $lang_misc['Merge'] ?>" /></span>
  851. <span class="cancel"><input type="submit" name="cancel" value="<?php echo $lang_common['Cancel'] ?>" formnovalidate /></span>
  852. </div>
  853. </form>
  854. </div>
  855. <?php
  856. $forum_id = $fid;
  857. ($hook = get_hook('mr_merge_topics_end')) ? eval($hook) : null;
  858. $tpl_temp = forum_trim(ob_get_contents());
  859. $tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
  860. ob_end_clean();
  861. // END SUBST - <!-- forum_main -->
  862. require FORUM_ROOT.'footer.php';
  863. }
  864. // Delete one or more topics
  865. else if (isset($_REQUEST['delete_topics']) || isset($_POST['delete_topics_comply']))
  866. {
  867. $topics = isset($_POST['topics']) && !empty($_POST['topics']) ? $_POST['topics'] : array();
  868. $topics = array_map('intval', (is_array($topics) ? $topics : explode(',', $topics)));
  869. if (empty($topics))
  870. message($lang_misc['No topics selected']);
  871. $multi = count($topics) > 1;
  872. if (isset($_POST['delete_topics_comply']))
  873. {
  874. if (!isset($_POST['req_confirm']))
  875. redirect(forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name']))), $lang_common['Cancel redirect']);
  876. ($hook = get_hook('mr_confirm_delete_topics_form_submitted')) ? eval($hook) : null;
  877. // Verify that the topic IDs are valid
  878. $query = array(
  879. 'SELECT' => 'COUNT(t.id)',
  880. 'FROM' => 'topics AS t',
  881. 'WHERE' => 't.id IN('.implode(',', $topics).') AND t.forum_id='.$fid
  882. );
  883. ($hook = get_hook('mr_confirm_delete_topics_qr_verify_topic_ids')) ? eval($hook) : null;
  884. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  885. if ($forum_db->result($result) != count($topics))
  886. message($lang_common['Bad request']);
  887. // Create an array of forum IDs that need to be synced
  888. $forum_ids = array($fid);
  889. $query = array(
  890. 'SELECT' => 't.forum_id',
  891. 'FROM' => 'topics AS t',
  892. 'WHERE' => 't.moved_to IN('.implode(',', $topics).')'
  893. );
  894. ($hook = get_hook('mr_confirm_delete_topics_qr_get_forums_to_sync')) ? eval($hook) : null;
  895. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  896. while ($row = $forum_db->fetch_row($result))
  897. $forum_ids[] = $row[0];
  898. // Delete the topics and any redirect topics
  899. $query = array(
  900. 'DELETE' => 'topics',
  901. 'WHERE' => 'id IN('.implode(',', $topics).') OR moved_to IN('.implode(',', $topics).')'
  902. );
  903. ($hook = get_hook('mr_confirm_delete_topics_qr_delete_topics')) ? eval($hook) : null;
  904. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  905. // Delete any subscriptions
  906. $query = array(
  907. 'DELETE' => 'subscriptions',
  908. 'WHERE' => 'topic_id IN('.implode(',', $topics).')'
  909. );
  910. ($hook = get_hook('mr_confirm_delete_topics_qr_delete_subscriptions')) ? eval($hook) : null;
  911. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  912. // Create a list of the post ID's in the deleted topic and strip the search index
  913. $query = array(
  914. 'SELECT' => 'p.id',
  915. 'FROM' => 'posts AS p',
  916. 'WHERE' => 'p.topic_id IN('.implode(',', $topics).')'
  917. );
  918. ($hook = get_hook('mr_confirm_delete_topics_qr_get_deleted_posts')) ? eval($hook) : null;
  919. $result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
  920. $post_ids = array();
  921. while ($row = $forum_db->fetch_row($result))
  922. $post_ids[] = $row[0];
  923. // Strip the search index provided we're not just deleting redirect topics
  924. if (!empty($post_ids))
  925. {
  926. if (!defined('FORUM_SEARCH_IDX_FUNCTIONS_LOADED'))
  927. require FORUM_ROOT.'include/search_idx.php';
  928. strip_search_index($post_ids);
  929. }
  930. // Delete posts
  931. $query = array(
  932. 'DELETE' => 'posts',
  933. 'WHERE' => 'topic_id IN('.implode(',', $topics).')'
  934. );
  935. ($hook = get_hook('mr_confirm_delete_topics_qr_delete_topic_posts')) ? eval($hook) : null;
  936. $forum_db->query_build($query) or error(__FILE__, __LINE__);
  937. foreach ($forum_ids as $cur_forum_id)
  938. sync_forum($cur_forum_id);
  939. $forum_flash->add_info($multi ? $lang_misc['Delete topics redirect'] : $lang_misc['Delete topic redirect']);
  940. ($hook = get_hook('mr_confirm_delete_topics_pre_redirect')) ? eval($hook) : null;
  941. redirect(forum_link($forum_url['forum'], array($fid, sef_friendly($cur_forum['forum_name']))), $multi ? $lang_misc['Delete topics redirect'] : $lang_misc['Delete topic redirect']);
  942. }
  943. // Setup form
  944. $forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] =0;
  945. $forum_page['form_action'] = forum_link($forum_url['moderate_forum'], $fid);
  946. $forum_page['hidden_fields'] = array(
  947. 'csrf_token' =>

Large files files are truncated, but you can click here to view the full file