diff --git a/Sources/Actions/Search.php b/Sources/Actions/Search.php index 41e46ab51a..7d5a9f39f9 100644 --- a/Sources/Actions/Search.php +++ b/Sources/Actions/Search.php @@ -18,7 +18,7 @@ use SMF\ActionInterface; use SMF\ActionRouter; use SMF\ActionTrait; -use SMF\Category; +use SMF\Board; use SMF\Config; use SMF\Db\DatabaseApi as Db; use SMF\ErrorHandler; @@ -70,6 +70,7 @@ public function execute(): void // Don't load this in XML mode. if (!isset($_REQUEST['xml'])) { Theme::loadTemplate('Search'); + Theme::loadTemplate('GenericControls'); Theme::loadJavaScriptFile('suggest.js', ['defer' => false, 'minimize' => true], 'smf_suggest'); } @@ -174,91 +175,18 @@ public function execute(): void } } - // Find all the boards this user is allowed to see. - $request = Db::$db->query( - 'SELECT b.id_cat, c.name AS cat_name, b.id_board, b.name, b.child_level - FROM {db_prefix}boards AS b - LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat) - WHERE {query_see_board} - AND redirect = {string:empty_string}', - [ - 'empty_string' => '', - ], - identifier: 'order_by_board_order', - ); - Utils::$context['num_boards'] = Db::$db->num_rows($request); - Utils::$context['boards_check_all'] = true; - Utils::$context['categories'] = []; - - while ($row = Db::$db->fetch_assoc($request)) { - // This category hasn't been set up yet.. - if (!isset(Utils::$context['categories'][$row['id_cat']])) { - Utils::$context['categories'][$row['id_cat']] = [ - 'id' => $row['id_cat'], - 'name' => $row['cat_name'], - 'boards' => [], - ]; - } - - $is_recycle_board = !empty(Config::$modSettings['recycle_enable']) && $row['id_board'] == Config::$modSettings['recycle_board']; - - // Set this board up, and let the template know when it's a child. (indent them..) - Utils::$context['categories'][$row['id_cat']]['boards'][$row['id_board']] = [ - 'id' => $row['id_board'], - 'name' => $row['name'], - 'child_level' => $row['child_level'], - ]; - - // If user selected some particular boards, is this one of them? - if (!empty(Utils::$context['search_params']['brd'])) { - Utils::$context['categories'][$row['id_cat']]['boards'][$row['id_board']]['selected'] = \in_array($row['id_board'], Utils::$context['search_params']['brd']); - } - // User didn't select any boards, so select all except ignored and recycle boards. - else { - Utils::$context['categories'][$row['id_cat']]['boards'][$row['id_board']]['selected'] = !$is_recycle_board && !\in_array($row['id_board'], User::$me->ignoreboards); - } - - // If a board wasn't checked that probably should have been ensure the board selection is selected, yo! - if (!Utils::$context['categories'][$row['id_cat']]['boards'][$row['id_board']]['selected'] && !$is_recycle_board) { - Utils::$context['boards_check_all'] = false; - } - } - Db::$db->free_result($request); - - Category::sort(Utils::$context['categories']); - - // Now, let's sort the list of categories into the boards for templates that like that. - $temp_boards = []; - - foreach (Utils::$context['categories'] as $category) { - $temp_boards[] = [ - 'name' => $category['name'], - 'child_ids' => array_keys($category['boards']), - ]; - $temp_boards = array_merge($temp_boards, array_values($category['boards'])); - - // Include a list of boards per category for easy toggling. - Utils::$context['categories'][$category['id']]['child_ids'] = array_keys($category['boards']); + // If user selected some particular boards, is this one of them? + if (!empty(Utils::$context['search_params']['brd'])) { + $boards = Utils::$context['search_params']['brd']; } - - $max_boards = ceil(\count($temp_boards) / 2); - - if ($max_boards == 1) { - $max_boards = 2; + // User didn't select any boards, so select all except ignored and recycle boards. + elseif (!empty(Config::$modSettings['recycle_enable']) && !empty(Config::$modSettings['recycle_board'])) { + $boards = array_merge(User::$me->ignoreboards, [(int) Config::$modSettings['recycle_board']]); + } else { + $boards = User::$me->ignoreboards; } - // Now, alternate them so they can be shown left and right ;). - Utils::$context['board_columns'] = []; - - for ($i = 0; $i < $max_boards; $i++) { - Utils::$context['board_columns'][] = $temp_boards[$i]; - - if (isset($temp_boards[$i + $max_boards])) { - Utils::$context['board_columns'][] = $temp_boards[$i + $max_boards]; - } else { - Utils::$context['board_columns'][] = []; - } - } + Utils::$context['categories'] = Board::getUserVisibleBoards($boards); if (!empty($_REQUEST['topic'])) { Utils::$context['search_params']['topic'] = (int) $_REQUEST['topic']; diff --git a/Sources/Board.php b/Sources/Board.php index d59edff048..260331e10a 100644 --- a/Sources/Board.php +++ b/Sources/Board.php @@ -1108,6 +1108,59 @@ public static function getMsgMemberID(int $messageID): int return (int) $memberID; } + /** + * Fetches the list of boards the user is allowed to see and organizes them by categories. + * + * This function queries the database for boards visible to the current user, grouped by categories. + * It returns a structured array of categories and their associated boards. + * + * @param array $boards An array of board IDs to mark as selected. + * @return array The structured array of categories and boards. + */ + public static function getUserVisibleBoards(array $boards): array + { + // Query to fetch boards visible to the user. + $request = Db::$db->query( + 'order_by_board_order', + 'SELECT id_board, b.name, child_level, c.name AS cat_name, id_cat + FROM {db_prefix}boards AS b + JOIN {db_prefix}categories AS c USING (id_cat) + WHERE {query_see_board} + AND redirect = {string:empty_string} + ORDER BY board_order', + [ + 'empty_string' => '', + ], + ); + + $categories = []; + $categoryTracker = []; + $currentCategoryIndex = -1; + + // Process the results and group boards by categories. + while ($row = Db::$db->fetch_assoc($request)) { + if (!isset($categoryTracker[$row['id_cat']])) { + $categories[++$currentCategoryIndex] = [ + 'id' => (int) $row['id_cat'], + 'name' => $row['cat_name'], + 'boards' => [], + ]; + $categoryTracker[$row['id_cat']] = true; + } + + $categories[$currentCategoryIndex]['boards'][] = [ + 'id' => (int) $row['id_board'], + 'name' => $row['name'], + 'child_level' => (int) $row['child_level'], + 'selected' => \in_array($row['id_board'], $boards), + ]; + } + + Db::$db->free_result($request); + + return $categories; + } + /** * Modify the settings and position of a board. * Used by ManageBoards.php to change the settings of a board.