Completed
Push — release-2.1 ( 6f6d35...abeae7 )
by Mathias
08:46
created

Sources/MoveTopic.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * This file contains the functions required to move topics from one board to
5
 * another board.
6
 *
7
 * Simple Machines Forum (SMF)
8
 *
9
 * @package SMF
10
 * @author Simple Machines http://www.simplemachines.org
11
 * @copyright 2017 Simple Machines and individual contributors
12
 * @license http://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1 Beta 4
15
 */
16
17
if (!defined('SMF'))
18
	die('No direct access...');
19
20
/**
21
 * This function allows to move a topic, making sure to ask the moderator
22
 * to give reason for topic move.
23
 * It must be called with a topic specified. (that is, global $topic must
24
 * be set... @todo fix this thing.)
25
 * If the member is the topic starter requires the move_own permission,
26
 * otherwise the move_any permission.
27
 * Accessed via ?action=movetopic.
28
 *
29
 * @uses the MoveTopic template, main sub-template.
30
 */
31
function MoveTopic()
32
{
33
	global $txt, $board, $topic, $user_info, $context, $language, $scripturl, $smcFunc, $modSettings, $sourcedir;
34
35
	if (empty($topic))
36
		fatal_lang_error('no_access', false);
37
38
	$request = $smcFunc['db_query']('', '
39
		SELECT t.id_member_started, ms.subject, t.approved
40
		FROM {db_prefix}topics AS t
41
			INNER JOIN {db_prefix}messages AS ms ON (ms.id_msg = t.id_first_msg)
42
		WHERE t.id_topic = {int:current_topic}
43
		LIMIT 1',
44
		array(
45
			'current_topic' => $topic,
46
		)
47
	);
48
	list ($id_member_started, $context['subject'], $context['is_approved']) = $smcFunc['db_fetch_row']($request);
49
	$smcFunc['db_free_result']($request);
50
51
	// Can they see it - if not approved?
52
	if ($modSettings['postmod_active'] && !$context['is_approved'])
53
		isAllowedTo('approve_posts');
54
55
	// Permission check!
56
	// @todo
57 View Code Duplication
	if (!allowedTo('move_any'))
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
58
	{
59
		if ($id_member_started == $user_info['id'])
60
		{
61
			isAllowedTo('move_own');
62
		}
63
		else
64
			isAllowedTo('move_any');
65
	}
66
67
	$context['move_any'] = $user_info['is_admin'] || $modSettings['topic_move_any'];
68
	$boards = array();
69
70 View Code Duplication
	if (!$context['move_any'])
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
	{
72
		$boards = array_diff(boardsAllowedTo('post_new'), array($board));
73
		if (empty($boards))
74
		{
75
			// No boards? Too bad...
76
			fatal_lang_error('moveto_no_boards');
77
		}
78
	}
79
80
	loadTemplate('MoveTopic');
81
82
	$options = array(
83
		'not_redirection' => true,
84
	);
85
86
	if (!empty($_SESSION['move_to_topic']) && $_SESSION['move_to_topic'] != $board)
87
		$options['selected_board'] = $_SESSION['move_to_topic'];
88
89
	if (!$context['move_any'])
90
		$options['included_boards'] = $boards;
91
92
	require_once($sourcedir . '/Subs-MessageIndex.php');
93
	$context['categories'] = getBoardList($options);
94
95
	$context['page_title'] = $txt['move_topic'];
96
97
	$context['linktree'][] = array(
98
		'url' => $scripturl . '?topic=' . $topic . '.0',
99
		'name' => $context['subject'],
100
	);
101
102
	$context['linktree'][] = array(
103
		'name' => $txt['move_topic'],
104
	);
105
106
	$context['back_to_topic'] = isset($_REQUEST['goback']);
107
108
	if ($user_info['language'] != $language)
109
	{
110
		loadLanguage('index', $language);
111
		$temp = $txt['movetopic_default'];
112
		loadLanguage('index');
113
114
		$txt['movetopic_default'] = $temp;
115
	}
116
117
	$context['sub_template'] = 'move';
118
119
	moveTopicConcurrence();
120
121
	// Register this form and get a sequence number in $context.
122
	checkSubmitOnce('register');
123
}
124
125
/**
126
 * Execute the move of a topic.
127
 * It is called on the submit of MoveTopic.
128
 * This function logs that topics have been moved in the moderation log.
129
 * If the member is the topic starter requires the move_own permission,
130
 * otherwise requires the move_any permission.
131
 * Upon successful completion redirects to message index.
132
 * Accessed via ?action=movetopic2.
133
 *
134
 * @uses Subs-Post.php.
135
 */
