Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loads all categories in Category::getTree(), not just populated ones #7912

Merged
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
8 changes: 6 additions & 2 deletions Sources/Alert.php
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ public static function load(int|array $ids = [], array $query_customizations = [
$joins = $query_customizations['joins'] ?? [];
$where = $query_customizations['where'] ?? [];
$order = $query_customizations['order'] ?? ['a.id_alert DESC'];
$group = $query_customizations['group'] ?? [];
$limit = $query_customizations['limit'] ?? min(!empty(Config::$modSettings['alerts_per_page']) ? Config::$modSettings['alerts_per_page'] : 1000, 1000);
$params = $query_customizations['params'] ?? [];

Expand Down Expand Up @@ -1594,20 +1595,23 @@ protected static function deleteInvisible(array &$alerts, int $memID): void
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int|string $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
* @return Generator<array> Iterating over the result gives database rows.
*/
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], int|string $limit = 0)
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], array $group = [], int|string $limit = 0)
{
$request = Db::$db->query(
'',
'SELECT
' . implode(', ', $selects) . '
FROM {db_prefix}user_alerts AS a' . (empty($joins) ? '' : '
' . implode("\n\t\t\t\t", $joins)) . (empty($where) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($order) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($group) ? '' : '
GROUP BY ' . implode(', ', $group)) . (empty($order) ? '' : '
ORDER BY ' . implode(', ', $order)) . (!empty($limit) ? '
LIMIT ' . $limit : ''),
$params,
Expand Down
5 changes: 3 additions & 2 deletions Sources/Board.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class Board implements \ArrayAccess
'getModeratorGroups' => 'getBoardModeratorGroups',
'isChildOf' => 'isChildOf',
'getParents' => 'getBoardParents',
'queryData' => 'queryData',
],
'prop_names' => [
'board_id' => 'board',
Expand Down Expand Up @@ -2189,12 +2188,14 @@ public static function getParents(int $id_parent): array
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
* @return Generator<array> Iterating over the result gives database rows.
*/
public static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], int $limit = 0)
public static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], array $group = [], int $limit = 0)
{
// If we only want some child boards, use a CTE query for improved performance.
if (!empty($params['id_parent']) && in_array('b.id_parent != 0', $where) && Db::$db->cte_support()) {
Expand Down
66 changes: 55 additions & 11 deletions Sources/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,26 +262,22 @@ public function unparseDescription(): void
/**
* Loads categories by ID number and/or by custom query.
*
* If both arguments are empty, loads nothing.
* If both arguments are empty, loads all categories.
*
* @param array|int $ids The ID numbers of zero or more boards.
* @param array|int $ids The ID numbers of zero or more categories.
* @param array $query_customizations Customizations to the SQL query.
* @return array Instances of this class for the loaded boards.
* @return array Instances of this class for the loaded categories.
*/
public static function load(array|int $ids = [], array $query_customizations = []): array
{
$loaded = [];

$ids = array_unique(array_map('intval', (array) $ids));

if (empty($query_customizations) && empty($ids)) {
return $loaded;
}

$selects = $query_customizations['selects'] ?? ['c.*'];
$joins = $query_customizations['joins'] ?? [];
$where = $query_customizations['where'] ?? [];
$order = $query_customizations['order'] ?? [];
$order = $query_customizations['order'] ?? ['c.cat_order'];
$group = $query_customizations['group'] ?? [];
$limit = $query_customizations['limit'] ?? 0;
$params = $query_customizations['params'] ?? [];
Expand All @@ -291,7 +287,7 @@ public static function load(array|int $ids = [], array $query_customizations = [
$params['ids'] = $ids;
}

foreach (Board::queryData($selects, $params, $joins, $where, $order, $group, $limit) as $row) {
foreach (self::queryData($selects, $params, $joins, $where, $order, $group, $limit) as $row) {
$row['id_cat'] = (int) $row['id_cat'];

if (isset(self::$loaded[$row['id_cat']])) {
Expand Down Expand Up @@ -674,7 +670,7 @@ public static function getTree(): void
'c.name AS cat_name', 'c.description AS cat_desc',
];
$params = [];
$joins = ['LEFT JOIN {db_prefix}categories AS c ON (b.id_cat = c.id_cat)'];
$joins = ['LEFT JOIN {db_prefix}boards AS b ON (b.id_cat = c.id_cat)'];
$where = ['{query_see_board}'];
$order = ['c.cat_order', 'b.child_level', 'b.board_order'];

Expand All @@ -690,8 +686,10 @@ public static function getTree(): void
// Getting all the board and category information you'd ever wanted.
self::$loaded = [];
$last_board_order = 0;
$prevBoard = 0;
$curLevel = 0;

foreach (Board::queryData($selects, $params, $joins, $where, $order) as $row) {
foreach (self::queryData($selects, $params, $joins, $where, $order) as $row) {
if (!isset(self::$loaded[$row['id_cat']])) {
self::init($row['id_cat'], [
'name' => $row['cat_name'],
Expand Down Expand Up @@ -845,6 +843,52 @@ function ($a, $b) {
$this->is_first = true;
}
}

/*************************
* Internal static methods
*************************/

/**
* Generator that runs queries about category data and yields the result rows.
*
* @param array $selects Table columns to select.
* @param array $params Parameters to substitute into query text.
* @param array $joins Zero or more *complete* JOIN clauses.
* E.g.: 'LEFT JOIN {db_prefix}boards AS b ON (c.id_cat = b.id_cat)'
* Note: 'FROM {db_prefix}categories AS c' is always part of the query.
* @param array $where Zero or more conditions for the WHERE clause.
* Conditions will be placed in parentheses and concatenated with AND.
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int|string $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
* @return Generator<array> Iterating over the result gives database rows.
*/
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], array $group = [], int|string $limit = 0)
{
$request = Db::$db->query(
'',
'SELECT
' . implode(', ', $selects) . '
FROM {db_prefix}categories AS c' . (empty($joins) ? '' : '
' . implode("\n\t\t\t\t", $joins)) . (empty($where) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($group) ? '' : '
GROUP BY ' . implode(', ', $group)) . (empty($order) ? '' : '
ORDER BY ' . implode(', ', $order)) . (!empty($limit) ? '
LIMIT ' . $limit : ''),
$params,
);

while ($row = Db::$db->fetch_assoc($request)) {
yield $row;
}

Db::$db->free_result($request);
}
}

// Export public static functions and properties to global namespace for backward compatibility.
Expand Down
12 changes: 8 additions & 4 deletions Sources/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,7 @@ public static function get(string $low_date, string $high_date, bool $use_permis
'cal.end_date >= {date:low_date}',
];
$order = $query_customizations['order'] ?? [];
$group = $query_customizations['group'] ?? [];
$limit = $query_customizations['limit'] ?? 0;
$params = $query_customizations['params'] ?? [
'high_date' => $high_date,
Expand All @@ -966,9 +967,9 @@ public static function get(string $low_date, string $high_date, bool $use_permis
$where[] = '(cal.id_board = {int:no_board_link} OR {query_wanna_see_board})';
}

IntegrationHook::call('integrate_query_event', [&$selects, &$params, &$joins, &$where, &$order, &$limit]);
IntegrationHook::call('integrate_query_event', [&$selects, &$params, &$joins, &$where, &$order, &$group, &$limit]);

foreach(self::queryData($selects, $params, $joins, $where, $order, $limit) as $row) {
foreach(self::queryData($selects, $params, $joins, $where, $order, $group, $limit) as $row) {
// If the attached topic is not approved then for the moment pretend it doesn't exist.
if (!empty($row['id_first_msg']) && Config::$modSettings['postmod_active'] && !$row['approved']) {
continue;
Expand Down Expand Up @@ -1169,20 +1170,23 @@ protected function fixEndDate(): void
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int|string $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
* @return Generator<array> Iterating over the result gives database rows.
*/
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], int|string $limit = 0)
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], array $group = [], int|string $limit = 0)
{
$request = Db::$db->query(
'',
'SELECT
' . implode(', ', $selects) . '
FROM {db_prefix}calendar AS cal' . (empty($joins) ? '' : '
' . implode("\n\t\t\t\t", $joins)) . (empty($where) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($order) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($group) ? '' : '
GROUP BY ' . implode(', ', $group)) . (empty($order) ? '' : '
ORDER BY ' . implode(', ', $order)) . (!empty($limit) ? '
LIMIT ' . $limit : ''),
$params,
Expand Down
2 changes: 2 additions & 0 deletions Sources/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,8 @@ protected static function getLink(object $group): string
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int|string $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
Expand Down
12 changes: 8 additions & 4 deletions Sources/Msg.php
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ public static function get($ids, array $query_customizations = [])
$order = $query_customizations['order'] ?? [
'm.id_msg' . (empty(Theme::$current->options['view_newest_first']) ? '' : ' DESC'),
];
$group = $query_customizations['group'] ?? [];
$limit = $query_customizations['limit'] ?? 0;
$params = $query_customizations['params'] ?? [
'new_from' => Topic::$info->new_from ?? Config::$modSettings['maxMsgID'] + 1,
Expand All @@ -587,9 +588,9 @@ public static function get($ids, array $query_customizations = [])
// Just FYI, for historical reasons the order in which the arguments are
// passed to this hook is different than the order in which they are
// passed to the queryData() method.
IntegrationHook::call('integrate_query_message', [&$selects, &$joins, &$params, &$where, &$order, &$limit]);
IntegrationHook::call('integrate_query_message', [&$selects, &$joins, &$params, &$where, &$order, &$group, &$limit]);

foreach(self::queryData($selects, $params, $joins, $where, $order, $limit) as $row) {
foreach(self::queryData($selects, $params, $joins, $where, $order, $group, $limit) as $row) {
$id = (int) $row['id_msg'];

yield (new self($id, $row));
Expand Down Expand Up @@ -3009,20 +3010,23 @@ public static function spell_suggest($dict, $word): array
* If this is left empty, no WHERE clause will be used.
* @param array $order Zero or more conditions for the ORDER BY clause.
* If this is left empty, no ORDER BY clause will be used.
* @param array $group Zero or more conditions for the GROUP BY clause.
* If this is left empty, no GROUP BY clause will be used.
* @param int|string $limit Maximum number of results to retrieve.
* If this is left empty, all results will be retrieved.
*
* @return Generator<array> Iterating over the result gives database rows.
*/
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], int|string $limit = 0)
protected static function queryData(array $selects, array $params = [], array $joins = [], array $where = [], array $order = [], array $group = [], int|string $limit = 0)
{
self::$messages_request = Db::$db->query(
'',
'SELECT
' . implode(', ', $selects) . '
FROM {db_prefix}messages AS m' . (empty($joins) ? '' : '
' . implode("\n\t\t\t\t", $joins)) . (empty($where) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($order) ? '' : '
WHERE (' . implode(') AND (', $where) . ')') . (empty($group) ? '' : '
GROUP BY ' . implode(', ', $group)) . (empty($order) ? '' : '
ORDER BY ' . implode(', ', $order)) . (!empty($limit) ? '
LIMIT ' . $limit : ''),
$params,
Expand Down
3 changes: 2 additions & 1 deletion Sources/Search/SearchResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ public static function get($ids, array $query_customizations = [])
Db::$db->custom_order('m.id_msg', $ids),
];

$group = $query_customizations['group'] ?? [];
$limit = $query_customizations['limit'] ?? '{int:limit}';

$params = $query_customizations['params'] ?? [
Expand All @@ -475,7 +476,7 @@ public static function get($ids, array $query_customizations = [])
$params['message_list'] = self::$messages_to_get = array_filter(array_unique(array_map('intval', (array) $ids)));
}

foreach(self::queryData($selects, $params, $joins, $where, $order, $limit) as $row) {
foreach(self::queryData($selects, $params, $joins, $where, $order, $group, $limit) as $row) {
$id = (int) $row['id_msg'];

yield (new self($id, $row));
Expand Down
Loading