Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 11 additions & 83 deletions Sources/Actions/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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');
}

Expand Down Expand Up @@ -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'];
Expand Down
53 changes: 53 additions & 0 deletions Sources/Board.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down