136
function MoveTopic2()
137
{
138
	global $txt, $topic, $scripturl, $sourcedir, $context;
139
	global $board, $language, $user_info, $smcFunc;
140
141
	if (empty($topic))
142
		fatal_lang_error('no_access', false);
143
144
	// You can't choose to have a redirection topic and use an empty reason.
145
	if (isset($_POST['postRedirect']) && (!isset($_POST['reason']) || trim($_POST['reason']) == ''))
146
		fatal_lang_error('movetopic_no_reason', false);
147
148
	moveTopicConcurrence();
149
150
	// Make sure this form hasn't been submitted before.
151
	checkSubmitOnce('check');
152
153
	$request = $smcFunc['db_query']('', '
154
		SELECT id_member_started, id_first_msg, approved
155
		FROM {db_prefix}topics
156
		WHERE id_topic = {int:current_topic}
157
		LIMIT 1',
158
		array(
159
			'current_topic' => $topic,
160
		)
161
	);
162
	list ($id_member_started, $id_first_msg, $context['is_approved']) = $smcFunc['db_fetch_row']($request);
163
	$smcFunc['db_free_result']($request);
164
165
	// Can they see it?
166
	if (!$context['is_approved'])
167
		isAllowedTo('approve_posts');
168
169
	// Can they move topics on this board?
170 View Code Duplication
	if (!allowedTo('move_any'))
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
	{
172
		if ($id_member_started == $user_info['id'])
173
			isAllowedTo('move_own');
174
		else
175
			isAllowedTo('move_any');
176
	}
177
178
	checkSession();
179
	require_once($sourcedir . '/Subs-Post.php');
180
181
	// The destination board must be numeric.
182
	$_POST['toboard'] = (int) $_POST['toboard'];
183
184
	// Make sure they can see the board they are trying to move to (and get whether posts count in the target board).
185
	$request = $smcFunc['db_query']('', '
186
		SELECT b.count_posts, b.name, m.subject
187
		FROM {db_prefix}boards AS b
188
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:current_topic})
189
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
190
		WHERE {query_see_board}
191
			AND b.id_board = {int:to_board}
192
			AND b.redirect = {string:blank_redirect}
193
		LIMIT 1',
194
		array(
195
			'current_topic' => $topic,
196
			'to_board' => $_POST['toboard'],
197
			'blank_redirect' => '',
198
		)
199
	);
200
	if ($smcFunc['db_num_rows']($request) == 0)
201
		fatal_lang_error('no_board');
202
	list ($pcounter, $board_name, $subject) = $smcFunc['db_fetch_row']($request);
203
	$smcFunc['db_free_result']($request);
204
205
	// Remember this for later.
206
	$_SESSION['move_to_topic'] = $_POST['toboard'];
207
208
	// Rename the topic...
209
	if (isset($_POST['reset_subject'], $_POST['custom_subject']) && $_POST['custom_subject'] != '')
210
	{
211
		$_POST['custom_subject'] = strtr($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['custom_subject'])), array("\r" => '', "\n" => '', "\t" => ''));
212
		// Keep checking the length.
213 View Code Duplication
		if ($smcFunc['strlen']($_POST['custom_subject']) > 100)
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
			$_POST['custom_subject'] = $smcFunc['substr']($_POST['custom_subject'], 0, 100);
215
216
		// If it's still valid move onwards and upwards.
217
		if ($_POST['custom_subject'] != '')
