|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* This file is mainly concerned with minor tasks relating to boards, such as |
|
5
|
|
|
* marking them read, collapsing categories, or quick moderation. |
|
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
|
|
|
* Mark a board or multiple boards read. |
|
22
|
|
|
* |
|
23
|
|
|
* @param int|array $boards The ID of a single board or an array of boards |
|
24
|
|
|
* @param bool $unread Whether we're marking them as unread |
|
25
|
|
|
*/ |
|
26
|
|
|
function markBoardsRead($boards, $unread = false) |
|
27
|
|
|
{ |
|
28
|
|
|
global $user_info, $modSettings, $smcFunc; |
|
29
|
|
|
|
|
30
|
|
|
// Force $boards to be an array. |
|
31
|
|
|
if (!is_array($boards)) |
|
32
|
|
|
$boards = array($boards); |
|
33
|
|
|
else |
|
34
|
|
|
$boards = array_unique($boards); |
|
35
|
|
|
|
|
36
|
|
|
// No boards, nothing to mark as read. |
|
37
|
|
|
if (empty($boards)) |
|
38
|
|
|
return; |
|
39
|
|
|
|
|
40
|
|
|
// Allow the user to mark a board as unread. |
|
41
|
|
|
if ($unread) |
|
42
|
|
|
{ |
|
43
|
|
|
// Clear out all the places where this lovely info is stored. |
|
44
|
|
|
// @todo Maybe not log_mark_read? |
|
45
|
|
|
$smcFunc['db_query']('', ' |
|
46
|
|
|
DELETE FROM {db_prefix}log_mark_read |
|
47
|
|
|
WHERE id_board IN ({array_int:board_list}) |
|
48
|
|
|
AND id_member = {int:current_member}', |
|
49
|
|
|
array( |
|
50
|
|
|
'current_member' => $user_info['id'], |
|
51
|
|
|
'board_list' => $boards, |
|
52
|
|
|
) |
|
53
|
|
|
); |
|
54
|
|
|
$smcFunc['db_query']('', ' |
|
55
|
|
|
DELETE FROM {db_prefix}log_boards |
|
56
|
|
|
WHERE id_board IN ({array_int:board_list}) |
|
57
|
|
|
AND id_member = {int:current_member}', |
|
58
|
|
|
array( |
|
59
|
|
|
'current_member' => $user_info['id'], |
|
60
|
|
|
'board_list' => $boards, |
|
61
|
|
|
) |
|
62
|
|
|
); |
|
63
|
|
|
} |
|
64
|
|
|
// Otherwise mark the board as read. |
|
65
|
|
|
else |
|
66
|
|
|
{ |
|
67
|
|
|
$markRead = array(); |
|
68
|
|
|
foreach ($boards as $board) |
|
69
|
|
|
$markRead[] = array($modSettings['maxMsgID'], $user_info['id'], $board); |
|
70
|
|
|
|
|
71
|
|
|
// Update log_mark_read and log_boards. |
|
72
|
|
|
$smcFunc['db_insert']('replace', |
|
73
|
|
|
'{db_prefix}log_mark_read', |
|
74
|
|
|
array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), |
|
75
|
|
|
$markRead, |
|
76
|
|
|
array('id_board', 'id_member') |
|
77
|
|
|
); |
|
78
|
|
|
|
|
79
|
|
|
$smcFunc['db_insert']('replace', |
|
80
|
|
|
'{db_prefix}log_boards', |
|
81
|
|
|
array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), |
|
82
|
|
|
$markRead, |
|
83
|
|
|
array('id_board', 'id_member') |
|
84
|
|
|
); |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
// Get rid of useless log_topics data, because log_mark_read is better for it - even if marking unread - I think so... |
|
88
|
|
|
// @todo look at this... |
|
89
|
|
|
// The call to markBoardsRead() in Display() used to be simply |
|
90
|
|
|
// marking log_boards (the previous query only) |
|
91
|
|
|
$result = $smcFunc['db_query']('', ' |
|
92
|
|
|
SELECT MIN(id_topic) |
|
93
|
|
|
FROM {db_prefix}log_topics |
|
94
|
|
|
WHERE id_member = {int:current_member}', |
|
95
|
|
|
array( |
|
96
|
|
|
'current_member' => $user_info['id'], |
|
97
|
|
|
) |
|
98
|
|
|
); |
|
99
|
|
|
list ($lowest_topic) = $smcFunc['db_fetch_row']($result); |
|
100
|
|
|
$smcFunc['db_free_result']($result); |
|
101
|
|
|
|
|
102
|
|
|
if (empty($lowest_topic)) |
|
103
|
|
|
return; |
|
104
|
|
|
|
|
105
|
|
|
// @todo SLOW This query seems to eat it sometimes. |
|
106
|
|
|
$result = $smcFunc['db_query']('', ' |
|
107
|
|
|
SELECT lt.id_topic |
|
108
|
|
|
FROM {db_prefix}log_topics AS lt |
|
109
|
|
|
INNER JOIN {db_prefix}topics AS t /*!40000 USE INDEX (PRIMARY) */ ON (t.id_topic = lt.id_topic |
|
110
|
|
|
AND t.id_board IN ({array_int:board_list})) |
|
111
|
|
|
WHERE lt.id_member = {int:current_member} |
|
112
|
|
|
AND lt.id_topic >= {int:lowest_topic} |
|
113
|
|
|
AND lt.unwatched != 1', |
|
114
|
|
|
array( |
|
115
|
|
|
'current_member' => $user_info['id'], |
|
116
|
|
|
'board_list' => $boards, |
|
117
|
|
|
'lowest_topic' => $lowest_topic, |
|
118
|
|
|
) |
|
119
|
|
|
); |
|
120
|
|
|
$topics = array(); |
|
121
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
122
|
|
|
$topics[] = $row['id_topic']; |
|
123
|
|
|
$smcFunc['db_free_result']($result); |
|
124
|
|
|
|
|
125
|
|
|
if (!empty($topics)) |
|
126
|
|
|
$smcFunc['db_query']('', ' |
|
127
|
|
|
DELETE FROM {db_prefix}log_topics |
|
128
|
|
|
WHERE id_member = {int:current_member} |
|
129
|
|
|
AND id_topic IN ({array_int:topic_list})', |
|
130
|
|
|
array( |
|
131
|
|
|
'current_member' => $user_info['id'], |
|
132
|
|
|
'topic_list' => $topics, |
|
133
|
|
|
) |
|
134
|
|
|
); |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
/** |
|
138
|
|
|
* Mark one or more boards as read. |
|
139
|
|
|
*/ |
|
140
|
|
|
function MarkRead() |
|
141
|
|
|
{ |
|
142
|
|
|
global $board, $topic, $user_info, $board_info, $modSettings, $smcFunc; |
|
143
|
|
|
|
|
144
|
|
|
// No Guests allowed! |
|
145
|
|
|
is_not_guest(); |
|
146
|
|
|
|
|
147
|
|
|
checkSession('get'); |
|
148
|
|
|
|
|
149
|
|
|
if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'all') |
|
150
|
|
|
{ |
|
151
|
|
|
// Find all the boards this user can see. |
|
152
|
|
|
$result = $smcFunc['db_query']('', ' |
|
153
|
|
|
SELECT b.id_board |
|
154
|
|
|
FROM {db_prefix}boards AS b |
|
155
|
|
|
WHERE {query_see_board}', |
|
156
|
|
|
array( |
|
157
|
|
|
) |
|
158
|
|
|
); |
|
159
|
|
|
$boards = array(); |
|
160
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
161
|
|
|
$boards[] = $row['id_board']; |
|
162
|
|
|
$smcFunc['db_free_result']($result); |
|
163
|
|
|
|
|
164
|
|
|
if (!empty($boards)) |
|
165
|
|
|
markBoardsRead($boards, isset($_REQUEST['unread'])); |
|
166
|
|
|
|
|
167
|
|
|
$_SESSION['id_msg_last_visit'] = $modSettings['maxMsgID']; |
|
168
|
|
View Code Duplication |
if (!empty($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'action=unread') !== false) |
|
|
|
|
|
|
169
|
|
|
redirectexit('action=unread'); |
|
170
|
|
|
|
|
171
|
|
|
if (isset($_SESSION['topicseen_cache'])) |
|
172
|
|
|
$_SESSION['topicseen_cache'] = array(); |
|
173
|
|
|
|
|
174
|
|
|
redirectexit(); |
|
175
|
|
|
} |
|
176
|
|
|
elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'unreadreplies') |
|
177
|
|
|
{ |
|
178
|
|
|
// Make sure all the topics are integers! |
|
179
|
|
|
$topics = array_map('intval', explode('-', $_REQUEST['topics'])); |
|
180
|
|
|
|
|
181
|
|
|
$request = $smcFunc['db_query']('', ' |
|
182
|
|
|
SELECT id_topic, unwatched |
|
183
|
|
|
FROM {db_prefix}log_topics |
|
184
|
|
|
WHERE id_topic IN ({array_int:selected_topics}) |
|
185
|
|
|
AND id_member = {int:current_user}', |
|
186
|
|
|
array( |
|
187
|
|
|
'selected_topics' => $topics, |
|
188
|
|
|
'current_user' => $user_info['id'], |
|
189
|
|
|
) |
|
190
|
|
|
); |
|
191
|
|
|
$logged_topics = array(); |
|
192
|
|
View Code Duplication |
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
|
|
|
|
|
193
|
|
|
$logged_topics[$row['id_topic']] = $row['unwatched']; |
|
194
|
|
|
$smcFunc['db_free_result']($request); |
|
195
|
|
|
|
|
196
|
|
|
$markRead = array(); |
|
197
|
|
View Code Duplication |
foreach ($topics as $id_topic) |
|
|
|
|
|
|
198
|
|
|
$markRead[] = array($modSettings['maxMsgID'], $user_info['id'], $id_topic, (isset($logged_topics[$topic]) ? $logged_topics[$topic] : 0)); |
|
199
|
|
|
|
|
200
|
|
|
$smcFunc['db_insert']('replace', |
|
201
|
|
|
'{db_prefix}log_topics', |
|
202
|
|
|
array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int', 'unwatched' => 'int'), |
|
203
|
|
|
$markRead, |
|
204
|
|
|
array('id_member', 'id_topic') |
|
205
|
|
|
); |
|
206
|
|
|
|
|
207
|
|
|
if (isset($_SESSION['topicseen_cache'])) |
|
208
|
|
|
$_SESSION['topicseen_cache'] = array(); |
|
209
|
|
|
|
|
210
|
|
|
redirectexit('action=unreadreplies'); |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
// Special case: mark a topic unread! |
|
214
|
|
|
elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'topic') |
|
215
|
|
|
{ |
|
216
|
|
|
// First, let's figure out what the latest message is. |
|
217
|
|
|
$result = $smcFunc['db_query']('', ' |
|
218
|
|
|
SELECT t.id_first_msg, t.id_last_msg, COALESCE(lt.unwatched, 0) as unwatched |
|
219
|
|
|
FROM {db_prefix}topics as t |
|
220
|
|
|
LEFT JOIN {db_prefix}log_topics as lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member}) |
|
221
|
|
|
WHERE t.id_topic = {int:current_topic}', |
|
222
|
|
|
array( |
|
223
|
|
|
'current_topic' => $topic, |
|
224
|
|
|
'current_member' => $user_info['id'], |
|
225
|
|
|
) |
|
226
|
|
|
); |
|
227
|
|
|
$topicinfo = $smcFunc['db_fetch_assoc']($result); |
|
228
|
|
|
$smcFunc['db_free_result']($result); |
|
229
|
|
|
|
|
230
|
|
|
if (!empty($_GET['t'])) |
|
231
|
|
|
{ |
|
232
|
|
|
// If they read the whole topic, go back to the beginning. |
|
233
|
|
|
if ($_GET['t'] >= $topicinfo['id_last_msg']) |
|
234
|
|
|
$earlyMsg = 0; |
|
235
|
|
|
// If they want to mark the whole thing read, same. |
|
236
|
|
|
elseif ($_GET['t'] <= $topicinfo['id_first_msg']) |
|
237
|
|
|
$earlyMsg = 0; |
|
238
|
|
|
// Otherwise, get the latest message before the named one. |
|
239
|
|
View Code Duplication |
else |
|
|
|
|
|
|
240
|
|
|
{ |
|
241
|
|
|
$result = $smcFunc['db_query']('', ' |
|
242
|
|
|
SELECT MAX(id_msg) |
|
243
|
|
|
FROM {db_prefix}messages |
|
244
|
|
|
WHERE id_topic = {int:current_topic} |
|
245
|
|
|
AND id_msg >= {int:id_first_msg} |
|
246
|
|
|
AND id_msg < {int:topic_msg_id}', |
|
247
|
|
|
array( |
|
248
|
|
|
'current_topic' => $topic, |
|
249
|
|
|
'topic_msg_id' => (int) $_GET['t'], |
|
250
|
|
|
'id_first_msg' => $topicinfo['id_first_msg'], |
|
251
|
|
|
) |
|
252
|
|
|
); |
|
253
|
|
|
list ($earlyMsg) = $smcFunc['db_fetch_row']($result); |
|
254
|
|
|
$smcFunc['db_free_result']($result); |
|
255
|
|
|
} |
|
256
|
|
|
} |
|
257
|
|
|
// Marking read from first page? That's the whole topic. |
|
258
|
|
|
elseif ($_REQUEST['start'] == 0) |
|
259
|
|
|
$earlyMsg = 0; |
|
260
|
|
View Code Duplication |
else |
|
|
|
|
|
|
261
|
|
|
{ |
|
262
|
|
|
$result = $smcFunc['db_query']('', ' |
|
263
|
|
|
SELECT id_msg |
|
264
|
|
|
FROM {db_prefix}messages |
|
265
|
|
|
WHERE id_topic = {int:current_topic} |
|
266
|
|
|
ORDER BY id_msg |
|
267
|
|
|
LIMIT {int:start}, 1', |
|
268
|
|
|
array( |
|
269
|
|
|
'current_topic' => $topic, |
|
270
|
|
|
'start' => (int) $_REQUEST['start'], |
|
271
|
|
|
) |
|
272
|
|
|
); |
|
273
|
|
|
list ($earlyMsg) = $smcFunc['db_fetch_row']($result); |
|
274
|
|
|
$smcFunc['db_free_result']($result); |
|
275
|
|
|
|
|
276
|
|
|
$earlyMsg--; |
|
277
|
|
|
} |
|
278
|
|
|
|
|
279
|
|
|
// Blam, unread! |
|
280
|
|
|
$smcFunc['db_insert']('replace', |
|
281
|
|
|
'{db_prefix}log_topics', |
|
282
|
|
|
array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int', 'unwatched' => 'int'), |
|
283
|
|
|
array($earlyMsg, $user_info['id'], $topic, $topicinfo['unwatched']), |
|
284
|
|
|
array('id_member', 'id_topic') |
|
285
|
|
|
); |
|
286
|
|
|
|
|
287
|
|
|
redirectexit('board=' . $board . '.0'); |
|
288
|
|
|
} |
|
289
|
|
|
else |
|
290
|
|
|
{ |
|
291
|
|
|
$categories = array(); |
|
292
|
|
|
$boards = array(); |
|
293
|
|
|
|
|
294
|
|
View Code Duplication |
if (isset($_REQUEST['c'])) |
|
|
|
|
|
|
295
|
|
|
{ |
|
296
|
|
|
$_REQUEST['c'] = explode(',', $_REQUEST['c']); |
|
297
|
|
|
foreach ($_REQUEST['c'] as $c) |
|
298
|
|
|
$categories[] = (int) $c; |
|
299
|
|
|
} |
|
300
|
|
View Code Duplication |
if (isset($_REQUEST['boards'])) |
|
|
|
|
|
|
301
|
|
|
{ |
|
302
|
|
|
$_REQUEST['boards'] = explode(',', $_REQUEST['boards']); |
|
303
|
|
|
foreach ($_REQUEST['boards'] as $b) |
|
304
|
|
|
$boards[] = (int) $b; |
|
305
|
|
|
} |
|
306
|
|
|
if (!empty($board)) |
|
307
|
|
|
$boards[] = (int) $board; |
|
308
|
|
|
|
|
309
|
|
View Code Duplication |
if (isset($_REQUEST['children']) && !empty($boards)) |
|
|
|
|
|
|
310
|
|
|
{ |
|
311
|
|
|
// They want to mark the entire tree starting with the boards specified |
|
312
|
|
|
// The easiest thing is to just get all the boards they can see, but since we've specified the top of tree we ignore some of them |
|
313
|
|
|
|
|
314
|
|
|
$request = $smcFunc['db_query']('', ' |
|
315
|
|
|
SELECT b.id_board, b.id_parent |
|
316
|
|
|
FROM {db_prefix}boards AS b |
|
317
|
|
|
WHERE {query_see_board} |
|
318
|
|
|
AND b.child_level > {int:no_parents} |
|
319
|
|
|
AND b.id_board NOT IN ({array_int:board_list}) |
|
320
|
|
|
ORDER BY child_level ASC |
|
321
|
|
|
', |
|
322
|
|
|
array( |
|
323
|
|
|
'no_parents' => 0, |
|
324
|
|
|
'board_list' => $boards, |
|
325
|
|
|
) |
|
326
|
|
|
); |
|
327
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
328
|
|
|
if (in_array($row['id_parent'], $boards)) |
|
329
|
|
|
$boards[] = $row['id_board']; |
|
330
|
|
|
$smcFunc['db_free_result']($request); |
|
331
|
|
|
} |
|
332
|
|
|
|
|
333
|
|
|
$clauses = array(); |
|
334
|
|
|
$clauseParameters = array(); |
|
335
|
|
|
if (!empty($categories)) |
|
336
|
|
|
{ |
|
337
|
|
|
$clauses[] = 'id_cat IN ({array_int:category_list})'; |
|
338
|
|
|
$clauseParameters['category_list'] = $categories; |
|
339
|
|
|
} |
|
340
|
|
|
if (!empty($boards)) |
|
341
|
|
|
{ |
|
342
|
|
|
$clauses[] = 'id_board IN ({array_int:board_list})'; |
|
343
|
|
|
$clauseParameters['board_list'] = $boards; |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
if (empty($clauses)) |
|
347
|
|
|
redirectexit(); |
|
348
|
|
|
|
|
349
|
|
|
$request = $smcFunc['db_query']('', ' |
|
350
|
|
|
SELECT b.id_board |
|
351
|
|
|
FROM {db_prefix}boards AS b |
|
352
|
|
|
WHERE {query_see_board} |
|
353
|
|
|
AND b.' . implode(' OR b.', $clauses), |
|
354
|
|
|
array_merge($clauseParameters, array( |
|
355
|
|
|
)) |
|
356
|
|
|
); |
|
357
|
|
|
$boards = array(); |
|
358
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
359
|
|
|
$boards[] = $row['id_board']; |
|
360
|
|
|
$smcFunc['db_free_result']($request); |
|
361
|
|
|
|
|
362
|
|
|
if (empty($boards)) |
|
363
|
|
|
redirectexit(); |
|
364
|
|
|
|
|
365
|
|
|
markBoardsRead($boards, isset($_REQUEST['unread'])); |
|
366
|
|
|
|
|
367
|
|
|
foreach ($boards as $b) |
|
368
|
|
|
{ |
|
369
|
|
|
if (isset($_SESSION['topicseen_cache'][$b])) |
|
370
|
|
|
$_SESSION['topicseen_cache'][$b] = array(); |
|
371
|
|
|
} |
|
372
|
|
|
|
|
373
|
|
|
if (!isset($_REQUEST['unread'])) |
|
374
|
|
|
{ |
|
375
|
|
|
// Find all the boards this user can see. |
|
376
|
|
|
$result = $smcFunc['db_query']('', ' |
|
377
|
|
|
SELECT b.id_board |
|
378
|
|
|
FROM {db_prefix}boards AS b |
|
379
|
|
|
WHERE b.id_parent IN ({array_int:parent_list}) |
|
380
|
|
|
AND {query_see_board}', |
|
381
|
|
|
array( |
|
382
|
|
|
'parent_list' => $boards, |
|
383
|
|
|
) |
|
384
|
|
|
); |
|
385
|
|
|
if ($smcFunc['db_num_rows']($result) > 0) |
|
386
|
|
|
{ |
|
387
|
|
|
$logBoardInserts = array(); |
|
388
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
389
|
|
|
$logBoardInserts[] = array($modSettings['maxMsgID'], $user_info['id'], $row['id_board']); |
|
390
|
|
|
|
|
391
|
|
|
$smcFunc['db_insert']('replace', |
|
392
|
|
|
'{db_prefix}log_boards', |
|
393
|
|
|
array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'), |
|
394
|
|
|
$logBoardInserts, |
|
395
|
|
|
array('id_member', 'id_board') |
|
396
|
|
|
); |
|
397
|
|
|
} |
|
398
|
|
|
$smcFunc['db_free_result']($result); |
|
399
|
|
|
|
|
400
|
|
|
if (empty($board)) |
|
401
|
|
|
redirectexit(); |
|
402
|
|
|
else |
|
403
|
|
|
redirectexit('board=' . $board . '.0'); |
|
404
|
|
|
} |
|
405
|
|
|
else |
|
406
|
|
|
{ |
|
407
|
|
|
if (empty($board_info['parent'])) |
|
408
|
|
|
redirectexit(); |
|
409
|
|
|
else |
|
410
|
|
|
redirectexit('board=' . $board_info['parent'] . '.0'); |
|
411
|
|
|
} |
|
412
|
|
|
} |
|
413
|
|
|
} |
|
414
|
|
|
|
|
415
|
|
|
/** |
|
416
|
|
|
* Get the id_member associated with the specified message. |
|
417
|
|
|
* @param int $messageID The ID of the message |
|
418
|
|
|
* @return int The ID of the member associated with that post |
|
419
|
|
|
*/ |
|
420
|
|
|
function getMsgMemberID($messageID) |
|
421
|
|
|
{ |
|
422
|
|
|
global $smcFunc; |
|
423
|
|
|
|
|
424
|
|
|
// Find the topic and make sure the member still exists. |
|
425
|
|
|
$result = $smcFunc['db_query']('', ' |
|
426
|
|
|
SELECT COALESCE(mem.id_member, 0) |
|
427
|
|
|
FROM {db_prefix}messages AS m |
|
428
|
|
|
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) |
|
429
|
|
|
WHERE m.id_msg = {int:selected_message} |
|
430
|
|
|
LIMIT 1', |
|
431
|
|
|
array( |
|
432
|
|
|
'selected_message' => (int) $messageID, |
|
433
|
|
|
) |
|
434
|
|
|
); |
|
435
|
|
View Code Duplication |
if ($smcFunc['db_num_rows']($result) > 0) |
|
|
|
|
|
|
436
|
|
|
list ($memberID) = $smcFunc['db_fetch_row']($result); |
|
437
|
|
|
// The message doesn't even exist. |
|
438
|
|
|
else |
|
439
|
|
|
$memberID = 0; |
|
440
|
|
|
$smcFunc['db_free_result']($result); |
|
441
|
|
|
|
|
442
|
|
|
return (int) $memberID; |
|
443
|
|
|
} |
|
444
|
|
|
|
|
445
|
|
|
/** |
|
446
|
|
|
* Modify the settings and position of a board. |
|
447
|
|
|
* Used by ManageBoards.php to change the settings of a board. |
|
448
|
|
|
* |
|
449
|
|
|
* @param int $board_id The ID of the board |
|
450
|
|
|
* @param array &$boardOptions An array of options related to the board |
|
451
|
|
|
*/ |
|
452
|
|
|
function modifyBoard($board_id, &$boardOptions) |
|
453
|
|
|
{ |
|
454
|
|
|
global $cat_tree, $boards, $smcFunc; |
|
455
|
|
|
|
|
456
|
|
|
// Get some basic information about all boards and categories. |
|
457
|
|
|
getBoardTree(); |
|
458
|
|
|
|
|
459
|
|
|
// Make sure given boards and categories exist. |
|
460
|
|
|
if (!isset($boards[$board_id]) || (isset($boardOptions['target_board']) && !isset($boards[$boardOptions['target_board']])) || (isset($boardOptions['target_category']) && !isset($cat_tree[$boardOptions['target_category']]))) |
|
461
|
|
|
fatal_lang_error('no_board'); |
|
462
|
|
|
|
|
463
|
|
|
$id = $board_id; |
|
464
|
|
|
call_integration_hook('integrate_pre_modify_board', array($id, &$boardOptions)); |
|
465
|
|
|
|
|
466
|
|
|
// All things that will be updated in the database will be in $boardUpdates. |
|
467
|
|
|
$boardUpdates = array(); |
|
468
|
|
|
$boardUpdateParameters = array(); |
|
469
|
|
|
|
|
470
|
|
|
// In case the board has to be moved |
|
471
|
|
|
if (isset($boardOptions['move_to'])) |
|
472
|
|
|
{ |
|
473
|
|
|
// Move the board to the top of a given category. |
|
474
|
|
|
if ($boardOptions['move_to'] == 'top') |
|
475
|
|
|
{ |
|
476
|
|
|
$id_cat = $boardOptions['target_category']; |
|
477
|
|
|
$child_level = 0; |
|
478
|
|
|
$id_parent = 0; |
|
479
|
|
|
$after = $cat_tree[$id_cat]['last_board_order']; |
|
480
|
|
|
} |
|
481
|
|
|
|
|
482
|
|
|
// Move the board to the bottom of a given category. |
|
483
|
|
|
elseif ($boardOptions['move_to'] == 'bottom') |
|
484
|
|
|
{ |
|
485
|
|
|
$id_cat = $boardOptions['target_category']; |
|
486
|
|
|
$child_level = 0; |
|
487
|
|
|
$id_parent = 0; |
|
488
|
|
|
$after = 0; |
|
489
|
|
|
foreach ($cat_tree[$id_cat]['children'] as $id_board => $dummy) |
|
490
|
|
|
$after = max($after, $boards[$id_board]['order']); |
|
491
|
|
|
} |
|
492
|
|
|
|
|
493
|
|
|
// Make the board a child of a given board. |
|
494
|
|
|
elseif ($boardOptions['move_to'] == 'child') |
|
495
|
|
|
{ |
|
496
|
|
|
$id_cat = $boards[$boardOptions['target_board']]['category']; |
|
497
|
|
|
$child_level = $boards[$boardOptions['target_board']]['level'] + 1; |
|
498
|
|
|
$id_parent = $boardOptions['target_board']; |
|
499
|
|
|
|
|
500
|
|
|
// People can be creative, in many ways... |
|
501
|
|
|
if (isChildOf($id_parent, $board_id)) |
|
502
|
|
|
fatal_lang_error('mboards_parent_own_child_error', false); |
|
503
|
|
|
elseif ($id_parent == $board_id) |
|
504
|
|
|
fatal_lang_error('mboards_board_own_child_error', false); |
|
505
|
|
|
|
|
506
|
|
|
$after = $boards[$boardOptions['target_board']]['order']; |
|
507
|
|
|
|
|
508
|
|
|
// Check if there are already children and (if so) get the max board order. |
|
509
|
|
|
if (!empty($boards[$id_parent]['tree']['children']) && empty($boardOptions['move_first_child'])) |
|
510
|
|
|
foreach ($boards[$id_parent]['tree']['children'] as $childBoard_id => $dummy) |
|
511
|
|
|
$after = max($after, $boards[$childBoard_id]['order']); |
|
512
|
|
|
} |
|
513
|
|
|
|
|
514
|
|
|
// Place a board before or after another board, on the same child level. |
|
515
|
|
|
elseif (in_array($boardOptions['move_to'], array('before', 'after'))) |
|
516
|
|
|
{ |
|
517
|
|
|
$id_cat = $boards[$boardOptions['target_board']]['category']; |
|
518
|
|
|
$child_level = $boards[$boardOptions['target_board']]['level']; |
|
519
|
|
|
$id_parent = $boards[$boardOptions['target_board']]['parent']; |
|
520
|
|
|
$after = $boards[$boardOptions['target_board']]['order'] - ($boardOptions['move_to'] == 'before' ? 1 : 0); |
|
521
|
|
|
} |
|
522
|
|
|
|
|
523
|
|
|
// Oops...? |
|
524
|
|
|
else |
|
525
|
|
|
trigger_error('modifyBoard(): The move_to value \'' . $boardOptions['move_to'] . '\' is incorrect', E_USER_ERROR); |
|
526
|
|
|
|
|
527
|
|
|
// Get a list of children of this board. |
|
528
|
|
|
$childList = array(); |
|
529
|
|
|
recursiveBoards($childList, $boards[$board_id]['tree']); |
|
530
|
|
|
|
|
531
|
|
|
// See if there are changes that affect children. |
|
532
|
|
|
$childUpdates = array(); |
|
533
|
|
|
$levelDiff = $child_level - $boards[$board_id]['level']; |
|
|
|
|
|
|
534
|
|
|
if ($levelDiff != 0) |
|
535
|
|
|
$childUpdates[] = 'child_level = child_level ' . ($levelDiff > 0 ? '+ ' : '') . '{int:level_diff}'; |
|
536
|
|
|
if ($id_cat != $boards[$board_id]['category']) |
|
|
|
|
|
|
537
|
|
|
$childUpdates[] = 'id_cat = {int:category}'; |
|
538
|
|
|
|
|
539
|
|
|
// Fix the children of this board. |
|
540
|
|
|
if (!empty($childList) && !empty($childUpdates)) |
|
541
|
|
|
$smcFunc['db_query']('', ' |
|
542
|
|
|
UPDATE {db_prefix}boards |
|
543
|
|
|
SET ' . implode(', |
|
544
|
|
|
', $childUpdates) . ' |
|
545
|
|
|
WHERE id_board IN ({array_int:board_list})', |
|
546
|
|
|
array( |
|
547
|
|
|
'board_list' => $childList, |
|
548
|
|
|
'category' => $id_cat, |
|
549
|
|
|
'level_diff' => $levelDiff, |
|
550
|
|
|
) |
|
551
|
|
|
); |
|
552
|
|
|
|
|
553
|
|
|
// Make some room for this spot. |
|
554
|
|
|
$smcFunc['db_query']('', ' |
|
555
|
|
|
UPDATE {db_prefix}boards |
|
556
|
|
|
SET board_order = board_order + {int:new_order} |
|
557
|
|
|
WHERE board_order > {int:insert_after} |
|
558
|
|
|
AND id_board != {int:selected_board}', |
|
559
|
|
|
array( |
|
560
|
|
|
'insert_after' => $after, |
|
|
|
|
|
|
561
|
|
|
'selected_board' => $board_id, |
|
562
|
|
|
'new_order' => 1 + count($childList), |
|
563
|
|
|
) |
|
564
|
|
|
); |
|
565
|
|
|
|
|
566
|
|
|
$boardUpdates[] = 'id_cat = {int:id_cat}'; |
|
567
|
|
|
$boardUpdates[] = 'id_parent = {int:id_parent}'; |
|
568
|
|
|
$boardUpdates[] = 'child_level = {int:child_level}'; |
|
569
|
|
|
$boardUpdates[] = 'board_order = {int:board_order}'; |
|
570
|
|
|
$boardUpdateParameters += array( |
|
571
|
|
|
'id_cat' => $id_cat, |
|
572
|
|
|
'id_parent' => $id_parent, |
|
|
|
|
|
|
573
|
|
|
'child_level' => $child_level, |
|
574
|
|
|
'board_order' => $after + 1, |
|
575
|
|
|
); |
|
576
|
|
|
} |
|
577
|
|
|
|
|
578
|
|
|
// This setting is a little twisted in the database... |
|
579
|
|
|
if (isset($boardOptions['posts_count'])) |
|
580
|
|
|
{ |
|
581
|
|
|
$boardUpdates[] = 'count_posts = {int:count_posts}'; |
|
582
|
|
|
$boardUpdateParameters['count_posts'] = $boardOptions['posts_count'] ? 0 : 1; |
|
583
|
|
|
} |
|
584
|
|
|
|
|
585
|
|
|
// Set the theme for this board. |
|
586
|
|
|
if (isset($boardOptions['board_theme'])) |
|
587
|
|
|
{ |
|
588
|
|
|
$boardUpdates[] = 'id_theme = {int:id_theme}'; |
|
589
|
|
|
$boardUpdateParameters['id_theme'] = (int) $boardOptions['board_theme']; |
|
590
|
|
|
} |
|
591
|
|
|
|
|
592
|
|
|
// Should the board theme override the user preferred theme? |
|
593
|
|
|
if (isset($boardOptions['override_theme'])) |
|
594
|
|
|
{ |
|
595
|
|
|
$boardUpdates[] = 'override_theme = {int:override_theme}'; |
|
596
|
|
|
$boardUpdateParameters['override_theme'] = $boardOptions['override_theme'] ? 1 : 0; |
|
597
|
|
|
} |
|
598
|
|
|
|
|
599
|
|
|
// Who's allowed to access this board. |
|
600
|
|
|
if (isset($boardOptions['access_groups'])) |
|
601
|
|
|
{ |
|
602
|
|
|
$boardUpdates[] = 'member_groups = {string:member_groups}'; |
|
603
|
|
|
$boardUpdateParameters['member_groups'] = implode(',', $boardOptions['access_groups']); |
|
604
|
|
|
} |
|
605
|
|
|
|
|
606
|
|
|
// And who isn't. |
|
607
|
|
View Code Duplication |
if (isset($boardOptions['deny_groups'])) |
|
|
|
|
|
|
608
|
|
|
{ |
|
609
|
|
|
$boardUpdates[] = 'deny_member_groups = {string:deny_groups}'; |
|
610
|
|
|
$boardUpdateParameters['deny_groups'] = implode(',', $boardOptions['deny_groups']); |
|
611
|
|
|
} |
|
612
|
|
|
|
|
613
|
|
|
if (isset($boardOptions['board_name'])) |
|
614
|
|
|
{ |
|
615
|
|
|
$boardUpdates[] = 'name = {string:board_name}'; |
|
616
|
|
|
$boardUpdateParameters['board_name'] = $boardOptions['board_name']; |
|
617
|
|
|
} |
|
618
|
|
|
|
|
619
|
|
|
if (isset($boardOptions['board_description'])) |
|
620
|
|
|
{ |
|
621
|
|
|
$boardUpdates[] = 'description = {string:board_description}'; |
|
622
|
|
|
$boardUpdateParameters['board_description'] = $boardOptions['board_description']; |
|
623
|
|
|
} |
|
624
|
|
|
|
|
625
|
|
|
if (isset($boardOptions['profile'])) |
|
626
|
|
|
{ |
|
627
|
|
|
$boardUpdates[] = 'id_profile = {int:profile}'; |
|
628
|
|
|
$boardUpdateParameters['profile'] = (int) $boardOptions['profile']; |
|
629
|
|
|
} |
|
630
|
|
|
|
|
631
|
|
View Code Duplication |
if (isset($boardOptions['redirect'])) |
|
|
|
|
|
|
632
|
|
|
{ |
|
633
|
|
|
$boardUpdates[] = 'redirect = {string:redirect}'; |
|
634
|
|
|
$boardUpdateParameters['redirect'] = $boardOptions['redirect']; |
|
635
|
|
|
} |
|
636
|
|
|
|
|
637
|
|
|
if (isset($boardOptions['num_posts'])) |
|
638
|
|
|
{ |
|
639
|
|
|
$boardUpdates[] = 'num_posts = {int:num_posts}'; |
|
640
|
|
|
$boardUpdateParameters['num_posts'] = (int) $boardOptions['num_posts']; |
|
641
|
|
|
} |
|
642
|
|
|
|
|
643
|
|
|
$id = $board_id; |
|
644
|
|
|
call_integration_hook('integrate_modify_board', array($id, $boardOptions, &$boardUpdates, &$boardUpdateParameters)); |
|
645
|
|
|
|
|
646
|
|
|
// Do the updates (if any). |
|
647
|
|
|
if (!empty($boardUpdates)) |
|
648
|
|
|
$smcFunc['db_query']('', ' |
|
649
|
|
|
UPDATE {db_prefix}boards |
|
650
|
|
|
SET |
|
651
|
|
|
' . implode(', |
|
652
|
|
|
', $boardUpdates) . ' |
|
653
|
|
|
WHERE id_board = {int:selected_board}', |
|
654
|
|
|
array_merge($boardUpdateParameters, array( |
|
655
|
|
|
'selected_board' => $board_id, |
|
656
|
|
|
)) |
|
657
|
|
|
); |
|
658
|
|
|
|
|
659
|
|
|
// Set moderators of this board. |
|
660
|
|
|
if (isset($boardOptions['moderators']) || isset($boardOptions['moderator_string']) || isset($boardOptions['moderator_groups']) || isset($boardOptions['moderator_group_string'])) |
|
661
|
|
|
{ |
|
662
|
|
|
// Reset current moderators for this board - if there are any! |
|
663
|
|
|
$smcFunc['db_query']('', ' |
|
664
|
|
|
DELETE FROM {db_prefix}moderators |
|
665
|
|
|
WHERE id_board = {int:board_list}', |
|
666
|
|
|
array( |
|
667
|
|
|
'board_list' => $board_id, |
|
668
|
|
|
) |
|
669
|
|
|
); |
|
670
|
|
|
|
|
671
|
|
|
// Validate and get the IDs of the new moderators. |
|
672
|
|
|
if (isset($boardOptions['moderator_string']) && trim($boardOptions['moderator_string']) != '') |
|
673
|
|
|
{ |
|
674
|
|
|
// Divvy out the usernames, remove extra space. |
|
675
|
|
|
$moderator_string = strtr($smcFunc['htmlspecialchars']($boardOptions['moderator_string'], ENT_QUOTES), array('"' => '"')); |
|
676
|
|
|
preg_match_all('~"([^"]+)"~', $moderator_string, $matches); |
|
677
|
|
|
$moderators = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_string))); |
|
678
|
|
View Code Duplication |
for ($k = 0, $n = count($moderators); $k < $n; $k++) |
|
|
|
|
|
|
679
|
|
|
{ |
|
680
|
|
|
$moderators[$k] = trim($moderators[$k]); |
|
681
|
|
|
|
|
682
|
|
|
if (strlen($moderators[$k]) == 0) |
|
683
|
|
|
unset($moderators[$k]); |
|
684
|
|
|
} |
|
685
|
|
|
|
|
686
|
|
|
// Find all the id_member's for the member_name's in the list. |
|
687
|
|
|
if (empty($boardOptions['moderators'])) |
|
688
|
|
|
$boardOptions['moderators'] = array(); |
|
689
|
|
|
if (!empty($moderators)) |
|
690
|
|
|
{ |
|
691
|
|
|
$request = $smcFunc['db_query']('', ' |
|
692
|
|
|
SELECT id_member |
|
693
|
|
|
FROM {db_prefix}members |
|
694
|
|
|
WHERE member_name IN ({array_string:moderator_list}) OR real_name IN ({array_string:moderator_list}) |
|
695
|
|
|
LIMIT {int:limit}', |
|
696
|
|
|
array( |
|
697
|
|
|
'moderator_list' => $moderators, |
|
698
|
|
|
'limit' => count($moderators), |
|
699
|
|
|
) |
|
700
|
|
|
); |
|
701
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
702
|
|
|
$boardOptions['moderators'][] = $row['id_member']; |
|
703
|
|
|
$smcFunc['db_free_result']($request); |
|
704
|
|
|
} |
|
705
|
|
|
} |
|
706
|
|
|
|
|
707
|
|
|
// Add the moderators to the board. |
|
708
|
|
|
if (!empty($boardOptions['moderators'])) |
|
709
|
|
|
{ |
|
710
|
|
|
$inserts = array(); |
|
711
|
|
|
foreach ($boardOptions['moderators'] as $moderator) |
|
712
|
|
|
$inserts[] = array($board_id, $moderator); |
|
713
|
|
|
|
|
714
|
|
|
$smcFunc['db_insert']('insert', |
|
715
|
|
|
'{db_prefix}moderators', |
|
716
|
|
|
array('id_board' => 'int', 'id_member' => 'int'), |
|
717
|
|
|
$inserts, |
|
718
|
|
|
array('id_board', 'id_member') |
|
719
|
|
|
); |
|
720
|
|
|
} |
|
721
|
|
|
|
|
722
|
|
|
// Reset current moderator groups for this board - if there are any! |
|
723
|
|
|
$smcFunc['db_query']('', ' |
|
724
|
|
|
DELETE FROM {db_prefix}moderator_groups |
|
725
|
|
|
WHERE id_board = {int:board_list}', |
|
726
|
|
|
array( |
|
727
|
|
|
'board_list' => $board_id, |
|
728
|
|
|
) |
|
729
|
|
|
); |
|
730
|
|
|
|
|
731
|
|
|
// Validate and get the IDs of the new moderator groups. |
|
732
|
|
|
if (isset($boardOptions['moderator_group_string']) && trim($boardOptions['moderator_group_string']) != '') |
|
733
|
|
|
{ |
|
734
|
|
|
// Divvy out the group names, remove extra space. |
|
735
|
|
|
$moderator_group_string = strtr($smcFunc['htmlspecialchars']($boardOptions['moderator_group_string'], ENT_QUOTES), array('"' => '"')); |
|
736
|
|
|
preg_match_all('~"([^"]+)"~', $moderator_group_string, $matches); |
|
737
|
|
|
$moderator_groups = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_group_string))); |
|
738
|
|
View Code Duplication |
for ($k = 0, $n = count($moderator_groups); $k < $n; $k++) |
|
|
|
|
|
|
739
|
|
|
{ |
|
740
|
|
|
$moderator_groups[$k] = trim($moderator_groups[$k]); |
|
741
|
|
|
|
|
742
|
|
|
if (strlen($moderator_groups[$k]) == 0) |
|
743
|
|
|
unset($moderator_groups[$k]); |
|
744
|
|
|
} |
|
745
|
|
|
|
|
746
|
|
|
/* Find all the id_group's for all the group names in the list |
|
747
|
|
|
But skip any invalid ones (invisible/post groups/Administrator/Moderator) */ |
|
748
|
|
|
if (empty($boardOptions['moderator_groups'])) |
|
749
|
|
|
$boardOptions['moderator_groups'] = array(); |
|
750
|
|
|
if (!empty($moderator_groups)) |
|
751
|
|
|
{ |
|
752
|
|
|
$request = $smcFunc['db_query']('', ' |
|
753
|
|
|
SELECT id_group |
|
754
|
|
|
FROM {db_prefix}membergroups |
|
755
|
|
|
WHERE group_name IN ({array_string:moderator_group_list}) |
|
756
|
|
|
AND hidden = {int:visible} |
|
757
|
|
|
AND min_posts = {int:negative_one} |
|
758
|
|
|
AND id_group NOT IN ({array_int:invalid_groups}) |
|
759
|
|
|
LIMIT {int:limit}', |
|
760
|
|
|
array( |
|
761
|
|
|
'visible' => 0, |
|
762
|
|
|
'negative_one' => -1, |
|
763
|
|
|
'invalid_groups' => array(1, 3), |
|
764
|
|
|
'moderator_group_list' => $moderator_groups, |
|
765
|
|
|
'limit' => count($moderator_groups), |
|
766
|
|
|
) |
|
767
|
|
|
); |
|
768
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
769
|
|
|
{ |
|
770
|
|
|
$boardOptions['moderator_groups'][] = $row['id_group']; |
|
771
|
|
|
} |
|
772
|
|
|
$smcFunc['db_free_result']($request); |
|
773
|
|
|
} |
|
774
|
|
|
} |
|
775
|
|
|
|
|
776
|
|
|
// Add the moderator groups to the board. |
|
777
|
|
|
if (!empty($boardOptions['moderator_groups'])) |
|
778
|
|
|
{ |
|
779
|
|
|
$inserts = array(); |
|
780
|
|
|
foreach ($boardOptions['moderator_groups'] as $moderator_group) |
|
781
|
|
|
$inserts[] = array($board_id, $moderator_group); |
|
782
|
|
|
|
|
783
|
|
|
$smcFunc['db_insert']('insert', |
|
784
|
|
|
'{db_prefix}moderator_groups', |
|
785
|
|
|
array('id_board' => 'int', 'id_group' => 'int'), |
|
786
|
|
|
$inserts, |
|
787
|
|
|
array('id_board', 'id_group') |
|
788
|
|
|
); |
|
789
|
|
|
} |
|
790
|
|
|
|
|
791
|
|
|
// Note that caches can now be wrong! |
|
792
|
|
|
updateSettings(array('settings_updated' => time())); |
|
793
|
|
|
} |
|
794
|
|
|
|
|
795
|
|
|
if (isset($boardOptions['move_to'])) |
|
796
|
|
|
reorderBoards(); |
|
797
|
|
|
|
|
798
|
|
|
clean_cache('data'); |
|
799
|
|
|
|
|
800
|
|
|
if (empty($boardOptions['dont_log'])) |
|
801
|
|
|
logAction('edit_board', array('board' => $board_id), 'admin'); |
|
802
|
|
|
} |
|
803
|
|
|
|
|
804
|
|
|
/** |
|
805
|
|
|
* Create a new board and set its properties and position. |
|
806
|
|
|
* Allows (almost) the same options as the modifyBoard() function. |
|
807
|
|
|
* With the option inherit_permissions set, the parent board permissions |
|
808
|
|
|
* will be inherited. |
|
809
|
|
|
* |
|
810
|
|
|
* @param array $boardOptions An array of information for the new board |
|
811
|
|
|
* @return int The ID of the new board |
|
812
|
|
|
*/ |
|
813
|
|
|
function createBoard($boardOptions) |
|
814
|
|
|
{ |
|
815
|
|
|
global $boards, $smcFunc; |
|
816
|
|
|
|
|
817
|
|
|
// Trigger an error if one of the required values is not set. |
|
818
|
|
|
if (!isset($boardOptions['board_name']) || trim($boardOptions['board_name']) == '' || !isset($boardOptions['move_to']) || !isset($boardOptions['target_category'])) |
|
819
|
|
|
trigger_error('createBoard(): One or more of the required options is not set', E_USER_ERROR); |
|
820
|
|
|
|
|
821
|
|
|
if (in_array($boardOptions['move_to'], array('child', 'before', 'after')) && !isset($boardOptions['target_board'])) |
|
822
|
|
|
trigger_error('createBoard(): Target board is not set', E_USER_ERROR); |
|
823
|
|
|
|
|
824
|
|
|
// Set every optional value to its default value. |
|
825
|
|
|
$boardOptions += array( |
|
826
|
|
|
'posts_count' => true, |
|
827
|
|
|
'override_theme' => false, |
|
828
|
|
|
'board_theme' => 0, |
|
829
|
|
|
'access_groups' => array(), |
|
830
|
|
|
'board_description' => '', |
|
831
|
|
|
'profile' => 1, |
|
832
|
|
|
'moderators' => '', |
|
833
|
|
|
'inherit_permissions' => true, |
|
834
|
|
|
'dont_log' => true, |
|
835
|
|
|
); |
|
836
|
|
|
$board_columns = array( |
|
837
|
|
|
'id_cat' => 'int', 'name' => 'string-255', 'description' => 'string', 'board_order' => 'int', |
|
838
|
|
|
'member_groups' => 'string', 'redirect' => 'string', |
|
839
|
|
|
); |
|
840
|
|
|
$board_parameters = array( |
|
841
|
|
|
$boardOptions['target_category'], $boardOptions['board_name'], '', 0, |
|
842
|
|
|
'-1,0', '', |
|
843
|
|
|
); |
|
844
|
|
|
|
|
845
|
|
|
call_integration_hook('integrate_create_board', array(&$boardOptions, &$board_columns, &$board_parameters)); |
|
846
|
|
|
|
|
847
|
|
|
// Insert a board, the settings are dealt with later. |
|
848
|
|
|
$board_id = $smcFunc['db_insert']('', |
|
849
|
|
|
'{db_prefix}boards', |
|
850
|
|
|
$board_columns, |
|
851
|
|
|
$board_parameters, |
|
852
|
|
|
array('id_board'), |
|
853
|
|
|
1 |
|
854
|
|
|
); |
|
855
|
|
|
|
|
856
|
|
|
if (empty($board_id)) |
|
857
|
|
|
return 0; |
|
858
|
|
|
|
|
859
|
|
|
// Change the board according to the given specifications. |
|
860
|
|
|
modifyBoard($board_id, $boardOptions); |
|
861
|
|
|
|
|
862
|
|
|
// Do we want the parent permissions to be inherited? |
|
863
|
|
|
if ($boardOptions['inherit_permissions']) |
|
864
|
|
|
{ |
|
865
|
|
|
getBoardTree(); |
|
866
|
|
|
|
|
867
|
|
|
if (!empty($boards[$board_id]['parent'])) |
|
868
|
|
|
{ |
|
869
|
|
|
$request = $smcFunc['db_query']('', ' |
|
870
|
|
|
SELECT id_profile |
|
871
|
|
|
FROM {db_prefix}boards |
|
872
|
|
|
WHERE id_board = {int:board_parent} |
|
873
|
|
|
LIMIT 1', |
|
874
|
|
|
array( |
|
875
|
|
|
'board_parent' => (int) $boards[$board_id]['parent'], |
|
876
|
|
|
) |
|
877
|
|
|
); |
|
878
|
|
|
list ($boardOptions['profile']) = $smcFunc['db_fetch_row']($request); |
|
879
|
|
|
$smcFunc['db_free_result']($request); |
|
880
|
|
|
|
|
881
|
|
|
$smcFunc['db_query']('', ' |
|
882
|
|
|
UPDATE {db_prefix}boards |
|
883
|
|
|
SET id_profile = {int:new_profile} |
|
884
|
|
|
WHERE id_board = {int:current_board}', |
|
885
|
|
|
array( |
|
886
|
|
|
'new_profile' => $boardOptions['profile'], |
|
887
|
|
|
'current_board' => $board_id, |
|
888
|
|
|
) |
|
889
|
|
|
); |
|
890
|
|
|
} |
|
891
|
|
|
} |
|
892
|
|
|
|
|
893
|
|
|
// Clean the data cache. |
|
894
|
|
|
clean_cache('data'); |
|
895
|
|
|
|
|
896
|
|
|
// Created it. |
|
897
|
|
|
logAction('add_board', array('board' => $board_id), 'admin'); |
|
898
|
|
|
|
|
899
|
|
|
// Here you are, a new board, ready to be spammed. |
|
900
|
|
|
return $board_id; |
|
901
|
|
|
} |
|
902
|
|
|
|
|
903
|
|
|
/** |
|
904
|
|
|
* Remove one or more boards. |
|
905
|
|
|
* Allows to move the children of the board before deleting it |
|
906
|
|
|
* if moveChildrenTo is set to null, the child boards will be deleted. |
|
907
|
|
|
* Deletes: |
|
908
|
|
|
* - all topics that are on the given boards; |
|
909
|
|
|
* - all information that's associated with the given boards; |
|
910
|
|
|
* updates the statistics to reflect the new situation. |
|
911
|
|
|
* |
|
912
|
|
|
* @param array $boards_to_remove The boards to remove |
|
913
|
|
|
* @param int $moveChildrenTo The ID of the board to move the child boards to (null to remove the child boards, 0 to make them a top-level board) |
|
914
|
|
|
*/ |
|
915
|
|
|
function deleteBoards($boards_to_remove, $moveChildrenTo = null) |
|
916
|
|
|
{ |
|
917
|
|
|
global $sourcedir, $boards, $smcFunc; |
|
918
|
|
|
|
|
919
|
|
|
// No boards to delete? Return! |
|
920
|
|
|
if (empty($boards_to_remove)) |
|
921
|
|
|
return; |
|
922
|
|
|
|
|
923
|
|
|
getBoardTree(); |
|
924
|
|
|
|
|
925
|
|
|
call_integration_hook('integrate_delete_board', array($boards_to_remove, &$moveChildrenTo)); |
|
926
|
|
|
|
|
927
|
|
|
// If $moveChildrenTo is set to null, include the children in the removal. |
|
928
|
|
|
if ($moveChildrenTo === null) |
|
929
|
|
|
{ |
|
930
|
|
|
// Get a list of the child boards that will also be removed. |
|
931
|
|
|
$child_boards_to_remove = array(); |
|
932
|
|
|
foreach ($boards_to_remove as $board_to_remove) |
|
933
|
|
|
recursiveBoards($child_boards_to_remove, $boards[$board_to_remove]['tree']); |
|
934
|
|
|
|
|
935
|
|
|
// Merge the children with their parents. |
|
936
|
|
|
if (!empty($child_boards_to_remove)) |
|
937
|
|
|
$boards_to_remove = array_unique(array_merge($boards_to_remove, $child_boards_to_remove)); |
|
938
|
|
|
} |
|
939
|
|
|
// Move the children to a safe home. |
|
940
|
|
|
else |
|
941
|
|
|
{ |
|
942
|
|
|
foreach ($boards_to_remove as $id_board) |
|
943
|
|
|
{ |
|
944
|
|
|
// @todo Separate category? |
|
945
|
|
|
if ($moveChildrenTo === 0) |
|
946
|
|
|
fixChildren($id_board, 0, 0); |
|
947
|
|
|
else |
|
948
|
|
|
fixChildren($id_board, $boards[$moveChildrenTo]['level'] + 1, $moveChildrenTo); |
|
949
|
|
|
} |
|
950
|
|
|
} |
|
951
|
|
|
|
|
952
|
|
|
// Delete ALL topics in the selected boards (done first so topics can't be marooned.) |
|
953
|
|
|
$request = $smcFunc['db_query']('', ' |
|
954
|
|
|
SELECT id_topic |
|
955
|
|
|
FROM {db_prefix}topics |
|
956
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
957
|
|
|
array( |
|
958
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
959
|
|
|
) |
|
960
|
|
|
); |
|
961
|
|
|
$topics = array(); |
|
962
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
963
|
|
|
$topics[] = $row['id_topic']; |
|
964
|
|
|
$smcFunc['db_free_result']($request); |
|
965
|
|
|
|
|
966
|
|
|
require_once($sourcedir . '/RemoveTopic.php'); |
|
967
|
|
|
removeTopics($topics, false); |
|
968
|
|
|
|
|
969
|
|
|
// Delete the board's logs. |
|
970
|
|
|
$smcFunc['db_query']('', ' |
|
971
|
|
|
DELETE FROM {db_prefix}log_mark_read |
|
972
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
973
|
|
|
array( |
|
974
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
975
|
|
|
) |
|
976
|
|
|
); |
|
977
|
|
|
$smcFunc['db_query']('', ' |
|
978
|
|
|
DELETE FROM {db_prefix}log_boards |
|
979
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
980
|
|
|
array( |
|
981
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
982
|
|
|
) |
|
983
|
|
|
); |
|
984
|
|
|
$smcFunc['db_query']('', ' |
|
985
|
|
|
DELETE FROM {db_prefix}log_notify |
|
986
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
987
|
|
|
array( |
|
988
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
989
|
|
|
) |
|
990
|
|
|
); |
|
991
|
|
|
|
|
992
|
|
|
// Delete this board's moderators. |
|
993
|
|
|
$smcFunc['db_query']('', ' |
|
994
|
|
|
DELETE FROM {db_prefix}moderators |
|
995
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
996
|
|
|
array( |
|
997
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
998
|
|
|
) |
|
999
|
|
|
); |
|
1000
|
|
|
|
|
1001
|
|
|
// Delete this board's moderator groups. |
|
1002
|
|
|
$smcFunc['db_query']('', ' |
|
1003
|
|
|
DELETE FROM {db_prefix}moderator_groups |
|
1004
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
1005
|
|
|
array( |
|
1006
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
1007
|
|
|
) |
|
1008
|
|
|
); |
|
1009
|
|
|
|
|
1010
|
|
|
// Delete any extra events in the calendar. |
|
1011
|
|
|
$smcFunc['db_query']('', ' |
|
1012
|
|
|
DELETE FROM {db_prefix}calendar |
|
1013
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
1014
|
|
|
array( |
|
1015
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
1016
|
|
|
) |
|
1017
|
|
|
); |
|
1018
|
|
|
|
|
1019
|
|
|
// Delete any message icons that only appear on these boards. |
|
1020
|
|
|
$smcFunc['db_query']('', ' |
|
1021
|
|
|
DELETE FROM {db_prefix}message_icons |
|
1022
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
1023
|
|
|
array( |
|
1024
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
1025
|
|
|
) |
|
1026
|
|
|
); |
|
1027
|
|
|
|
|
1028
|
|
|
// Delete the boards. |
|
1029
|
|
|
$smcFunc['db_query']('', ' |
|
1030
|
|
|
DELETE FROM {db_prefix}boards |
|
1031
|
|
|
WHERE id_board IN ({array_int:boards_to_remove})', |
|
1032
|
|
|
array( |
|
1033
|
|
|
'boards_to_remove' => $boards_to_remove, |
|
1034
|
|
|
) |
|
1035
|
|
|
); |
|
1036
|
|
|
|
|
1037
|
|
|
// Latest message/topic might not be there anymore. |
|
1038
|
|
|
updateStats('message'); |
|
1039
|
|
|
updateStats('topic'); |
|
1040
|
|
|
updateSettings(array( |
|
1041
|
|
|
'calendar_updated' => time(), |
|
1042
|
|
|
)); |
|
1043
|
|
|
|
|
1044
|
|
|
// Plus reset the cache to stop people getting odd results. |
|
1045
|
|
|
updateSettings(array('settings_updated' => time())); |
|
1046
|
|
|
|
|
1047
|
|
|
// Clean the cache as well. |
|
1048
|
|
|
clean_cache('data'); |
|
1049
|
|
|
|
|
1050
|
|
|
// Let's do some serious logging. |
|
1051
|
|
|
foreach ($boards_to_remove as $id_board) |
|
1052
|
|
|
logAction('delete_board', array('boardname' => $boards[$id_board]['name']), 'admin'); |
|
1053
|
|
|
|
|
1054
|
|
|
reorderBoards(); |
|
1055
|
|
|
} |
|
1056
|
|
|
|
|
1057
|
|
|
/** |
|
1058
|
|
|
* Put all boards in the right order and sorts the records of the boards table. |
|
1059
|
|
|
* Used by modifyBoard(), deleteBoards(), modifyCategory(), and deleteCategories() functions |
|
1060
|
|
|
*/ |
|
1061
|
|
|
function reorderBoards() |
|
1062
|
|
|
{ |
|
1063
|
|
|
global $cat_tree, $boardList, $boards, $smcFunc; |
|
1064
|
|
|
|
|
1065
|
|
|
getBoardTree(); |
|
1066
|
|
|
|
|
1067
|
|
|
// Set the board order for each category. |
|
1068
|
|
|
$board_order = 0; |
|
1069
|
|
|
foreach ($cat_tree as $catID => $dummy) |
|
1070
|
|
|
{ |
|
1071
|
|
|
foreach ($boardList[$catID] as $boardID) |
|
1072
|
|
|
if ($boards[$boardID]['order'] != ++$board_order) |
|
1073
|
|
|
$smcFunc['db_query']('', ' |
|
1074
|
|
|
UPDATE {db_prefix}boards |
|
1075
|
|
|
SET board_order = {int:new_order} |
|
1076
|
|
|
WHERE id_board = {int:selected_board}', |
|
1077
|
|
|
array( |
|
1078
|
|
|
'new_order' => $board_order, |
|
1079
|
|
|
'selected_board' => $boardID, |
|
1080
|
|
|
) |
|
1081
|
|
|
); |
|
1082
|
|
|
} |
|
1083
|
|
|
|
|
1084
|
|
|
// Empty the board order cache |
|
1085
|
|
|
cache_put_data('board_order', null, -3600); |
|
1086
|
|
|
} |
|
1087
|
|
|
|
|
1088
|
|
|
/** |
|
1089
|
|
|
* Fixes the children of a board by setting their child_levels to new values. |
|
1090
|
|
|
* Used when a board is deleted or moved, to affect its children. |
|
1091
|
|
|
* |
|
1092
|
|
|
* @param int $parent The ID of the parent board |
|
1093
|
|
|
* @param int $newLevel The new child level for each of the child boards |
|
1094
|
|
|
* @param int $newParent The ID of the new parent board |
|
1095
|
|
|
*/ |
|
1096
|
|
|
function fixChildren($parent, $newLevel, $newParent) |
|
1097
|
|
|
{ |
|
1098
|
|
|
global $smcFunc; |
|
1099
|
|
|
|
|
1100
|
|
|
// Grab all children of $parent... |
|
1101
|
|
|
$result = $smcFunc['db_query']('', ' |
|
1102
|
|
|
SELECT id_board |
|
1103
|
|
|
FROM {db_prefix}boards |
|
1104
|
|
|
WHERE id_parent = {int:parent_board}', |
|
1105
|
|
|
array( |
|
1106
|
|
|
'parent_board' => $parent, |
|
1107
|
|
|
) |
|
1108
|
|
|
); |
|
1109
|
|
|
$children = array(); |
|
1110
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result)) |
|
1111
|
|
|
$children[] = $row['id_board']; |
|
1112
|
|
|
$smcFunc['db_free_result']($result); |
|
1113
|
|
|
|
|
1114
|
|
|
// ...and set it to a new parent and child_level. |
|
1115
|
|
|
$smcFunc['db_query']('', ' |
|
1116
|
|
|
UPDATE {db_prefix}boards |
|
1117
|
|
|
SET id_parent = {int:new_parent}, child_level = {int:new_child_level} |
|
1118
|
|
|
WHERE id_parent = {int:parent_board}', |
|
1119
|
|
|
array( |
|
1120
|
|
|
'new_parent' => $newParent, |
|
1121
|
|
|
'new_child_level' => $newLevel, |
|
1122
|
|
|
'parent_board' => $parent, |
|
1123
|
|
|
) |
|
1124
|
|
|
); |
|
1125
|
|
|
|
|
1126
|
|
|
// Recursively fix the children of the children. |
|
1127
|
|
|
foreach ($children as $child) |
|
1128
|
|
|
fixChildren($child, $newLevel + 1, $child); |
|
1129
|
|
|
} |
|
1130
|
|
|
|
|
1131
|
|
|
/** |
|
1132
|
|
|
* Tries to load up the entire board order and category very very quickly |
|
1133
|
|
|
* Returns an array with two elements, cats and boards |
|
1134
|
|
|
* |
|
1135
|
|
|
* @return array An array of categories and boards |
|
1136
|
|
|
*/ |
|
1137
|
|
|
function getTreeOrder() |
|
1138
|
|
|
{ |
|
1139
|
|
|
global $smcFunc; |
|
1140
|
|
|
|
|
1141
|
|
|
static $tree_order = array( |
|
1142
|
|
|
'cats' => array(), |
|
1143
|
|
|
'boards' => array(), |
|
1144
|
|
|
); |
|
1145
|
|
|
|
|
1146
|
|
|
if (!empty($tree_order['boards'])) |
|
1147
|
|
|
return $tree_order; |
|
1148
|
|
|
|
|
1149
|
|
|
if (($cached = cache_get_data('board_order', 86400)) !== null) |
|
1150
|
|
|
{ |
|
1151
|
|
|
$tree_order = $cached; |
|
1152
|
|
|
return $cached; |
|
1153
|
|
|
} |
|
1154
|
|
|
|
|
1155
|
|
|
$request = $smcFunc['db_query']('', ' |
|
1156
|
|
|
SELECT b.id_board, b.id_cat |
|
1157
|
|
|
FROM {db_prefix}boards AS b |
|
1158
|
|
|
ORDER BY b.board_order', |
|
1159
|
|
|
array() |
|
1160
|
|
|
); |
|
1161
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
1162
|
|
|
{ |
|
1163
|
|
|
if (!in_array($row['id_cat'], $tree_order['cats'])) |
|
1164
|
|
|
$tree_order['cats'][] = $row['id_cat']; |
|
1165
|
|
|
$tree_order['boards'][] = $row['id_board']; |
|
1166
|
|
|
} |
|
1167
|
|
|
$smcFunc['db_free_result']($request); |
|
1168
|
|
|
|
|
1169
|
|
|
cache_put_data('board_order', $tree_order, 86400); |
|
1170
|
|
|
|
|
1171
|
|
|
return $tree_order; |
|
1172
|
|
|
} |
|
1173
|
|
|
|
|
1174
|
|
|
/** |
|
1175
|
|
|
* Takes a board array and sorts it |
|
1176
|
|
|
* |
|
1177
|
|
|
* @param array &$boards The boards |
|
1178
|
|
|
*/ |
|
1179
|
|
|
function sortBoards(array &$boards) |
|
1180
|
|
|
{ |
|
1181
|
|
|
$tree = getTreeOrder(); |
|
1182
|
|
|
|
|
1183
|
|
|
$ordered = array(); |
|
1184
|
|
|
foreach ($tree['boards'] as $board) |
|
1185
|
|
|
if (!empty($boards[$board])) |
|
1186
|
|
|
{ |
|
1187
|
|
|
$ordered[$board] = $boards[$board]; |
|
1188
|
|
|
|
|
1189
|
|
View Code Duplication |
if (is_array($ordered[$board]) && !empty($ordered[$board]['boards'])) |
|
|
|
|
|
|
1190
|
|
|
sortBoards($ordered[$board]['boards']); |
|
1191
|
|
|
|
|
1192
|
|
View Code Duplication |
if (is_array($ordered[$board]) && !empty($ordered[$board]['children'])) |
|
|
|
|
|
|
1193
|
|
|
sortBoards($ordered[$board]['children']); |
|
1194
|
|
|
} |
|
1195
|
|
|
|
|
1196
|
|
|
$boards = $ordered; |
|
1197
|
|
|
} |
|
1198
|
|
|
|
|
1199
|
|
|
/** |
|
1200
|
|
|
* Takes a category array and sorts it |
|
1201
|
|
|
* |
|
1202
|
|
|
* @param array &$categories The categories |
|
1203
|
|
|
*/ |
|
1204
|
|
|
function sortCategories(array &$categories) |
|
1205
|
|
|
{ |
|
1206
|
|
|
$tree = getTreeOrder(); |
|
1207
|
|
|
|
|
1208
|
|
|
$ordered = array(); |
|
1209
|
|
|
foreach ($tree['cats'] as $cat) |
|
1210
|
|
|
if (!empty($categories[$cat])) |
|
1211
|
|
|
{ |
|
1212
|
|
|
$ordered[$cat] = $categories[$cat]; |
|
1213
|
|
|
if (!empty($ordered[$cat]['boards'])) |
|
1214
|
|
|
sortBoards($ordered[$cat]['boards']); |
|
1215
|
|
|
} |
|
1216
|
|
|
|
|
1217
|
|
|
$categories = $ordered; |
|
1218
|
|
|
} |
|
1219
|
|
|
|
|
1220
|
|
|
/** |
|
1221
|
|
|
* Returns the given board's moderators, with their names and links |
|
1222
|
|
|
* |
|
1223
|
|
|
* @param array $boards The boards to get moderators of |
|
1224
|
|
|
* @return array An array containing information about the moderators of each board |
|
1225
|
|
|
*/ |
|
1226
|
|
View Code Duplication |
function getBoardModerators(array $boards) |
|
|
|
|
|
|
1227
|
|
|
{ |
|
1228
|
|
|
global $smcFunc, $scripturl, $txt; |
|
1229
|
|
|
|
|
1230
|
|
|
if (empty($boards)) |
|
1231
|
|
|
return array(); |
|
1232
|
|
|
|
|
1233
|
|
|
$request = $smcFunc['db_query']('', ' |
|
1234
|
|
|
SELECT mem.id_member, mem.real_name, mo.id_board |
|
1235
|
|
|
FROM {db_prefix}moderators AS mo |
|
1236
|
|
|
INNER JOIN {db_prefix}members AS mem ON (mem.id_member = mo.id_member) |
|
1237
|
|
|
WHERE mo.id_board IN ({array_int:boards})', |
|
1238
|
|
|
array( |
|
1239
|
|
|
'boards' => $boards, |
|
1240
|
|
|
) |
|
1241
|
|
|
); |
|
1242
|
|
|
$moderators = array(); |
|
1243
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
1244
|
|
|
{ |
|
1245
|
|
|
if (empty($moderators[$row['id_board']])) |
|
1246
|
|
|
$moderators[$row['id_board']] = array(); |
|
1247
|
|
|
|
|
1248
|
|
|
$moderators[$row['id_board']][] = array( |
|
1249
|
|
|
'id' => $row['id_member'], |
|
1250
|
|
|
'name' => $row['real_name'], |
|
1251
|
|
|
'href' => $scripturl . '?action=profile;u=' . $row['id_member'], |
|
1252
|
|
|
'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" title="' . $txt['board_moderator'] . '">' . $row['real_name'] . '</a>', |
|
1253
|
|
|
); |
|
1254
|
|
|
} |
|
1255
|
|
|
$smcFunc['db_free_result']($request); |
|
1256
|
|
|
|
|
1257
|
|
|
return $moderators; |
|
1258
|
|
|
} |
|
1259
|
|
|
|
|
1260
|
|
|
/** |
|
1261
|
|
|
* Returns board's moderator groups with their names and link |
|
1262
|
|
|
* |
|
1263
|
|
|
* @param array $boards The boards to get moderator groups of |
|
1264
|
|
|
* @return array An array containing information about the groups assigned to moderate each board |
|
1265
|
|
|
*/ |
|
1266
|
|
View Code Duplication |
function getBoardModeratorGroups(array $boards) |
|
|
|
|
|
|
1267
|
|
|
{ |
|
1268
|
|
|
global $smcFunc, $scripturl, $txt; |
|
1269
|
|
|
|
|
1270
|
|
|
if (empty($boards)) |
|
1271
|
|
|
return array(); |
|
1272
|
|
|
|
|
1273
|
|
|
$request = $smcFunc['db_query']('', ' |
|
1274
|
|
|
SELECT mg.id_group, mg.group_name, bg.id_board |
|
1275
|
|
|
FROM {db_prefix}moderator_groups AS bg |
|
1276
|
|
|
INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = bg.id_group) |
|
1277
|
|
|
WHERE bg.id_board IN ({array_int:boards})', |
|
1278
|
|
|
array( |
|
1279
|
|
|
'boards' => $boards, |
|
1280
|
|
|
) |
|
1281
|
|
|
); |
|
1282
|
|
|
$groups = array(); |
|
1283
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
1284
|
|
|
{ |
|
1285
|
|
|
if (empty($groups[$row['id_board']])) |
|
1286
|
|
|
$groups[$row['id_board']] = array(); |
|
1287
|
|
|
|
|
1288
|
|
|
$groups[$row['id_board']][] = array( |
|
1289
|
|
|
'id' => $row['id_group'], |
|
1290
|
|
|
'name' => $row['group_name'], |
|
1291
|
|
|
'href' => $scripturl . '?action=groups;sa=members;group=' . $row['id_group'], |
|
1292
|
|
|
'link' => '<a href="' . $scripturl . '?action=groups;sa=members;group=' . $row['id_group'] . '" title="' . $txt['board_moderator'] . '">' . $row['group_name'] . '</a>', |
|
1293
|
|
|
); |
|
1294
|
|
|
} |
|
1295
|
|
|
|
|
1296
|
|
|
return $groups; |
|
1297
|
|
|
} |
|
1298
|
|
|
|
|
1299
|
|
|
/** |
|
1300
|
|
|
* Load a lot of useful information regarding the boards and categories. |
|
1301
|
|
|
* The information retrieved is stored in globals: |
|
1302
|
|
|
* $boards properties of each board. |
|
1303
|
|
|
* $boardList a list of boards grouped by category ID. |
|
1304
|
|
|
* $cat_tree properties of each category. |
|
1305
|
|
|
*/ |
|
1306
|
|
|
function getBoardTree() |
|
1307
|
|
|
{ |
|
1308
|
|
|
global $cat_tree, $boards, $boardList, $smcFunc; |
|
1309
|
|
|
|
|
1310
|
|
|
$boardColumns = array( |
|
1311
|
|
|
'COALESCE(b.id_board, 0) AS id_board', 'b.id_parent', 'b.name AS board_name', |
|
1312
|
|
|
'b.description', 'b.child_level', 'b.board_order', 'b.count_posts', 'b.member_groups', |
|
1313
|
|
|
'b.id_theme', 'b.override_theme', 'b.id_profile', 'b.redirect', 'b.num_posts', |
|
1314
|
|
|
'b.num_topics', 'b.deny_member_groups', 'c.id_cat', 'c.name AS cat_name', |
|
1315
|
|
|
'c.description AS cat_desc', 'c.cat_order', 'c.can_collapse', |
|
1316
|
|
|
); |
|
1317
|
|
|
|
|
1318
|
|
|
// Let mods add extra columns and parameters to the SELECT query |
|
1319
|
|
|
$extraBoardColumns = array(); |
|
1320
|
|
|
$extraBoardParameters = array(); |
|
1321
|
|
|
call_integration_hook('integrate_pre_boardtree', array(&$extraBoardColumns, &$extraBoardParameters)); |
|
1322
|
|
|
|
|
1323
|
|
|
$boardColumns = array_unique(array_merge($boardColumns, $extraBoardColumns)); |
|
1324
|
|
|
$boardParameters = array_unique($extraBoardParameters); |
|
1325
|
|
|
|
|
1326
|
|
|
// Getting all the board and category information you'd ever wanted. |
|
1327
|
|
|
$request = $smcFunc['db_query']('', ' |
|
1328
|
|
|
SELECT |
|
1329
|
|
|
' . implode(', ', $boardColumns) . ' |
|
1330
|
|
|
FROM {db_prefix}categories AS c |
|
1331
|
|
|
LEFT JOIN {db_prefix}boards AS b ON (b.id_cat = c.id_cat) |
|
1332
|
|
|
WHERE {query_see_board} |
|
1333
|
|
|
ORDER BY c.cat_order, b.child_level, b.board_order', |
|
1334
|
|
|
$boardParameters |
|
1335
|
|
|
); |
|
1336
|
|
|
$cat_tree = array(); |
|
1337
|
|
|
$boards = array(); |
|
1338
|
|
|
$last_board_order = 0; |
|
1339
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
1340
|
|
|
{ |
|
1341
|
|
|
if (!isset($cat_tree[$row['id_cat']])) |
|
1342
|
|
|
{ |
|
1343
|
|
|
$cat_tree[$row['id_cat']] = array( |
|
1344
|
|
|
'node' => array( |
|
1345
|
|
|
'id' => $row['id_cat'], |
|
1346
|
|
|
'name' => $row['cat_name'], |
|
1347
|
|
|
'description' => $row['cat_desc'], |
|
1348
|
|
|
'order' => $row['cat_order'], |
|
1349
|
|
|
'can_collapse' => $row['can_collapse'] |
|
1350
|
|
|
), |
|
1351
|
|
|
'is_first' => empty($cat_tree), |
|
1352
|
|
|
'last_board_order' => $last_board_order, |
|
1353
|
|
|
'children' => array() |
|
1354
|
|
|
); |
|
1355
|
|
|
$prevBoard = 0; |
|
1356
|
|
|
$curLevel = 0; |
|
1357
|
|
|
} |
|
1358
|
|
|
|
|
1359
|
|
|
if (!empty($row['id_board'])) |
|
1360
|
|
|
{ |
|
1361
|
|
|
if ($row['child_level'] != $curLevel) |
|
|
|
|
|
|
1362
|
|
|
$prevBoard = 0; |
|
1363
|
|
|
|
|
1364
|
|
|
$boards[$row['id_board']] = array( |
|
1365
|
|
|
'id' => $row['id_board'], |
|
1366
|
|
|
'category' => $row['id_cat'], |
|
1367
|
|
|
'parent' => $row['id_parent'], |
|
1368
|
|
|
'level' => $row['child_level'], |
|
1369
|
|
|
'order' => $row['board_order'], |
|
1370
|
|
|
'name' => $row['board_name'], |
|
1371
|
|
|
'member_groups' => explode(',', $row['member_groups']), |
|
1372
|
|
|
'deny_groups' => explode(',', $row['deny_member_groups']), |
|
1373
|
|
|
'description' => $row['description'], |
|
1374
|
|
|
'count_posts' => empty($row['count_posts']), |
|
1375
|
|
|
'posts' => $row['num_posts'], |
|
1376
|
|
|
'topics' => $row['num_topics'], |
|
1377
|
|
|
'theme' => $row['id_theme'], |
|
1378
|
|
|
'override_theme' => $row['override_theme'], |
|
1379
|
|
|
'profile' => $row['id_profile'], |
|
1380
|
|
|
'redirect' => $row['redirect'], |
|
1381
|
|
|
'prev_board' => $prevBoard |
|
|
|
|
|
|
1382
|
|
|
); |
|
1383
|
|
|
$prevBoard = $row['id_board']; |
|
1384
|
|
|
$last_board_order = $row['board_order']; |
|
1385
|
|
|
|
|
1386
|
|
|
if (empty($row['child_level'])) |
|
1387
|
|
|
{ |
|
1388
|
|
|
$cat_tree[$row['id_cat']]['children'][$row['id_board']] = array( |
|
1389
|
|
|
'node' => &$boards[$row['id_board']], |
|
1390
|
|
|
'is_first' => empty($cat_tree[$row['id_cat']]['children']), |
|
1391
|
|
|
'children' => array() |
|
1392
|
|
|
); |
|
1393
|
|
|
$boards[$row['id_board']]['tree'] = &$cat_tree[$row['id_cat']]['children'][$row['id_board']]; |
|
1394
|
|
|
} |
|
1395
|
|
|
else |
|
1396
|
|
|
{ |
|
1397
|
|
|
// Parent doesn't exist! |
|
1398
|
|
|
if (!isset($boards[$row['id_parent']]['tree'])) |
|
1399
|
|
|
fatal_lang_error('no_valid_parent', false, array($row['board_name'])); |
|
1400
|
|
|
|
|
1401
|
|
|
// Wrong childlevel...we can silently fix this... |
|
1402
|
|
|
if ($boards[$row['id_parent']]['tree']['node']['level'] != $row['child_level'] - 1) |
|
1403
|
|
|
$smcFunc['db_query']('', ' |
|
1404
|
|
|
UPDATE {db_prefix}boards |
|
1405
|
|
|
SET child_level = {int:new_child_level} |
|
1406
|
|
|
WHERE id_board = {int:selected_board}', |
|
1407
|
|
|
array( |
|
1408
|
|
|
'new_child_level' => $boards[$row['id_parent']]['tree']['node']['level'] + 1, |
|
1409
|
|
|
'selected_board' => $row['id_board'], |
|
1410
|
|
|
) |
|
1411
|
|
|
); |
|
1412
|
|
|
|
|
1413
|
|
|
$boards[$row['id_parent']]['tree']['children'][$row['id_board']] = array( |
|
1414
|
|
|
'node' => &$boards[$row['id_board']], |
|
1415
|
|
|
'is_first' => empty($boards[$row['id_parent']]['tree']['children']), |
|
1416
|
|
|
'children' => array() |
|
1417
|
|
|
); |
|
1418
|
|
|
$boards[$row['id_board']]['tree'] = &$boards[$row['id_parent']]['tree']['children'][$row['id_board']]; |
|
1419
|
|
|
} |
|
1420
|
|
|
} |
|
1421
|
|
|
|
|
1422
|
|
|
// If mods want to do anything with this board before we move on, now's the time |
|
1423
|
|
|
call_integration_hook('integrate_boardtree_board', array($row)); |
|
1424
|
|
|
} |
|
1425
|
|
|
$smcFunc['db_free_result']($request); |
|
1426
|
|
|
|
|
1427
|
|
|
// Get a list of all the boards in each category (using recursion). |
|
1428
|
|
|
$boardList = array(); |
|
1429
|
|
|
foreach ($cat_tree as $catID => $node) |
|
1430
|
|
|
{ |
|
1431
|
|
|
$boardList[$catID] = array(); |
|
1432
|
|
|
recursiveBoards($boardList[$catID], $node); |
|
1433
|
|
|
} |
|
1434
|
|
|
} |
|
1435
|
|
|
|
|
1436
|
|
|
/** |
|
1437
|
|
|
* Recursively get a list of boards. |
|
1438
|
|
|
* Used by getBoardTree |
|
1439
|
|
|
* |
|
1440
|
|
|
* @param array &$_boardList The board list |
|
1441
|
|
|
* @param array &$_tree The board tree |
|
1442
|
|
|
*/ |
|
1443
|
|
|
function recursiveBoards(&$_boardList, &$_tree) |
|
1444
|
|
|
{ |
|
1445
|
|
|
if (empty($_tree['children'])) |
|
1446
|
|
|
return; |
|
1447
|
|
|
|
|
1448
|
|
|
foreach ($_tree['children'] as $id => $node) |
|
1449
|
|
|
{ |
|
1450
|
|
|
$_boardList[] = $id; |
|
1451
|
|
|
recursiveBoards($_boardList, $node); |
|
1452
|
|
|
} |
|
1453
|
|
|
} |
|
1454
|
|
|
|
|
1455
|
|
|
/** |
|
1456
|
|
|
* Returns whether the child board id is actually a child of the parent (recursive). |
|
1457
|
|
|
* @param int $child The ID of the child board |
|
1458
|
|
|
* @param int $parent The ID of a parent board |
|
1459
|
|
|
* @return boolean Whether the specified child board is actually a child of the specified parent board. |
|
1460
|
|
|
*/ |
|
1461
|
|
|
function isChildOf($child, $parent) |
|
1462
|
|
|
{ |
|
1463
|
|
|
global $boards; |
|
1464
|
|
|
|
|
1465
|
|
|
if (empty($boards[$child]['parent'])) |
|
1466
|
|
|
return false; |
|
1467
|
|
|
|
|
1468
|
|
|
if ($boards[$child]['parent'] == $parent) |
|
1469
|
|
|
return true; |
|
1470
|
|
|
|
|
1471
|
|
|
return isChildOf($boards[$child]['parent'], $parent); |
|
1472
|
|
|
} |
|
1473
|
|
|
|
|
1474
|
|
|
?> |
|
|
|
|
|
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.