annotate forum/Sources/Subs-Boards.php @ 87:df86d318892b website

Link to SampleType doc
author Chris Cannam
date Mon, 10 Feb 2014 18:11:48 +0000
parents e3e11437ecea
children
rev   line source
Chris@76 1 <?php
Chris@76 2
Chris@76 3 /**
Chris@76 4 * Simple Machines Forum (SMF)
Chris@76 5 *
Chris@76 6 * @package SMF
Chris@76 7 * @author Simple Machines http://www.simplemachines.org
Chris@76 8 * @copyright 2011 Simple Machines
Chris@76 9 * @license http://www.simplemachines.org/about/smf/license.php BSD
Chris@76 10 *
Chris@76 11 * @version 2.0
Chris@76 12 */
Chris@76 13
Chris@76 14 if (!defined('SMF'))
Chris@76 15 die('Hacking attempt...');
Chris@76 16
Chris@76 17 /* This file is mainly concerned with minor tasks relating to boards, such as
Chris@76 18 marking them read, collapsing categories, or quick moderation. It defines
Chris@76 19 the following list of functions:
Chris@76 20
Chris@76 21 void markBoardsRead(array boards)
Chris@76 22 // !!!
Chris@76 23
Chris@76 24 void MarkRead()
Chris@76 25 // !!!
Chris@76 26
Chris@76 27 int getMsgMemberID(int id_msg)
Chris@76 28 // !!!
Chris@76 29
Chris@76 30 void modifyBoard(int board_id, array boardOptions)
Chris@76 31 - general function to modify the settings and position of a board.
Chris@76 32 - used by ManageBoards.php to change the settings of a board.
Chris@76 33
Chris@76 34 int createBoard(array boardOptions)
Chris@76 35 - general function to create a new board and set its position.
Chris@76 36 - allows (almost) the same options as the modifyBoard() function.
Chris@76 37 - with the option inherit_permissions set, the parent board permissions
Chris@76 38 will be inherited.
Chris@76 39 - returns the ID of the newly created board.
Chris@76 40
Chris@76 41 void deleteBoards(array boards_to_remove, moveChildrenTo = null)
Chris@76 42 - general function to delete one or more boards.
Chris@76 43 - allows to move the children of the board before deleting it
Chris@76 44 - if moveChildrenTo is set to null, the child boards will be deleted.
Chris@76 45 - deletes all topics that are on the given boards.
Chris@76 46 - deletes all information that's associated with the given boards.
Chris@76 47 - updates the statistics to reflect the new situation.
Chris@76 48
Chris@76 49 void reorderBoards()
Chris@76 50 - updates the database to put all boards in the right order.
Chris@76 51 - sorts the records of the boards table.
Chris@76 52 - used by modifyBoard(), deleteBoards(), modifyCategory(), and
Chris@76 53 deleteCategories() functions.
Chris@76 54
Chris@76 55 void fixChildren(int parent, int newLevel, int newParent)
Chris@76 56 - recursively updates the children of parent's child_level and
Chris@76 57 id_parent to newLevel and newParent.
Chris@76 58 - used when a board is deleted or moved, to affect its children.
Chris@76 59
Chris@76 60 bool isChildOf(int child, int parent)
Chris@76 61 - determines if child is a child of parent.
Chris@76 62 - recurses down the tree until there are no more parents.
Chris@76 63 - returns true if child is a child of parent.
Chris@76 64
Chris@76 65 void getBoardTree()
Chris@76 66 - load information regarding the boards and categories.
Chris@76 67 - the information retrieved is stored in globals:
Chris@76 68 - $boards properties of each board.
Chris@76 69 - $boardList a list of boards grouped by category ID.
Chris@76 70 - $cat_tree properties of each category.
Chris@76 71
Chris@76 72 void recursiveBoards()
Chris@76 73 - function used by getBoardTree to recursively get a list of boards.
Chris@76 74
Chris@76 75 bool isChildOf(int child, int parent)
Chris@76 76 - determine if a certain board id is a child of another board.
Chris@76 77 - the parent might be several levels higher than the child.
Chris@76 78 */
Chris@76 79
Chris@76 80 // Mark a board or multiple boards read.
Chris@76 81 function markBoardsRead($boards, $unread = false)
Chris@76 82 {
Chris@76 83 global $user_info, $modSettings, $smcFunc;
Chris@76 84
Chris@76 85 // Force $boards to be an array.
Chris@76 86 if (!is_array($boards))
Chris@76 87 $boards = array($boards);
Chris@76 88 else
Chris@76 89 $boards = array_unique($boards);
Chris@76 90
Chris@76 91 // No boards, nothing to mark as read.
Chris@76 92 if (empty($boards))
Chris@76 93 return;
Chris@76 94
Chris@76 95 // Allow the user to mark a board as unread.
Chris@76 96 if ($unread)
Chris@76 97 {
Chris@76 98 // Clear out all the places where this lovely info is stored.
Chris@76 99 // !! Maybe not log_mark_read?
Chris@76 100 $smcFunc['db_query']('', '
Chris@76 101 DELETE FROM {db_prefix}log_mark_read
Chris@76 102 WHERE id_board IN ({array_int:board_list})
Chris@76 103 AND id_member = {int:current_member}',
Chris@76 104 array(
Chris@76 105 'current_member' => $user_info['id'],
Chris@76 106 'board_list' => $boards,
Chris@76 107 )
Chris@76 108 );
Chris@76 109 $smcFunc['db_query']('', '
Chris@76 110 DELETE FROM {db_prefix}log_boards
Chris@76 111 WHERE id_board IN ({array_int:board_list})
Chris@76 112 AND id_member = {int:current_member}',
Chris@76 113 array(
Chris@76 114 'current_member' => $user_info['id'],
Chris@76 115 'board_list' => $boards,
Chris@76 116 )
Chris@76 117 );
Chris@76 118 }
Chris@76 119 // Otherwise mark the board as read.
Chris@76 120 else
Chris@76 121 {
Chris@76 122 $markRead = array();
Chris@76 123 foreach ($boards as $board)
Chris@76 124 $markRead[] = array($modSettings['maxMsgID'], $user_info['id'], $board);
Chris@76 125
Chris@76 126 // Update log_mark_read and log_boards.
Chris@76 127 $smcFunc['db_insert']('replace',
Chris@76 128 '{db_prefix}log_mark_read',
Chris@76 129 array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'),
Chris@76 130 $markRead,
Chris@76 131 array('id_board', 'id_member')
Chris@76 132 );
Chris@76 133
Chris@76 134 $smcFunc['db_insert']('replace',
Chris@76 135 '{db_prefix}log_boards',
Chris@76 136 array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'),
Chris@76 137 $markRead,
Chris@76 138 array('id_board', 'id_member')
Chris@76 139 );
Chris@76 140 }
Chris@76 141
Chris@76 142 // Get rid of useless log_topics data, because log_mark_read is better for it - even if marking unread - I think so...
Chris@76 143 $result = $smcFunc['db_query']('', '
Chris@76 144 SELECT MIN(id_topic)
Chris@76 145 FROM {db_prefix}log_topics
Chris@76 146 WHERE id_member = {int:current_member}',
Chris@76 147 array(
Chris@76 148 'current_member' => $user_info['id'],
Chris@76 149 )
Chris@76 150 );
Chris@76 151 list ($lowest_topic) = $smcFunc['db_fetch_row']($result);
Chris@76 152 $smcFunc['db_free_result']($result);
Chris@76 153
Chris@76 154 if (empty($lowest_topic))
Chris@76 155 return;
Chris@76 156
Chris@76 157 // !!!SLOW This query seems to eat it sometimes.
Chris@76 158 $result = $smcFunc['db_query']('', '
Chris@76 159 SELECT lt.id_topic
Chris@76 160 FROM {db_prefix}log_topics AS lt
Chris@76 161 INNER JOIN {db_prefix}topics AS t /*!40000 USE INDEX (PRIMARY) */ ON (t.id_topic = lt.id_topic
Chris@76 162 AND t.id_board IN ({array_int:board_list}))
Chris@76 163 WHERE lt.id_member = {int:current_member}
Chris@76 164 AND lt.id_topic >= {int:lowest_topic}',
Chris@76 165 array(
Chris@76 166 'current_member' => $user_info['id'],
Chris@76 167 'board_list' => $boards,
Chris@76 168 'lowest_topic' => $lowest_topic,
Chris@76 169 )
Chris@76 170 );
Chris@76 171 $topics = array();
Chris@76 172 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 173 $topics[] = $row['id_topic'];
Chris@76 174 $smcFunc['db_free_result']($result);
Chris@76 175
Chris@76 176 if (!empty($topics))
Chris@76 177 $smcFunc['db_query']('', '
Chris@76 178 DELETE FROM {db_prefix}log_topics
Chris@76 179 WHERE id_member = {int:current_member}
Chris@76 180 AND id_topic IN ({array_int:topic_list})',
Chris@76 181 array(
Chris@76 182 'current_member' => $user_info['id'],
Chris@76 183 'topic_list' => $topics,
Chris@76 184 )
Chris@76 185 );
Chris@76 186 }
Chris@76 187
Chris@76 188 // Mark one or more boards as read.
Chris@76 189 function MarkRead()
Chris@76 190 {
Chris@76 191 global $board, $topic, $user_info, $board_info, $modSettings, $smcFunc;
Chris@76 192
Chris@76 193 // No Guests allowed!
Chris@76 194 is_not_guest();
Chris@76 195
Chris@76 196 checkSession('get');
Chris@76 197
Chris@76 198 if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'all')
Chris@76 199 {
Chris@76 200 // Find all the boards this user can see.
Chris@76 201 $result = $smcFunc['db_query']('', '
Chris@76 202 SELECT b.id_board
Chris@76 203 FROM {db_prefix}boards AS b
Chris@76 204 WHERE {query_see_board}',
Chris@76 205 array(
Chris@76 206 )
Chris@76 207 );
Chris@76 208 $boards = array();
Chris@76 209 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 210 $boards[] = $row['id_board'];
Chris@76 211 $smcFunc['db_free_result']($result);
Chris@76 212
Chris@76 213 if (!empty($boards))
Chris@76 214 markBoardsRead($boards, isset($_REQUEST['unread']));
Chris@76 215
Chris@76 216 $_SESSION['id_msg_last_visit'] = $modSettings['maxMsgID'];
Chris@76 217 if (!empty($_SESSION['old_url']) && strpos($_SESSION['old_url'], 'action=unread') !== false)
Chris@76 218 redirectexit('action=unread');
Chris@76 219
Chris@76 220 if (isset($_SESSION['topicseen_cache']))
Chris@76 221 $_SESSION['topicseen_cache'] = array();
Chris@76 222
Chris@76 223 redirectexit();
Chris@76 224 }
Chris@76 225 elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'unreadreplies')
Chris@76 226 {
Chris@76 227 // Make sure all the boards are integers!
Chris@76 228 $topics = explode('-', $_REQUEST['topics']);
Chris@76 229
Chris@76 230 $markRead = array();
Chris@76 231 foreach ($topics as $id_topic)
Chris@76 232 $markRead[] = array($modSettings['maxMsgID'], $user_info['id'], (int) $id_topic);
Chris@76 233
Chris@76 234 $smcFunc['db_insert']('replace',
Chris@76 235 '{db_prefix}log_topics',
Chris@76 236 array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'),
Chris@76 237 $markRead,
Chris@76 238 array('id_member', 'id_topic')
Chris@76 239 );
Chris@76 240
Chris@76 241 if (isset($_SESSION['topicseen_cache']))
Chris@76 242 $_SESSION['topicseen_cache'] = array();
Chris@76 243
Chris@76 244 redirectexit('action=unreadreplies');
Chris@76 245 }
Chris@76 246
Chris@76 247 // Special case: mark a topic unread!
Chris@76 248 elseif (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'topic')
Chris@76 249 {
Chris@76 250 // First, let's figure out what the latest message is.
Chris@76 251 $result = $smcFunc['db_query']('', '
Chris@76 252 SELECT id_first_msg, id_last_msg
Chris@76 253 FROM {db_prefix}topics
Chris@76 254 WHERE id_topic = {int:current_topic}',
Chris@76 255 array(
Chris@76 256 'current_topic' => $topic,
Chris@76 257 )
Chris@76 258 );
Chris@76 259 $topicinfo = $smcFunc['db_fetch_assoc']($result);
Chris@76 260 $smcFunc['db_free_result']($result);
Chris@76 261
Chris@76 262 if (!empty($_GET['t']))
Chris@76 263 {
Chris@76 264 // If they read the whole topic, go back to the beginning.
Chris@76 265 if ($_GET['t'] >= $topicinfo['id_last_msg'])
Chris@76 266 $earlyMsg = 0;
Chris@76 267 // If they want to mark the whole thing read, same.
Chris@76 268 elseif ($_GET['t'] <= $topicinfo['id_first_msg'])
Chris@76 269 $earlyMsg = 0;
Chris@76 270 // Otherwise, get the latest message before the named one.
Chris@76 271 else
Chris@76 272 {
Chris@76 273 $result = $smcFunc['db_query']('', '
Chris@76 274 SELECT MAX(id_msg)
Chris@76 275 FROM {db_prefix}messages
Chris@76 276 WHERE id_topic = {int:current_topic}
Chris@76 277 AND id_msg >= {int:id_first_msg}
Chris@76 278 AND id_msg < {int:topic_msg_id}',
Chris@76 279 array(
Chris@76 280 'current_topic' => $topic,
Chris@76 281 'topic_msg_id' => (int) $_GET['t'],
Chris@76 282 'id_first_msg' => $topicinfo['id_first_msg'],
Chris@76 283 )
Chris@76 284 );
Chris@76 285 list ($earlyMsg) = $smcFunc['db_fetch_row']($result);
Chris@76 286 $smcFunc['db_free_result']($result);
Chris@76 287 }
Chris@76 288 }
Chris@76 289 // Marking read from first page? That's the whole topic.
Chris@76 290 elseif ($_REQUEST['start'] == 0)
Chris@76 291 $earlyMsg = 0;
Chris@76 292 else
Chris@76 293 {
Chris@76 294 $result = $smcFunc['db_query']('', '
Chris@76 295 SELECT id_msg
Chris@76 296 FROM {db_prefix}messages
Chris@76 297 WHERE id_topic = {int:current_topic}
Chris@76 298 ORDER BY id_msg
Chris@76 299 LIMIT ' . (int) $_REQUEST['start'] . ', 1',
Chris@76 300 array(
Chris@76 301 'current_topic' => $topic,
Chris@76 302 )
Chris@76 303 );
Chris@76 304 list ($earlyMsg) = $smcFunc['db_fetch_row']($result);
Chris@76 305 $smcFunc['db_free_result']($result);
Chris@76 306
Chris@76 307 $earlyMsg--;
Chris@76 308 }
Chris@76 309
Chris@76 310 // Blam, unread!
Chris@76 311 $smcFunc['db_insert']('replace',
Chris@76 312 '{db_prefix}log_topics',
Chris@76 313 array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int'),
Chris@76 314 array($earlyMsg, $user_info['id'], $topic),
Chris@76 315 array('id_member', 'id_topic')
Chris@76 316 );
Chris@76 317
Chris@76 318 redirectexit('board=' . $board . '.0');
Chris@76 319 }
Chris@76 320 else
Chris@76 321 {
Chris@76 322 $categories = array();
Chris@76 323 $boards = array();
Chris@76 324
Chris@76 325 if (isset($_REQUEST['c']))
Chris@76 326 {
Chris@76 327 $_REQUEST['c'] = explode(',', $_REQUEST['c']);
Chris@76 328 foreach ($_REQUEST['c'] as $c)
Chris@76 329 $categories[] = (int) $c;
Chris@76 330 }
Chris@76 331 if (isset($_REQUEST['boards']))
Chris@76 332 {
Chris@76 333 $_REQUEST['boards'] = explode(',', $_REQUEST['boards']);
Chris@76 334 foreach ($_REQUEST['boards'] as $b)
Chris@76 335 $boards[] = (int) $b;
Chris@76 336 }
Chris@76 337 if (!empty($board))
Chris@76 338 $boards[] = (int) $board;
Chris@76 339
Chris@76 340 if (isset($_REQUEST['children']) && !empty($boards))
Chris@76 341 {
Chris@76 342 // They want to mark the entire tree starting with the boards specified
Chris@76 343 // The easist 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
Chris@76 344
Chris@76 345 $request = $smcFunc['db_query']('', '
Chris@76 346 SELECT b.id_board, b.id_parent
Chris@76 347 FROM {db_prefix}boards AS b
Chris@76 348 WHERE {query_see_board}
Chris@76 349 AND b.child_level > {int:no_parents}
Chris@76 350 AND b.id_board NOT IN ({array_int:board_list})
Chris@76 351 ORDER BY child_level ASC
Chris@76 352 ',
Chris@76 353 array(
Chris@76 354 'no_parents' => 0,
Chris@76 355 'board_list' => $boards,
Chris@76 356 )
Chris@76 357 );
Chris@76 358 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 359 if (in_array($row['id_parent'], $boards))
Chris@76 360 $boards[] = $row['id_board'];
Chris@76 361 $smcFunc['db_free_result']($request);
Chris@76 362 }
Chris@76 363
Chris@76 364 $clauses = array();
Chris@76 365 $clauseParameters = array();
Chris@76 366 if (!empty($categories))
Chris@76 367 {
Chris@76 368 $clauses[] = 'id_cat IN ({array_int:category_list})';
Chris@76 369 $clauseParameters['category_list'] = $categories;
Chris@76 370 }
Chris@76 371 if (!empty($boards))
Chris@76 372 {
Chris@76 373 $clauses[] = 'id_board IN ({array_int:board_list})';
Chris@76 374 $clauseParameters['board_list'] = $boards;
Chris@76 375 }
Chris@76 376
Chris@76 377 if (empty($clauses))
Chris@76 378 redirectexit();
Chris@76 379
Chris@76 380 $request = $smcFunc['db_query']('', '
Chris@76 381 SELECT b.id_board
Chris@76 382 FROM {db_prefix}boards AS b
Chris@76 383 WHERE {query_see_board}
Chris@76 384 AND b.' . implode(' OR b.', $clauses),
Chris@76 385 array_merge($clauseParameters, array(
Chris@76 386 ))
Chris@76 387 );
Chris@76 388 $boards = array();
Chris@76 389 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 390 $boards[] = $row['id_board'];
Chris@76 391 $smcFunc['db_free_result']($request);
Chris@76 392
Chris@76 393 if (empty($boards))
Chris@76 394 redirectexit();
Chris@76 395
Chris@76 396 markBoardsRead($boards, isset($_REQUEST['unread']));
Chris@76 397
Chris@76 398 foreach ($boards as $b)
Chris@76 399 {
Chris@76 400 if (isset($_SESSION['topicseen_cache'][$b]))
Chris@76 401 $_SESSION['topicseen_cache'][$b] = array();
Chris@76 402 }
Chris@76 403
Chris@76 404 if (!isset($_REQUEST['unread']))
Chris@76 405 {
Chris@76 406 // Find all the boards this user can see.
Chris@76 407 $result = $smcFunc['db_query']('', '
Chris@76 408 SELECT b.id_board
Chris@76 409 FROM {db_prefix}boards AS b
Chris@76 410 WHERE b.id_parent IN ({array_int:parent_list})
Chris@76 411 AND {query_see_board}',
Chris@76 412 array(
Chris@76 413 'parent_list' => $boards,
Chris@76 414 )
Chris@76 415 );
Chris@76 416 if ($smcFunc['db_num_rows']($result) > 0)
Chris@76 417 {
Chris@76 418 $logBoardInserts = '';
Chris@76 419 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 420 $logBoardInserts[] = array($modSettings['maxMsgID'], $user_info['id'], $row['id_board']);
Chris@76 421
Chris@76 422 $smcFunc['db_insert']('replace',
Chris@76 423 '{db_prefix}log_boards',
Chris@76 424 array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'),
Chris@76 425 $logBoardInserts,
Chris@76 426 array('id_member', 'id_board')
Chris@76 427 );
Chris@76 428 }
Chris@76 429 $smcFunc['db_free_result']($result);
Chris@76 430
Chris@76 431 if (empty($board))
Chris@76 432 redirectexit();
Chris@76 433 else
Chris@76 434 redirectexit('board=' . $board . '.0');
Chris@76 435 }
Chris@76 436 else
Chris@76 437 {
Chris@76 438 if (empty($board_info['parent']))
Chris@76 439 redirectexit();
Chris@76 440 else
Chris@76 441 redirectexit('board=' . $board_info['parent'] . '.0');
Chris@76 442 }
Chris@76 443 }
Chris@76 444 }
Chris@76 445
Chris@76 446 // Get the id_member associated with the specified message.
Chris@76 447 function getMsgMemberID($messageID)
Chris@76 448 {
Chris@76 449 global $smcFunc;
Chris@76 450
Chris@76 451 // Find the topic and make sure the member still exists.
Chris@76 452 $result = $smcFunc['db_query']('', '
Chris@76 453 SELECT IFNULL(mem.id_member, 0)
Chris@76 454 FROM {db_prefix}messages AS m
Chris@76 455 LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
Chris@76 456 WHERE m.id_msg = {int:selected_message}
Chris@76 457 LIMIT 1',
Chris@76 458 array(
Chris@76 459 'selected_message' => (int) $messageID,
Chris@76 460 )
Chris@76 461 );
Chris@76 462 if ($smcFunc['db_num_rows']($result) > 0)
Chris@76 463 list ($memberID) = $smcFunc['db_fetch_row']($result);
Chris@76 464 // The message doesn't even exist.
Chris@76 465 else
Chris@76 466 $memberID = 0;
Chris@76 467 $smcFunc['db_free_result']($result);
Chris@76 468
Chris@76 469 return (int) $memberID;
Chris@76 470 }
Chris@76 471
Chris@76 472 // Modify the settings and position of a board.
Chris@76 473 function modifyBoard($board_id, &$boardOptions)
Chris@76 474 {
Chris@76 475 global $sourcedir, $cat_tree, $boards, $boardList, $modSettings, $smcFunc;
Chris@76 476
Chris@76 477 // Get some basic information about all boards and categories.
Chris@76 478 getBoardTree();
Chris@76 479
Chris@76 480 // Make sure given boards and categories exist.
Chris@76 481 if (!isset($boards[$board_id]) || (isset($boardOptions['target_board']) && !isset($boards[$boardOptions['target_board']])) || (isset($boardOptions['target_category']) && !isset($cat_tree[$boardOptions['target_category']])))
Chris@76 482 fatal_lang_error('no_board');
Chris@76 483
Chris@76 484 // All things that will be updated in the database will be in $boardUpdates.
Chris@76 485 $boardUpdates = array();
Chris@76 486 $boardUpdateParameters = array();
Chris@76 487
Chris@76 488 // In case the board has to be moved
Chris@76 489 if (isset($boardOptions['move_to']))
Chris@76 490 {
Chris@76 491 // Move the board to the top of a given category.
Chris@76 492 if ($boardOptions['move_to'] == 'top')
Chris@76 493 {
Chris@76 494 $id_cat = $boardOptions['target_category'];
Chris@76 495 $child_level = 0;
Chris@76 496 $id_parent = 0;
Chris@76 497 $after = $cat_tree[$id_cat]['last_board_order'];
Chris@76 498 }
Chris@76 499
Chris@76 500 // Move the board to the bottom of a given category.
Chris@76 501 elseif ($boardOptions['move_to'] == 'bottom')
Chris@76 502 {
Chris@76 503 $id_cat = $boardOptions['target_category'];
Chris@76 504 $child_level = 0;
Chris@76 505 $id_parent = 0;
Chris@76 506 $after = 0;
Chris@76 507 foreach ($cat_tree[$id_cat]['children'] as $id_board => $dummy)
Chris@76 508 $after = max($after, $boards[$id_board]['order']);
Chris@76 509 }
Chris@76 510
Chris@76 511 // Make the board a child of a given board.
Chris@76 512 elseif ($boardOptions['move_to'] == 'child')
Chris@76 513 {
Chris@76 514 $id_cat = $boards[$boardOptions['target_board']]['category'];
Chris@76 515 $child_level = $boards[$boardOptions['target_board']]['level'] + 1;
Chris@76 516 $id_parent = $boardOptions['target_board'];
Chris@76 517
Chris@76 518 // People can be creative, in many ways...
Chris@76 519 if (isChildOf($id_parent, $board_id))
Chris@76 520 fatal_lang_error('mboards_parent_own_child_error', false);
Chris@76 521 elseif ($id_parent == $board_id)
Chris@76 522 fatal_lang_error('mboards_board_own_child_error', false);
Chris@76 523
Chris@76 524 $after = $boards[$boardOptions['target_board']]['order'];
Chris@76 525
Chris@76 526 // Check if there are already children and (if so) get the max board order.
Chris@76 527 if (!empty($boards[$id_parent]['tree']['children']) && empty($boardOptions['move_first_child']))
Chris@76 528 foreach ($boards[$id_parent]['tree']['children'] as $childBoard_id => $dummy)
Chris@76 529 $after = max($after, $boards[$childBoard_id]['order']);
Chris@76 530 }
Chris@76 531
Chris@76 532 // Place a board before or after another board, on the same child level.
Chris@76 533 elseif (in_array($boardOptions['move_to'], array('before', 'after')))
Chris@76 534 {
Chris@76 535 $id_cat = $boards[$boardOptions['target_board']]['category'];
Chris@76 536 $child_level = $boards[$boardOptions['target_board']]['level'];
Chris@76 537 $id_parent = $boards[$boardOptions['target_board']]['parent'];
Chris@76 538 $after = $boards[$boardOptions['target_board']]['order'] - ($boardOptions['move_to'] == 'before' ? 1 : 0);
Chris@76 539 }
Chris@76 540
Chris@76 541 // Oops...?
Chris@76 542 else
Chris@76 543 trigger_error('modifyBoard(): The move_to value \'' . $boardOptions['move_to'] . '\' is incorrect', E_USER_ERROR);
Chris@76 544
Chris@76 545 // Get a list of children of this board.
Chris@76 546 $childList = array();
Chris@76 547 recursiveBoards($childList, $boards[$board_id]['tree']);
Chris@76 548
Chris@76 549 // See if there are changes that affect children.
Chris@76 550 $childUpdates = array();
Chris@76 551 $levelDiff = $child_level - $boards[$board_id]['level'];
Chris@76 552 if ($levelDiff != 0)
Chris@76 553 $childUpdates[] = 'child_level = child_level ' . ($levelDiff > 0 ? '+ ' : '') . '{int:level_diff}';
Chris@76 554 if ($id_cat != $boards[$board_id]['category'])
Chris@76 555 $childUpdates[] = 'id_cat = {int:category}';
Chris@76 556
Chris@76 557 // Fix the children of this board.
Chris@76 558 if (!empty($childList) && !empty($childUpdates))
Chris@76 559 $smcFunc['db_query']('', '
Chris@76 560 UPDATE {db_prefix}boards
Chris@76 561 SET ' . implode(',
Chris@76 562 ', $childUpdates) . '
Chris@76 563 WHERE id_board IN ({array_int:board_list})',
Chris@76 564 array(
Chris@76 565 'board_list' => $childList,
Chris@76 566 'category' => $id_cat,
Chris@76 567 'level_diff' => $levelDiff,
Chris@76 568 )
Chris@76 569 );
Chris@76 570
Chris@76 571 // Make some room for this spot.
Chris@76 572 $smcFunc['db_query']('', '
Chris@76 573 UPDATE {db_prefix}boards
Chris@76 574 SET board_order = board_order + {int:new_order}
Chris@76 575 WHERE board_order > {int:insert_after}
Chris@76 576 AND id_board != {int:selected_board}',
Chris@76 577 array(
Chris@76 578 'insert_after' => $after,
Chris@76 579 'selected_board' => $board_id,
Chris@76 580 'new_order' => 1 + count($childList),
Chris@76 581 )
Chris@76 582 );
Chris@76 583
Chris@76 584 $boardUpdates[] = 'id_cat = {int:id_cat}';
Chris@76 585 $boardUpdates[] = 'id_parent = {int:id_parent}';
Chris@76 586 $boardUpdates[] = 'child_level = {int:child_level}';
Chris@76 587 $boardUpdates[] = 'board_order = {int:board_order}';
Chris@76 588 $boardUpdateParameters += array(
Chris@76 589 'id_cat' => $id_cat,
Chris@76 590 'id_parent' => $id_parent,
Chris@76 591 'child_level' => $child_level,
Chris@76 592 'board_order' => $after + 1,
Chris@76 593 );
Chris@76 594 }
Chris@76 595
Chris@76 596 // This setting is a little twisted in the database...
Chris@76 597 if (isset($boardOptions['posts_count']))
Chris@76 598 {
Chris@76 599 $boardUpdates[] = 'count_posts = {int:count_posts}';
Chris@76 600 $boardUpdateParameters['count_posts'] = $boardOptions['posts_count'] ? 0 : 1;
Chris@76 601 }
Chris@76 602
Chris@76 603 // Set the theme for this board.
Chris@76 604 if (isset($boardOptions['board_theme']))
Chris@76 605 {
Chris@76 606 $boardUpdates[] = 'id_theme = {int:id_theme}';
Chris@76 607 $boardUpdateParameters['id_theme'] = (int) $boardOptions['board_theme'];
Chris@76 608 }
Chris@76 609
Chris@76 610 // Should the board theme override the user preferred theme?
Chris@76 611 if (isset($boardOptions['override_theme']))
Chris@76 612 {
Chris@76 613 $boardUpdates[] = 'override_theme = {int:override_theme}';
Chris@76 614 $boardUpdateParameters['override_theme'] = $boardOptions['override_theme'] ? 1 : 0;
Chris@76 615 }
Chris@76 616
Chris@76 617 // Who's allowed to access this board.
Chris@76 618 if (isset($boardOptions['access_groups']))
Chris@76 619 {
Chris@76 620 $boardUpdates[] = 'member_groups = {string:member_groups}';
Chris@76 621 $boardUpdateParameters['member_groups'] = implode(',', $boardOptions['access_groups']);
Chris@76 622 }
Chris@76 623
Chris@76 624 if (isset($boardOptions['board_name']))
Chris@76 625 {
Chris@76 626 $boardUpdates[] = 'name = {string:board_name}';
Chris@76 627 $boardUpdateParameters['board_name'] = $boardOptions['board_name'];
Chris@76 628 }
Chris@76 629
Chris@76 630 if (isset($boardOptions['board_description']))
Chris@76 631 {
Chris@76 632 $boardUpdates[] = 'description = {string:board_description}';
Chris@76 633 $boardUpdateParameters['board_description'] = $boardOptions['board_description'];
Chris@76 634 }
Chris@76 635
Chris@76 636 if (isset($boardOptions['profile']))
Chris@76 637 {
Chris@76 638 $boardUpdates[] = 'id_profile = {int:profile}';
Chris@76 639 $boardUpdateParameters['profile'] = (int) $boardOptions['profile'];
Chris@76 640 }
Chris@76 641
Chris@76 642 if (isset($boardOptions['redirect']))
Chris@76 643 {
Chris@76 644 $boardUpdates[] = 'redirect = {string:redirect}';
Chris@76 645 $boardUpdateParameters['redirect'] = $boardOptions['redirect'];
Chris@76 646 }
Chris@76 647
Chris@76 648 if (isset($boardOptions['num_posts']))
Chris@76 649 {
Chris@76 650 $boardUpdates[] = 'num_posts = {int:num_posts}';
Chris@76 651 $boardUpdateParameters['num_posts'] = (int) $boardOptions['num_posts'];
Chris@76 652 }
Chris@76 653
Chris@76 654 // Do the updates (if any).
Chris@76 655 if (!empty($boardUpdates))
Chris@76 656 $request = $smcFunc['db_query']('', '
Chris@76 657 UPDATE {db_prefix}boards
Chris@76 658 SET
Chris@76 659 ' . implode(',
Chris@76 660 ', $boardUpdates) . '
Chris@76 661 WHERE id_board = {int:selected_board}',
Chris@76 662 array_merge($boardUpdateParameters, array(
Chris@76 663 'selected_board' => $board_id,
Chris@76 664 ))
Chris@76 665 );
Chris@76 666
Chris@76 667 // Set moderators of this board.
Chris@76 668 if (isset($boardOptions['moderators']) || isset($boardOptions['moderator_string']))
Chris@76 669 {
Chris@76 670 // Reset current moderators for this board - if there are any!
Chris@76 671 $smcFunc['db_query']('', '
Chris@76 672 DELETE FROM {db_prefix}moderators
Chris@76 673 WHERE id_board = {int:board_list}',
Chris@76 674 array(
Chris@76 675 'board_list' => $board_id,
Chris@76 676 )
Chris@76 677 );
Chris@76 678
Chris@76 679 // Validate and get the IDs of the new moderators.
Chris@76 680 if (isset($boardOptions['moderator_string']) && trim($boardOptions['moderator_string']) != '')
Chris@76 681 {
Chris@76 682 // Divvy out the usernames, remove extra space.
Chris@76 683 $moderator_string = strtr($smcFunc['htmlspecialchars']($boardOptions['moderator_string'], ENT_QUOTES), array('&quot;' => '"'));
Chris@76 684 preg_match_all('~"([^"]+)"~', $moderator_string, $matches);
Chris@76 685 $moderators = array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $moderator_string)));
Chris@76 686 for ($k = 0, $n = count($moderators); $k < $n; $k++)
Chris@76 687 {
Chris@76 688 $moderators[$k] = trim($moderators[$k]);
Chris@76 689
Chris@76 690 if (strlen($moderators[$k]) == 0)
Chris@76 691 unset($moderators[$k]);
Chris@76 692 }
Chris@76 693
Chris@76 694 // Find all the id_member's for the member_name's in the list.
Chris@76 695 if (empty($boardOptions['moderators']))
Chris@76 696 $boardOptions['moderators'] = array();
Chris@76 697 if (!empty($moderators))
Chris@76 698 {
Chris@76 699 $request = $smcFunc['db_query']('', '
Chris@76 700 SELECT id_member
Chris@76 701 FROM {db_prefix}members
Chris@76 702 WHERE member_name IN ({array_string:moderator_list}) OR real_name IN ({array_string:moderator_list})
Chris@76 703 LIMIT ' . count($moderators),
Chris@76 704 array(
Chris@76 705 'moderator_list' => $moderators,
Chris@76 706 )
Chris@76 707 );
Chris@76 708 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 709 $boardOptions['moderators'][] = $row['id_member'];
Chris@76 710 $smcFunc['db_free_result']($request);
Chris@76 711 }
Chris@76 712 }
Chris@76 713
Chris@76 714 // Add the moderators to the board.
Chris@76 715 if (!empty($boardOptions['moderators']))
Chris@76 716 {
Chris@76 717 $inserts = array();
Chris@76 718 foreach ($boardOptions['moderators'] as $moderator)
Chris@76 719 $inserts[] = array($board_id, $moderator);
Chris@76 720
Chris@76 721 $smcFunc['db_insert']('insert',
Chris@76 722 '{db_prefix}moderators',
Chris@76 723 array('id_board' => 'int', 'id_member' => 'int'),
Chris@76 724 $inserts,
Chris@76 725 array('id_board', 'id_member')
Chris@76 726 );
Chris@76 727 }
Chris@76 728
Chris@76 729 // Note that caches can now be wrong!
Chris@76 730 updateSettings(array('settings_updated' => time()));
Chris@76 731 }
Chris@76 732
Chris@76 733 if (isset($boardOptions['move_to']))
Chris@76 734 reorderBoards();
Chris@76 735
Chris@76 736 clean_cache('data');
Chris@76 737
Chris@76 738 if (empty($boardOptions['dont_log']))
Chris@76 739 logAction('edit_board', array('board' => $board_id), 'admin');
Chris@76 740 }
Chris@76 741
Chris@76 742 // Create a new board and set its properties and position.
Chris@76 743 function createBoard($boardOptions)
Chris@76 744 {
Chris@76 745 global $boards, $modSettings, $smcFunc;
Chris@76 746
Chris@76 747 // Trigger an error if one of the required values is not set.
Chris@76 748 if (!isset($boardOptions['board_name']) || trim($boardOptions['board_name']) == '' || !isset($boardOptions['move_to']) || !isset($boardOptions['target_category']))
Chris@76 749 trigger_error('createBoard(): One or more of the required options is not set', E_USER_ERROR);
Chris@76 750
Chris@76 751 if (in_array($boardOptions['move_to'], array('child', 'before', 'after')) && !isset($boardOptions['target_board']))
Chris@76 752 trigger_error('createBoard(): Target board is not set', E_USER_ERROR);
Chris@76 753
Chris@76 754 // Set every optional value to its default value.
Chris@76 755 $boardOptions += array(
Chris@76 756 'posts_count' => true,
Chris@76 757 'override_theme' => false,
Chris@76 758 'board_theme' => 0,
Chris@76 759 'access_groups' => array(),
Chris@76 760 'board_description' => '',
Chris@76 761 'profile' => 1,
Chris@76 762 'moderators' => '',
Chris@76 763 'inherit_permissions' => true,
Chris@76 764 'dont_log' => true,
Chris@76 765 );
Chris@76 766
Chris@76 767 // Insert a board, the settings are dealt with later.
Chris@76 768 $smcFunc['db_insert']('',
Chris@76 769 '{db_prefix}boards',
Chris@76 770 array(
Chris@76 771 'id_cat' => 'int', 'name' => 'string-255', 'description' => 'string', 'board_order' => 'int',
Chris@76 772 'member_groups' => 'string', 'redirect' => 'string',
Chris@76 773 ),
Chris@76 774 array(
Chris@76 775 $boardOptions['target_category'], $boardOptions['board_name'] , '', 0,
Chris@76 776 '-1,0', '',
Chris@76 777 ),
Chris@76 778 array('id_board')
Chris@76 779 );
Chris@76 780 $board_id = $smcFunc['db_insert_id']('{db_prefix}boards', 'id_board');
Chris@76 781
Chris@76 782 if (empty($board_id))
Chris@76 783 return 0;
Chris@76 784
Chris@76 785 // Change the board according to the given specifications.
Chris@76 786 modifyBoard($board_id, $boardOptions);
Chris@76 787
Chris@76 788 // Do we want the parent permissions to be inherited?
Chris@76 789 if ($boardOptions['inherit_permissions'])
Chris@76 790 {
Chris@76 791 getBoardTree();
Chris@76 792
Chris@76 793 if (!empty($boards[$board_id]['parent']))
Chris@76 794 {
Chris@76 795 $request = $smcFunc['db_query']('', '
Chris@76 796 SELECT id_profile
Chris@76 797 FROM {db_prefix}boards
Chris@76 798 WHERE id_board = {int:board_parent}
Chris@76 799 LIMIT 1',
Chris@76 800 array(
Chris@76 801 'board_parent' => (int) $boards[$board_id]['parent'],
Chris@76 802 )
Chris@76 803 );
Chris@76 804 list ($boardOptions['profile']) = $smcFunc['db_fetch_row']($request);
Chris@76 805 $smcFunc['db_free_result']($request);
Chris@76 806
Chris@76 807 $smcFunc['db_query']('', '
Chris@76 808 UPDATE {db_prefix}boards
Chris@76 809 SET id_profile = {int:new_profile}
Chris@76 810 WHERE id_board = {int:current_board}',
Chris@76 811 array(
Chris@76 812 'new_profile' => $boardOptions['profile'],
Chris@76 813 'current_board' => $board_id,
Chris@76 814 )
Chris@76 815 );
Chris@76 816 }
Chris@76 817 }
Chris@76 818
Chris@76 819 // Clean the data cache.
Chris@76 820 clean_cache('data');
Chris@76 821
Chris@76 822 // Created it.
Chris@76 823 logAction('add_board', array('board' => $board_id), 'admin');
Chris@76 824
Chris@76 825 // Here you are, a new board, ready to be spammed.
Chris@76 826 return $board_id;
Chris@76 827 }
Chris@76 828
Chris@76 829 // Remove one or more boards.
Chris@76 830 function deleteBoards($boards_to_remove, $moveChildrenTo = null)
Chris@76 831 {
Chris@76 832 global $sourcedir, $boards, $smcFunc;
Chris@76 833
Chris@76 834 // No boards to delete? Return!
Chris@76 835 if (empty($boards_to_remove))
Chris@76 836 return;
Chris@76 837
Chris@76 838 getBoardTree();
Chris@76 839
Chris@76 840 // If $moveChildrenTo is set to null, include the children in the removal.
Chris@76 841 if ($moveChildrenTo === null)
Chris@76 842 {
Chris@76 843 // Get a list of the child boards that will also be removed.
Chris@76 844 $child_boards_to_remove = array();
Chris@76 845 foreach ($boards_to_remove as $board_to_remove)
Chris@76 846 recursiveBoards($child_boards_to_remove, $boards[$board_to_remove]['tree']);
Chris@76 847
Chris@76 848 // Merge the children with their parents.
Chris@76 849 if (!empty($child_boards_to_remove))
Chris@76 850 $boards_to_remove = array_unique(array_merge($boards_to_remove, $child_boards_to_remove));
Chris@76 851 }
Chris@76 852 // Move the children to a safe home.
Chris@76 853 else
Chris@76 854 {
Chris@76 855 foreach ($boards_to_remove as $id_board)
Chris@76 856 {
Chris@76 857 // !!! Separate category?
Chris@76 858 if ($moveChildrenTo === 0)
Chris@76 859 fixChildren($id_board, 0, 0);
Chris@76 860 else
Chris@76 861 fixChildren($id_board, $boards[$moveChildrenTo]['level'] + 1, $moveChildrenTo);
Chris@76 862 }
Chris@76 863 }
Chris@76 864
Chris@76 865 // Delete ALL topics in the selected boards (done first so topics can't be marooned.)
Chris@76 866 $request = $smcFunc['db_query']('', '
Chris@76 867 SELECT id_topic
Chris@76 868 FROM {db_prefix}topics
Chris@76 869 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 870 array(
Chris@76 871 'boards_to_remove' => $boards_to_remove,
Chris@76 872 )
Chris@76 873 );
Chris@76 874 $topics = array();
Chris@76 875 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 876 $topics[] = $row['id_topic'];
Chris@76 877 $smcFunc['db_free_result']($request);
Chris@76 878
Chris@76 879 require_once($sourcedir . '/RemoveTopic.php');
Chris@76 880 removeTopics($topics, false);
Chris@76 881
Chris@76 882 // Delete the board's logs.
Chris@76 883 $smcFunc['db_query']('', '
Chris@76 884 DELETE FROM {db_prefix}log_mark_read
Chris@76 885 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 886 array(
Chris@76 887 'boards_to_remove' => $boards_to_remove,
Chris@76 888 )
Chris@76 889 );
Chris@76 890 $smcFunc['db_query']('', '
Chris@76 891 DELETE FROM {db_prefix}log_boards
Chris@76 892 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 893 array(
Chris@76 894 'boards_to_remove' => $boards_to_remove,
Chris@76 895 )
Chris@76 896 );
Chris@76 897 $smcFunc['db_query']('', '
Chris@76 898 DELETE FROM {db_prefix}log_notify
Chris@76 899 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 900 array(
Chris@76 901 'boards_to_remove' => $boards_to_remove,
Chris@76 902 )
Chris@76 903 );
Chris@76 904
Chris@76 905 // Delete this board's moderators.
Chris@76 906 $smcFunc['db_query']('', '
Chris@76 907 DELETE FROM {db_prefix}moderators
Chris@76 908 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 909 array(
Chris@76 910 'boards_to_remove' => $boards_to_remove,
Chris@76 911 )
Chris@76 912 );
Chris@76 913
Chris@76 914 // Delete any extra events in the calendar.
Chris@76 915 $smcFunc['db_query']('', '
Chris@76 916 DELETE FROM {db_prefix}calendar
Chris@76 917 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 918 array(
Chris@76 919 'boards_to_remove' => $boards_to_remove,
Chris@76 920 )
Chris@76 921 );
Chris@76 922
Chris@76 923 // Delete any message icons that only appear on these boards.
Chris@76 924 $smcFunc['db_query']('', '
Chris@76 925 DELETE FROM {db_prefix}message_icons
Chris@76 926 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 927 array(
Chris@76 928 'boards_to_remove' => $boards_to_remove,
Chris@76 929 )
Chris@76 930 );
Chris@76 931
Chris@76 932 // Delete the boards.
Chris@76 933 $smcFunc['db_query']('', '
Chris@76 934 DELETE FROM {db_prefix}boards
Chris@76 935 WHERE id_board IN ({array_int:boards_to_remove})',
Chris@76 936 array(
Chris@76 937 'boards_to_remove' => $boards_to_remove,
Chris@76 938 )
Chris@76 939 );
Chris@76 940
Chris@76 941 // Latest message/topic might not be there anymore.
Chris@76 942 updateStats('message');
Chris@76 943 updateStats('topic');
Chris@76 944 updateSettings(array(
Chris@76 945 'calendar_updated' => time(),
Chris@76 946 ));
Chris@76 947
Chris@76 948 // Plus reset the cache to stop people getting odd results.
Chris@76 949 updateSettings(array('settings_updated' => time()));
Chris@76 950
Chris@76 951 // Clean the cache as well.
Chris@76 952 clean_cache('data');
Chris@76 953
Chris@76 954 // Let's do some serious logging.
Chris@76 955 foreach ($boards_to_remove as $id_board)
Chris@76 956 logAction('delete_board', array('boardname' => $boards[$id_board]['name']), 'admin');
Chris@76 957
Chris@76 958 reorderBoards();
Chris@76 959 }
Chris@76 960
Chris@76 961 // Put all boards in the right order.
Chris@76 962 function reorderBoards()
Chris@76 963 {
Chris@76 964 global $cat_tree, $boardList, $boards, $smcFunc;
Chris@76 965
Chris@76 966 getBoardTree();
Chris@76 967
Chris@76 968 // Set the board order for each category.
Chris@76 969 $board_order = 0;
Chris@76 970 foreach ($cat_tree as $catID => $dummy)
Chris@76 971 {
Chris@76 972 foreach ($boardList[$catID] as $boardID)
Chris@76 973 if ($boards[$boardID]['order'] != ++$board_order)
Chris@76 974 $smcFunc['db_query']('', '
Chris@76 975 UPDATE {db_prefix}boards
Chris@76 976 SET board_order = {int:new_order}
Chris@76 977 WHERE id_board = {int:selected_board}',
Chris@76 978 array(
Chris@76 979 'new_order' => $board_order,
Chris@76 980 'selected_board' => $boardID,
Chris@76 981 )
Chris@76 982 );
Chris@76 983 }
Chris@76 984
Chris@76 985 // Sort the records of the boards table on the board_order value.
Chris@76 986 $smcFunc['db_query']('alter_table_boards', '
Chris@76 987 ALTER TABLE {db_prefix}boards
Chris@76 988 ORDER BY board_order',
Chris@76 989 array(
Chris@76 990 'db_error_skip' => true,
Chris@76 991 )
Chris@76 992 );
Chris@76 993 }
Chris@76 994
Chris@76 995 // Fixes the children of a board by setting their child_levels to new values.
Chris@76 996 function fixChildren($parent, $newLevel, $newParent)
Chris@76 997 {
Chris@76 998 global $smcFunc;
Chris@76 999
Chris@76 1000 // Grab all children of $parent...
Chris@76 1001 $result = $smcFunc['db_query']('', '
Chris@76 1002 SELECT id_board
Chris@76 1003 FROM {db_prefix}boards
Chris@76 1004 WHERE id_parent = {int:parent_board}',
Chris@76 1005 array(
Chris@76 1006 'parent_board' => $parent,
Chris@76 1007 )
Chris@76 1008 );
Chris@76 1009 $children = array();
Chris@76 1010 while ($row = $smcFunc['db_fetch_assoc']($result))
Chris@76 1011 $children[] = $row['id_board'];
Chris@76 1012 $smcFunc['db_free_result']($result);
Chris@76 1013
Chris@76 1014 // ...and set it to a new parent and child_level.
Chris@76 1015 $smcFunc['db_query']('', '
Chris@76 1016 UPDATE {db_prefix}boards
Chris@76 1017 SET id_parent = {int:new_parent}, child_level = {int:new_child_level}
Chris@76 1018 WHERE id_parent = {int:parent_board}',
Chris@76 1019 array(
Chris@76 1020 'new_parent' => $newParent,
Chris@76 1021 'new_child_level' => $newLevel,
Chris@76 1022 'parent_board' => $parent,
Chris@76 1023 )
Chris@76 1024 );
Chris@76 1025
Chris@76 1026 // Recursively fix the children of the children.
Chris@76 1027 foreach ($children as $child)
Chris@76 1028 fixChildren($child, $newLevel + 1, $child);
Chris@76 1029 }
Chris@76 1030
Chris@76 1031 // Load a lot of useful information regarding the boards and categories.
Chris@76 1032 function getBoardTree()
Chris@76 1033 {
Chris@76 1034 global $cat_tree, $boards, $boardList, $txt, $modSettings, $smcFunc;
Chris@76 1035
Chris@76 1036 // Getting all the board and category information you'd ever wanted.
Chris@76 1037 $request = $smcFunc['db_query']('', '
Chris@76 1038 SELECT
Chris@76 1039 IFNULL(b.id_board, 0) AS id_board, b.id_parent, b.name AS board_name, b.description, b.child_level,
Chris@76 1040 b.board_order, b.count_posts, b.member_groups, b.id_theme, b.override_theme, b.id_profile, b.redirect,
Chris@76 1041 b.num_posts, b.num_topics, c.id_cat, c.name AS cat_name, c.cat_order, c.can_collapse
Chris@76 1042 FROM {db_prefix}categories AS c
Chris@76 1043 LEFT JOIN {db_prefix}boards AS b ON (b.id_cat = c.id_cat)
Chris@76 1044 ORDER BY c.cat_order, b.child_level, b.board_order',
Chris@76 1045 array(
Chris@76 1046 )
Chris@76 1047 );
Chris@76 1048 $cat_tree = array();
Chris@76 1049 $boards = array();
Chris@76 1050 $last_board_order = 0;
Chris@76 1051 while ($row = $smcFunc['db_fetch_assoc']($request))
Chris@76 1052 {
Chris@76 1053 if (!isset($cat_tree[$row['id_cat']]))
Chris@76 1054 {
Chris@76 1055 $cat_tree[$row['id_cat']] = array(
Chris@76 1056 'node' => array(
Chris@76 1057 'id' => $row['id_cat'],
Chris@76 1058 'name' => $row['cat_name'],
Chris@76 1059 'order' => $row['cat_order'],
Chris@76 1060 'can_collapse' => $row['can_collapse']
Chris@76 1061 ),
Chris@76 1062 'is_first' => empty($cat_tree),
Chris@76 1063 'last_board_order' => $last_board_order,
Chris@76 1064 'children' => array()
Chris@76 1065 );
Chris@76 1066 $prevBoard = 0;
Chris@76 1067 $curLevel = 0;
Chris@76 1068 }
Chris@76 1069
Chris@76 1070 if (!empty($row['id_board']))
Chris@76 1071 {
Chris@76 1072 if ($row['child_level'] != $curLevel)
Chris@76 1073 $prevBoard = 0;
Chris@76 1074
Chris@76 1075 $boards[$row['id_board']] = array(
Chris@76 1076 'id' => $row['id_board'],
Chris@76 1077 'category' => $row['id_cat'],
Chris@76 1078 'parent' => $row['id_parent'],
Chris@76 1079 'level' => $row['child_level'],
Chris@76 1080 'order' => $row['board_order'],
Chris@76 1081 'name' => $row['board_name'],
Chris@76 1082 'member_groups' => explode(',', $row['member_groups']),
Chris@76 1083 'description' => $row['description'],
Chris@76 1084 'count_posts' => empty($row['count_posts']),
Chris@76 1085 'posts' => $row['num_posts'],
Chris@76 1086 'topics' => $row['num_topics'],
Chris@76 1087 'theme' => $row['id_theme'],
Chris@76 1088 'override_theme' => $row['override_theme'],
Chris@76 1089 'profile' => $row['id_profile'],
Chris@76 1090 'redirect' => $row['redirect'],
Chris@76 1091 'prev_board' => $prevBoard
Chris@76 1092 );
Chris@76 1093 $prevBoard = $row['id_board'];
Chris@76 1094 $last_board_order = $row['board_order'];
Chris@76 1095
Chris@76 1096 if (empty($row['child_level']))
Chris@76 1097 {
Chris@76 1098 $cat_tree[$row['id_cat']]['children'][$row['id_board']] = array(
Chris@76 1099 'node' => &$boards[$row['id_board']],
Chris@76 1100 'is_first' => empty($cat_tree[$row['id_cat']]['children']),
Chris@76 1101 'children' => array()
Chris@76 1102 );
Chris@76 1103 $boards[$row['id_board']]['tree'] = &$cat_tree[$row['id_cat']]['children'][$row['id_board']];
Chris@76 1104 }
Chris@76 1105 else
Chris@76 1106 {
Chris@76 1107 // Parent doesn't exist!
Chris@76 1108 if (!isset($boards[$row['id_parent']]['tree']))
Chris@76 1109 fatal_lang_error('no_valid_parent', false, array($row['board_name']));
Chris@76 1110
Chris@76 1111 // Wrong childlevel...we can silently fix this...
Chris@76 1112 if ($boards[$row['id_parent']]['tree']['node']['level'] != $row['child_level'] - 1)
Chris@76 1113 $smcFunc['db_query']('', '
Chris@76 1114 UPDATE {db_prefix}boards
Chris@76 1115 SET child_level = {int:new_child_level}
Chris@76 1116 WHERE id_board = {int:selected_board}',
Chris@76 1117 array(
Chris@76 1118 'new_child_level' => $boards[$row['id_parent']]['tree']['node']['level'] + 1,
Chris@76 1119 'selected_board' => $row['id_board'],
Chris@76 1120 )
Chris@76 1121 );
Chris@76 1122
Chris@76 1123 $boards[$row['id_parent']]['tree']['children'][$row['id_board']] = array(
Chris@76 1124 'node' => &$boards[$row['id_board']],
Chris@76 1125 'is_first' => empty($boards[$row['id_parent']]['tree']['children']),
Chris@76 1126 'children' => array()
Chris@76 1127 );
Chris@76 1128 $boards[$row['id_board']]['tree'] = &$boards[$row['id_parent']]['tree']['children'][$row['id_board']];
Chris@76 1129 }
Chris@76 1130 }
Chris@76 1131 }
Chris@76 1132 $smcFunc['db_free_result']($request);
Chris@76 1133
Chris@76 1134 // Get a list of all the boards in each category (using recursion).
Chris@76 1135 $boardList = array();
Chris@76 1136 foreach ($cat_tree as $catID => $node)
Chris@76 1137 {
Chris@76 1138 $boardList[$catID] = array();
Chris@76 1139 recursiveBoards($boardList[$catID], $node);
Chris@76 1140 }
Chris@76 1141 }
Chris@76 1142
Chris@76 1143 // Recursively get a list of boards.
Chris@76 1144 function recursiveBoards(&$_boardList, &$_tree)
Chris@76 1145 {
Chris@76 1146 if (empty($_tree['children']))
Chris@76 1147 return;
Chris@76 1148
Chris@76 1149 foreach ($_tree['children'] as $id => $node)
Chris@76 1150 {
Chris@76 1151 $_boardList[] = $id;
Chris@76 1152 recursiveBoards($_boardList, $node);
Chris@76 1153 }
Chris@76 1154 }
Chris@76 1155
Chris@76 1156 // Returns whether the child board id is actually a child of the parent (recursive).
Chris@76 1157 function isChildOf($child, $parent)
Chris@76 1158 {
Chris@76 1159 global $boards;
Chris@76 1160
Chris@76 1161 if (empty($boards[$child]['parent']))
Chris@76 1162 return false;
Chris@76 1163
Chris@76 1164 if ($boards[$child]['parent'] == $parent)
Chris@76 1165 return true;
Chris@76 1166
Chris@76 1167 return isChildOf($boards[$child]['parent'], $parent);
Chris@76 1168 }
Chris@76 1169
Chris@76 1170 ?>