218
		{
219
			if (isset($_POST['enforce_subject']))
220
			{
221
				// Get a response prefix, but in the forum's default language.
222 View Code Duplication
				if (!isset($context['response_prefix']) && !($context['response_prefix'] = cache_get_data('response_prefix')))
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
223
				{
224
					if ($language === $user_info['language'])
225
						$context['response_prefix'] = $txt['response_prefix'];
226
					else
227
					{
228
						loadLanguage('index', $language, false);
229
						$context['response_prefix'] = $txt['response_prefix'];
230
						loadLanguage('index');
231
					}
232
					cache_put_data('response_prefix', $context['response_prefix'], 600);
233
				}
234
235
				$smcFunc['db_query']('', '
236
					UPDATE {db_prefix}messages
237
					SET subject = {string:subject}
238
					WHERE id_topic = {int:current_topic}',
239
					array(
240
						'current_topic' => $topic,
241
						'subject' => $context['response_prefix'] . $_POST['custom_subject'],
242
					)
243
				);
244
			}
245
246
			$smcFunc['db_query']('', '
247
				UPDATE {db_prefix}messages
248
				SET subject = {string:custom_subject}
249
				WHERE id_msg = {int:id_first_msg}',
250
				array(
251
					'id_first_msg' => $id_first_msg,
252
					'custom_subject' => $_POST['custom_subject'],
253
				)
254
			);
255
256
			// Fix the subject cache.
257
			updateStats('subject', $topic, $_POST['custom_subject']);
258
		}
259
	}
260
261
	// Create a link to this in the old board.
262
	// @todo Does this make sense if the topic was unapproved before? I'd just about say so.
263
	if (isset($_POST['postRedirect']))
264
	{
265
		// Should be in the boardwide language.
266
		if ($user_info['language'] != $language)
267
			loadLanguage('index', $language);
268
269
		$_POST['reason'] = $smcFunc['htmlspecialchars']($_POST['reason'], ENT_QUOTES);
270
		preparsecode($_POST['reason']);
271
272
		// Add a URL onto the message.
273
		$_POST['reason'] = strtr($_POST['reason'], array(
274
			$txt['movetopic_auto_board'] => '[url=' . $scripturl . '?board=' . $_POST['toboard'] . '.0]' . $board_name . '[/url]',
275
			$txt['movetopic_auto_topic'] => '[iurl]' . $scripturl . '?topic=' . $topic . '.0[/iurl]'
276
		));
277
278
		// auto remove this MOVED redirection topic in the future?
279
		$redirect_expires = !empty($_POST['redirect_expires']) ? ((int) ($_POST['redirect_expires'] * 60) + time()) : 0;
280
281
		// redirect to the MOVED topic from topic list?
282
		$redirect_topic = isset($_POST['redirect_topic']) ? $topic : 0;
283
284
		$msgOptions = array(
285
			'subject' => $txt['moved'] . ': ' . $subject,
286
			'body' => $_POST['reason'],
287
			'icon' => 'moved',
288
			'smileys_enabled' => 1,
289
		);
290
		$topicOptions = array(
291
			'board' => $board,
292
			'lock_mode' => 1,
293
			'mark_as_read' => true,
294
			'redirect_expires' => $redirect_expires,
295
			'redirect_topic' => $redirect_topic,
296
		);
297
		$posterOptions = array(
298
			'id' => $user_info['id'],
299
			'update_post_count' => empty($pcounter),
300
		);
301
		createPost($msgOptions, $topicOptions, $posterOptions);
302
	}
303
304
	$request = $smcFunc['db_query']('', '
305
		SELECT count_posts
306
		FROM {db_prefix}boards
307
		WHERE id_board = {int:current_board}
308
		LIMIT 1',
309
		array(
310
			'current_board' => $board,
311
		)
312
	);
313
	list ($pcounter_from) = $smcFunc['db_fetch_row']($request);
314
	$smcFunc['db_free_result']($request);
315
316
	if ($pcounter_from != $pcounter)
317
	{
318
		$request = $smcFunc['db_query']('', '
319
			SELECT id_member
320
			FROM {db_prefix}messages
321
			WHERE id_topic = {int:current_topic}
322
				AND approved = {int:is_approved}',
323
			array(
324
				'current_topic' => $topic,
325
				'is_approved' => 1,
326
			)
327
		);
328
		$posters = array();
329
		while ($row = $smcFunc['db_fetch_assoc']($request))
330
		{
331
			if (!isset($posters[$row['id_member']]))
332
				$posters[$row['id_member']] = 0;
333
334
			$posters[$row['id_member']]++;
335
		}
336
		$smcFunc['db_free_result']($request);
337
338
		foreach ($posters as $id_member => $posts)
339
		{
340
			// The board we're moving from counted posts, but not to.
341
			if (empty($pcounter_from))
342
				updateMemberData($id_member, array('posts' => 'posts - ' . $posts));
343
			// The reverse: from didn't, to did.
344
			else
345
				updateMemberData($id_member, array('posts' => 'posts + ' . $posts));
346
		}
347
	}
348
349
	// Do the move (includes statistics update needed for the redirect topic).
350
	moveTopics($topic, $_POST['toboard']);
351
352
	// Log that they moved this topic.
353
	if (!allowedTo('move_own') || $id_member_started != $user_info['id'])
354
		logAction('move', array('topic' => $topic, 'board_from' => $board, 'board_to' => $_POST['toboard']));
355
	// Notify people that this topic has been moved?
356
	sendNotifications($topic, 'move');
357
358
	// Why not go back to the original board in case they want to keep moving?
359
	if (!isset($_REQUEST['goback']))
360
		redirectexit('board=' . $board . '.0');
361
	else
362
		redirectexit('topic=' . $topic . '.0');
363
}
364
365
/**
366
 * Moves one or more topics to a specific board. (doesn't check permissions.)
367
 * Determines the source boards for the supplied topics
368
 * Handles the moving of mark_read data
369
 * Updates the posts count of the affected boards
370
 *
371
 * @param int|int[] $topics The ID of a single topic to move or an array containing the IDs of multiple topics to move
372
 * @param int $toBoard The ID of the board to move the topics to
373
 */
374
function moveTopics($topics, $toBoard)
375
{
376
	global $sourcedir, $user_info, $modSettings, $smcFunc;
377
378
	// Empty array?
379
	if (empty($topics))
380
		return;
381
382
	// Only a single topic.
383
	if (is_numeric($topics))
384
		$topics = array($topics);
385
386
	$fromBoards = array();
387
388
	// Destination board empty or equal to 0?
389
	if (empty($toBoard))
390
		return;
391
392
	// Are we moving to the recycle board?
393
	$isRecycleDest = !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] == $toBoard;
394
395
	// Callback for search APIs to do their thing
396
	require_once($sourcedir . '/Search.php');
397
	$searchAPI = findSearchAPI();
398
	if ($searchAPI->supportsMethod('topicsMoved'))
399
		$searchAPI->topicsMoved($topics, $toBoard);
400
401
	// Determine the source boards...
402
	$request = $smcFunc['db_query']('', '
403
		SELECT id_board, approved, COUNT(*) AS num_topics, SUM(unapproved_posts) AS unapproved_posts,
404
			SUM(num_replies) AS num_replies
405
		FROM {db_prefix}topics
406
		WHERE id_topic IN ({array_int:topics})
407
		GROUP BY id_board, approved',
408
		array(
409
			'topics' => $topics,
410
		)
411
	);
412
	// Num of rows = 0 -> no topics found. Num of rows > 1 -> topics are on multiple boards.
413
	if ($smcFunc['db_num_rows']($request) == 0)
414
		return;
415 View Code Duplication
	while ($row = $smcFunc['db_fetch_assoc']($request))
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
416
	{
417
		if (!isset($fromBoards[$row['id_board']]['num_posts']))
418
		{
419
			$fromBoards[$row['id_board']] = array(
420
				'num_posts' => 0,
421
				'num_topics' => 0,
422
				'unapproved_posts' => 0,
423
				'unapproved_topics' => 0,
424
				'id_board' => $row['id_board']
425
			);
426
		}
427
		// Posts = (num_replies + 1) for each approved topic.
428
		$fromBoards[$row['id_board']]['num_posts'] += $row['num_replies'] + ($row['approved'] ? $row['num_topics'] : 0);
429
		$fromBoards[$row['id_board']]['unapproved_posts'] += $row['unapproved_posts'];
430
431
		// Add the topics to the right type.
432
		if ($row['approved'])
433
			$fromBoards[$row['id_board']]['num_topics'] += $row['num_topics'];
434
		else
435
			$fromBoards[$row['id_board']]['unapproved_topics'] += $row['num_topics'];
436
	}
437
	$smcFunc['db_free_result']($request);
438
439
	// Move over the mark_read data. (because it may be read and now not by some!)
440
	$SaveAServer = max(0, $modSettings['maxMsgID'] - 50000);
441
	$request = $smcFunc['db_query']('', '
442
		SELECT lmr.id_member, lmr.id_msg, t.id_topic, COALESCE(lt.unwatched, 0) AS unwatched
443
		FROM {db_prefix}topics AS t
444
			INNER JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = t.id_board
445
				AND lmr.id_msg > t.id_first_msg AND lmr.id_msg > {int:protect_lmr_msg})
446
			LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = lmr.id_member)
447
		WHERE t.id_topic IN ({array_int:topics})
448
			AND lmr.id_msg > COALESCE(lt.id_msg, 0)',
449
		array(
450
			'protect_lmr_msg' => $SaveAServer,
451
			'topics' => $topics,
452
		)
453
	);
454
	$log_topics = array();
455
	while ($row = $smcFunc['db_fetch_assoc']($request))
456
	{
457
		$log_topics[] = array($row['id_topic'], $row['id_member'], $row['id_msg'], (is_null($row['unwatched']) ? 0 : $row['unwatched']));
458
459
		// Prevent queries from getting too big. Taking some steam off.
460
		if (count($log_topics) > 500)
461
		{
462
			$smcFunc['db_insert']('replace',
463
				'{db_prefix}log_topics',
464
				array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int', 'unwatched' => 'int'),
465
				$log_topics,
466
				array('id_topic', 'id_member')
467
			);
468
469
			$log_topics = array();
470
		}
471
	}
472
	$smcFunc['db_free_result']($request);
473
474
	// Now that we have all the topics that *should* be marked read, and by which members...
475
	if (!empty($log_topics))
476
	{
477
		// Insert that information into the database!
478
		$smcFunc['db_insert']('replace',
479
			'{db_prefix}log_topics',
480
			array('id_topic' => 'int', 'id_member' => 'int', 'id_msg' => 'int', 'unwatched' => 'int'),
481
			$log_topics,
482
			array('id_topic', 'id_member')
483
		);
484
	}
485
486
	// Update the number of posts on each board.
487
	$totalTopics = 0;
488
	$totalPosts = 0;
489
	$totalUnapprovedTopics = 0;
490
	$totalUnapprovedPosts = 0;
491
	foreach ($fromBoards as $stats)
492
	{
493
		$smcFunc['db_query']('', '
494
			UPDATE {db_prefix}boards
495
			SET
496
				num_posts = CASE WHEN {int:num_posts} > num_posts THEN 0 ELSE num_posts - {int:num_posts} END,
497
				num_topics = CASE WHEN {int:num_topics} > num_topics THEN 0 ELSE num_topics - {int:num_topics} END,
498
				unapproved_posts = CASE WHEN {int:unapproved_posts} > unapproved_posts THEN 0 ELSE unapproved_posts - {int:unapproved_posts} END,
499
				unapproved_topics = CASE WHEN {int:unapproved_topics} > unapproved_topics THEN 0 ELSE unapproved_topics - {int:unapproved_topics} END
500
			WHERE id_board = {int:id_board}',
501
			array(
502
				'id_board' => $stats['id_board'],
503
				'num_posts' => $stats['num_posts'],
504
				'num_topics' => $stats['num_topics'],
505
				'unapproved_posts' => $stats['unapproved_posts'],
506
				'unapproved_topics' => $stats['unapproved_topics'],
507
			)
508
		);
509
		$totalTopics += $stats['num_topics'];
510
		$totalPosts += $stats['num_posts'];
511
		$totalUnapprovedTopics += $stats['unapproved_topics'];
512
		$totalUnapprovedPosts += $stats['unapproved_posts'];
513
	}
514
	$smcFunc['db_query']('', '
515
		UPDATE {db_prefix}boards
516
		SET
517
			num_topics = num_topics + {int:total_topics},
518
			num_posts = num_posts + {int:total_posts},' . ($isRecycleDest ? '
519
			unapproved_posts = {int:no_unapproved}, unapproved_topics = {int:no_unapproved}' : '
520
			unapproved_posts = unapproved_posts + {int:total_unapproved_posts},
521
			unapproved_topics = unapproved_topics + {int:total_unapproved_topics}') . '
522
		WHERE id_board = {int:id_board}',
523
		array(
524
			'id_board' => $toBoard,
525
			'total_topics' => $totalTopics,
526
			'total_posts' => $totalPosts,
527
			'total_unapproved_topics' => $totalUnapprovedTopics,
528
			'total_unapproved_posts' => $totalUnapprovedPosts,
529
			'no_unapproved' => 0,
530
		)
531
	);
532
533
	// Move the topic.  Done.  :P
534
	$smcFunc['db_query']('', '
535
		UPDATE {db_prefix}topics
536
		SET id_board = {int:id_board}' . ($isRecycleDest ? ',
537
			unapproved_posts = {int:no_unapproved}, approved = {int:is_approved}' : '') . '
538
		WHERE id_topic IN ({array_int:topics})',
539
		array(
540
			'id_board' => $toBoard,
541
			'topics' => $topics,
542
			'is_approved' => 1,
543
			'no_unapproved' => 0,
544
		)
545
	);
546
547
	// If this was going to the recycle bin, check what messages are being recycled, and remove them from the queue.
548
	if ($isRecycleDest && ($totalUnapprovedTopics || $totalUnapprovedPosts))
549
	{
550
		$request = $smcFunc['db_query']('', '
551
			SELECT id_msg
552
			FROM {db_prefix}messages
553
			WHERE id_topic IN ({array_int:topics})
554
				and approved = {int:not_approved}',
555
			array(
556
				'topics' => $topics,
557
				'not_approved' => 0,
558
			)
559
		);
560
		$approval_msgs = array();
561
		while ($row = $smcFunc['db_fetch_assoc']($request))
562
			$approval_msgs[] = $row['id_msg'];
563
		$smcFunc['db_free_result']($request);
564
565
		// Empty the approval queue for these, as we're going to approve them next.
566
		if (!empty($approval_msgs))
567
			$smcFunc['db_query']('', '
568
				DELETE FROM {db_prefix}approval_queue
569
				WHERE id_msg IN ({array_int:message_list})
570
					AND id_attach = {int:id_attach}',
571
				array(
572
					'message_list' => $approval_msgs,
573
					'id_attach' => 0,
574
				)
575
			);
576
577
		// Get all the current max and mins.
578
		$request = $smcFunc['db_query']('', '
579
			SELECT id_topic, id_first_msg, id_last_msg
580
			FROM {db_prefix}topics
581
			WHERE id_topic IN ({array_int:topics})',
582
			array(
583
				'topics' => $topics,
584
			)
585
		);
586
		$topicMaxMin = array();
587
		while ($row = $smcFunc['db_fetch_assoc']($request))
588
		{
589
			$topicMaxMin[$row['id_topic']] = array(
590
				'min' => $row['id_first_msg'],
591
				'max' => $row['id_last_msg'],
592
			);
593
		}
594
		$smcFunc['db_free_result']($request);
595
596
		// Check the MAX and MIN are correct.
597
		$request = $smcFunc['db_query']('', '
598
			SELECT id_topic, MIN(id_msg) AS first_msg, MAX(id_msg) AS last_msg
599
			FROM {db_prefix}messages
600
			WHERE id_topic IN ({array_int:topics})
601
			GROUP BY id_topic',
602
			array(
603
				'topics' => $topics,
604
			)
605
		);
606
		while ($row = $smcFunc['db_fetch_assoc']($request))
607
		{
608
			// If not, update.
609
			if ($row['first_msg'] != $topicMaxMin[$row['id_topic']]['min'] || $row['last_msg'] != $topicMaxMin[$row['id_topic']]['max'])
610
				$smcFunc['db_query']('', '
611
					UPDATE {db_prefix}topics
612
					SET id_first_msg = {int:first_msg}, id_last_msg = {int:last_msg}
613
					WHERE id_topic = {int:selected_topic}',
614
					array(
615
						'first_msg' => $row['first_msg'],
616
						'last_msg' => $row['last_msg'],
617
						'selected_topic' => $row['id_topic'],
618
					)
619
				);
620
		}
621
		$smcFunc['db_free_result']($request);
622
	}
623
624
	$smcFunc['db_query']('', '
625
		UPDATE {db_prefix}messages
626
		SET id_board = {int:id_board}' . ($isRecycleDest ? ',approved = {int:is_approved}' : '') . '
627
		WHERE id_topic IN ({array_int:topics})',
628
		array(
629
			'id_board' => $toBoard,
630
			'topics' => $topics,
631
			'is_approved' => 1,
632
		)
633
	);
634
	$smcFunc['db_query']('', '
635
		UPDATE {db_prefix}log_reported
636
		SET id_board = {int:id_board}
637
		WHERE id_topic IN ({array_int:topics})',
638
		array(
639
			'id_board' => $toBoard,
640
			'topics' => $topics,
641
		)
642
	);
643
	$smcFunc['db_query']('', '
644
		UPDATE {db_prefix}calendar
645
		SET id_board = {int:id_board}
646
		WHERE id_topic IN ({array_int:topics})',
647
		array(
648
			'id_board' => $toBoard,
649
			'topics' => $topics,
650
		)
651
	);
652
653
	// Mark target board as seen, if it was already marked as seen before.
654
	$request = $smcFunc['db_query']('', '
655
		SELECT (COALESCE(lb.id_msg, 0) >= b.id_msg_updated) AS isSeen
656
		FROM {db_prefix}boards AS b
657
			LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})
658
		WHERE b.id_board = {int:id_board}',
659
		array(
660
			'current_member' => $user_info['id'],
661
			'id_board' => $toBoard,
662
		)
663
	);
664
	list ($isSeen) = $smcFunc['db_fetch_row']($request);
665
	$smcFunc['db_free_result']($request);
666
667
	if (!empty($isSeen) && !$user_info['is_guest'])
668
	{
669
		$smcFunc['db_insert']('replace',
670
			'{db_prefix}log_boards',
671
			array('id_board' => 'int', 'id_member' => 'int', 'id_msg' => 'int'),
672
			array($toBoard, $user_info['id'], $modSettings['maxMsgID']),
673
			array('id_board', 'id_member')
674
		);
675
	}
676
677
	// Update the cache?
678 View Code Duplication
	if (!empty($modSettings['cache_enable']) && $modSettings['cache_enable'] >= 3)
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
679
		foreach ($topics as $topic_id)
680
			cache_put_data('topic_board-' . $topic_id, null, 120);
681
682
	require_once($sourcedir . '/Subs-Post.php');
683
684
	$updates = array_keys($fromBoards);
685
	$updates[] = $toBoard;
686
687
	updateLastMessages(array_unique($updates));
688
689
	// Update 'em pesky stats.
690
	updateStats('topic');
691
	updateStats('message');
692
	updateSettings(array(
693
		'calendar_updated' => time(),
694
	));
695
}
696
697
/**
698
 * Called after a topic is moved to update $board_link and $topic_link to point to new location
699
 */
700
function moveTopicConcurrence()
701
{
702
	global $board, $topic, $smcFunc, $scripturl;
703
704
	if (isset($_GET['current_board']))
705
		$move_from = (int) $_GET['current_board'];
706
707
	if (empty($move_from) || empty($board) || empty($topic))
708
		return true;
709
710
	if ($move_from == $board)
711
		return true;
712
	else
713
	{
714
		$request = $smcFunc['db_query']('', '
715
			SELECT m.subject, b.name
716
			FROM {db_prefix}topics as t
717
				LEFT JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board)
718
				LEFT JOIN {db_prefix}messages AS m ON (t.id_first_msg = m.id_msg)
719
			WHERE t.id_topic = {int:topic_id}
720
			LIMIT 1',
721
			array(
722
				'topic_id' => $topic,
723
			)
724
		);
725
		list($topic_subject, $board_name) = $smcFunc['db_fetch_row']($request);
726
		$smcFunc['db_free_result']($request);
727
		$board_link = '<a href="' . $scripturl . '?board=' . $board . '.0">' . $board_name . '</a>';
728
		$topic_link = '<a href="' . $scripturl . '?topic=' . $topic . '.0">' . $topic_subject . '</a>';
729
		fatal_lang_error('topic_already_moved', false, array($topic_link, $board_link));
730
	}
731
}
732
733
?>