Passed
Pull Request — release-2.1 (#5958)
by John
03:43
created

getBoardIndex_assign_mods()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 13
nc 9
nop 3
dl 0
loc 23
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file currently only contains one function to collect the data needed to
5
 * show a list of boards for the board index and the message index.
6
 *
7
 * Simple Machines Forum (SMF)
8
 *
9
 * @package SMF
10
 * @author Simple Machines https://www.simplemachines.org
11
 * @copyright 2020 Simple Machines and individual contributors
12
 * @license https://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1 RC2
15
 */
16
17
if (!defined('SMF'))
18
	die('No direct access...');
19
20
/**
21
 * Fetches a list of boards and (optional) categories including
22
 * statistical information, child boards and moderators.
23
 * 	- Used by both the board index (main data) and the message index (child
24
 * boards).
25
 * 	- Depending on the include_categories setting returns an associative
26
 * array with categories->boards->child_boards or an associative array
27
 * with boards->child_boards.
28
 *
29
 * @param array $boardIndexOptions An array of boardindex options
30
 * @return array An array of information for displaying the boardindex
31
 */
32
function getBoardIndex($boardIndexOptions)
33
{
34
	global $smcFunc, $scripturl, $user_info, $modSettings, $txt;
35
	global $settings, $options, $context, $sourcedir;
36
37
	// For performance, track the latest post while going through the
38
	// boards. We only want to call timeformat() once if we can help it.
39
	$latest_post = array(
40
		'timestamp' => 0,
41
		'ref' => 0,
42
	);
43
44
	// Children can affect parents, so we need to gather all the boards first and then process them after.
45
	$row_boards = getBoardIndex_query($boardIndexOptions);
46
47
	$categories = array();
48
	$this_category = array();
49
	$boards = array();
50
51
	// Run through the categories and boards (or only boards)....
52
	for (reset($row_boards); key($row_boards) !== null; next($row_boards))
53
	{
54
		$row_board = current($row_boards);
55
56
		// Perhaps we are ignoring this board?
57
		$ignoreThisBoard = in_array($row_board['id_board'], $user_info['ignoreboards']);
58
		$row_board['is_read'] = !empty($row_board['is_read']) || $ignoreThisBoard ? '1' : '0';
59
60
		if ($boardIndexOptions['include_categories'])
61
		{
62
			// Haven't set this category yet.
63
			if (empty($categories[$row_board['id_cat']]))
64
			{
65
				$name = parse_bbc($row_board['cat_name'], false, '', $context['description_allowed_tags']);
66
				$description = parse_bbc($row_board['cat_desc'], false, '', $context['description_allowed_tags']);
67
68
				$categories[$row_board['id_cat']] = array(
69
					'id' => $row_board['id_cat'],
70
					'name' => $name,
71
					'description' => $description,
72
					'is_collapsed' => $row_board['can_collapse'] == 1 && !empty($options['collapse_category_' . $row_board['id_cat']]),
73
					'can_collapse' => !$user_info['is_guest'] && $row_board['can_collapse'] == 1,
74
					'href' => $scripturl . '#c' . $row_board['id_cat'],
75
					'boards' => array(),
76
					'new' => false,
77
					'css_class' => '',
78
					'link' => '<a id="c' . $row_board['id_cat'] . '"></a>' . (!$user_info['is_guest'] ? '<a href="' . $scripturl . '?action=unread;c=' . $row_board['id_cat'] . '" title="' . sprintf($txt['new_posts_in_category'], $name) . '">' . $name . '</a>' : $name),
79
				);
80
			}
81
82
			// If this board has new posts in it (and isn't the recycle bin!) then the category is new.
83
			if (empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $row_board['id_board'])
84
				$categories[$row_board['id_cat']]['new'] |= empty($row_board['is_read']);
85
86
			// Avoid showing category unread link where it only has redirection boards.
87
			$categories[$row_board['id_cat']]['show_unread'] = !empty($categories[$row_board['id_cat']]['show_unread']) ? 1 : !$row_board['is_redirect'];
88
89
			// Let's save some typing.  Climbing the array might be slower, anyhow.
90
			$this_category = &$categories[$row_board['id_cat']]['boards'];
91
		}
92
93
		// This is a parent board.
94
		$isChild = false;
95
		if ($row_board['id_parent'] == $boardIndexOptions['parent_id'])
96
		{
97
			$boards[] = $row_board['id_board'];
98
99
			// We might or might not have already added this board, so...
100
			if (!isset($this_category[$row_board['id_board']]))
101
				$this_category[$row_board['id_board']] = array();
102
103
			$board_name = parse_bbc($row_board['board_name'], false, '', $context['description_allowed_tags']);
104
			$board_description = parse_bbc($row_board['description'], false, '', $context['description_allowed_tags']);
105
106
			// !!! Reoving this union messes with the board hierarchy.
107
			$this_category[$row_board['id_board']] += array(
108
				'new' => empty($row_board['is_read']),
109
				'id' => $row_board['id_board'],
110
				'type' => 'board',
111
				'name' => $board_name,
112
				'description' => $board_description,
113
				'moderators' => array(),
114
				'moderator_groups' => array(),
115
				'link_moderators' => array(),
116
				'link_moderator_groups' => array(),
117
				'children' => array(),
118
				'link_children' => array(),
119
				'children_new' => false,
120
				'topics' => $row_board['num_topics'],
121
				'posts' => $row_board['num_posts'],
122
				'is_redirect' => $row_board['is_redirect'],
123
				'unapproved_topics' => $row_board['unapproved_topics'],
124
				'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'],
125
				'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])),
126
				'href' => $scripturl . '?board=' . $row_board['id_board'] . '.0',
127
				'link' => '<a href="' . $scripturl . '?board=' . $row_board['id_board'] . '.0">' . $board_name . '</a>',
128
				'board_tooltip' => $txt['old_posts'],
129
				'board_class' => 'off',
130
				'css_class' => '',
131
			);
132
133
			// We can do some of the figuring-out-what-icon now.
134
			// For certain types of thing we also set up what the tooltip is.
135
			if ($this_category[$row_board['id_board']]['is_redirect'])
136
			{
137
				$this_category[$row_board['id_board']]['type'] = 'redirect';
138
				$this_category[$row_board['id_board']]['board_class'] = 'redirect';
139
				$this_category[$row_board['id_board']]['board_tooltip'] = $txt['redirect_board'];
140
			}
141
			elseif ($this_category[$row_board['id_board']]['new'] || $context['user']['is_guest'])
142
			{
143
				// If we're showing to guests, we want to give them the idea that something interesting is going on!
144
				$this_category[$row_board['id_board']]['board_class'] = 'on';
145
				$this_category[$row_board['id_board']]['board_tooltip'] = $txt['new_posts'];
146
			}
147
		}
148
		// This is a child board.
149
		elseif (isset($row_boards[$row_board['id_parent']]['id_parent']) && $row_boards[$row_board['id_parent']]['id_parent'] == $boardIndexOptions['parent_id'])
150
		{
151
			$isChild = true;
152
153
			// Ensure the parent has at least the most important info defined
154
			if (!isset($this_category[$row_board['id_parent']]))
155
				$this_category[$row_board['id_parent']] = array(
156
					'children' => array(),
157
					'children_new' => false,
158
					'board_class' => 'off',
159
				);
160
161
			$board_name = parse_bbc($row_board['board_name'], false, '', $context['description_allowed_tags']);
162
			$board_description = parse_bbc($row_board['description'], false, '', $context['description_allowed_tags']);
163
164
			$this_category[$row_board['id_parent']]['children'][$row_board['id_board']] = array(
165
				'id' => $row_board['id_board'],
166
				'name' => $board_name,
167
				'description' => $board_description,
168
				'short_description' => shorten_subject($board_description, 128),
169
				'new' => empty($row_board['is_read']),
170
				'topics' => $row_board['num_topics'],
171
				'posts' => $row_board['num_posts'],
172
				'is_redirect' => $row_board['is_redirect'],
173
				'unapproved_topics' => $row_board['unapproved_topics'],
174
				'unapproved_posts' => $row_board['unapproved_posts'] - $row_board['unapproved_topics'],
175
				'can_approve_posts' => !empty($user_info['mod_cache']['ap']) && ($user_info['mod_cache']['ap'] == array(0) || in_array($row_board['id_board'], $user_info['mod_cache']['ap'])),
176
				'href' => $scripturl . '?board=' . $row_board['id_board'] . '.0',
177
				'link' => '<a href="' . $scripturl . '?board=' . $row_board['id_board'] . '.0">' . $board_name . '</a>'
178
			);
179
180
			// Counting child board posts in the parent's totals?
181
			if (!empty($boardIndexOptions['countChildPosts']) && !$row_board['is_redirect'])
182
			{
183
				$row_boards[$row_board['id_parent']]['num_posts'] += $row_board['num_posts'];
184
				$row_boards[$row_board['id_parent']]['num_topics'] += $row_board['num_topics'];
185
			}
186
187
			// Does this board contain new boards?
188
			$this_category[$row_board['id_parent']]['children_new'] |= empty($row_board['is_read']);
189
190
			// Update the icon if appropriate
191
			if ($this_category[$row_board['id_parent']]['children_new'] && $this_category[$row_board['id_parent']]['board_class'] == 'off')
192
			{
193
				$this_category[$row_board['id_parent']]['board_class'] = 'on2';
194
				$this_category[$row_board['id_parent']]['board_tooltip'] = $txt['new_posts'];
195
			}
196
197
			// This is easier to use in many cases for the theme....
198
			$this_category[$row_board['id_parent']]['link_children'][] = &$this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['link'];
199
		}
200
		// A further descendent (grandchild, great-grandchild, etc.)
201
		else
202
		{
203
			// Propagate some values to the parent board
204
			if (isset($row_boards[$row_board['id_parent']]))
205
			{
206
				$row_boards[$row_board['id_parent']]['is_read'] |= $row_board['is_read'];
207
208
				if (!empty($boardIndexOptions['countChildPosts']) && !$row_board['is_redirect'])
209
				{
210
					$row_boards[$row_board['id_parent']]['num_posts'] += $row_board['num_posts'];
211
					$row_boards[$row_board['id_parent']]['num_topics'] += $row_board['num_topics'];
212
				}
213
214
				if ($row_boards[$row_board['id_parent']]['poster_time'] < $row_board['poster_time'])
215
				{
216
					$row_boards[$row_board['id_parent']]['id_msg'] = $row_board['id_msg'];
217
					$row_boards[$row_board['id_parent']]['subject'] = $row_board['subject'];
218
					$row_boards[$row_board['id_parent']]['poster_time'] = $row_board['poster_time'];
219
					$row_boards[$row_board['id_parent']]['short_subject'] = (!empty($row_board['short_subject']) ? $row_board['short_subject'] : '');
220
					$row_boards[$row_board['id_parent']]['poster_name'] = $row_board['poster_name'];
221
					$row_boards[$row_board['id_parent']]['real_name'] = $row_board['real_name'];
222
					$row_boards[$row_board['id_parent']]['id_member'] = $row_board['id_member'];
223
					$row_boards[$row_board['id_parent']]['id_topic'] = $row_board['id_topic'];
224
					$row_boards[$row_board['id_parent']]['new_from'] = $row_board['new_from'];
225
226
					if (!empty($settings['avatars_on_boardIndex']))
227
					{
228
						$row_boards[$row_board['id_parent']]['avatar'] = $row_board['avatar'];
229
						$row_boards[$row_board['id_parent']]['email_address'] = $row_board['email_address'];
230
						$row_boards[$row_board['id_parent']]['member_filename'] = !empty($row_board['member_filename']) ? $row_board['member_filename'] : '';
231
					}
232
				}
233
			}
234
235
			continue;
236
		}
237
238
		// Prepare the subject, and make sure it's not too long.
239
		censorText($row_board['subject']);
240
		$row_board['short_subject'] = shorten_subject($row_board['subject'], 24);
241
242
		/* The board's and children's 'last_post's have:
243
		time, timestamp (a number that represents the time.), id (of the post), topic (topic id.),
244
		link, href, subject, start (where they should go for the first unread post.),
245
		and member. (which has id, name, link, href, username in it.) */
246
		$this_last_post = array(
247
			'id' => $row_board['id_msg'],
248
			'time' => $row_board['poster_time'],
249
			'timestamp' => forum_time(true, $row_board['poster_time']),
250
			'subject' => $row_board['short_subject'],
251
			'member' => array(
252
				'id' => $row_board['id_member'],
253
				'username' => $row_board['poster_name'] != '' ? $row_board['poster_name'] : $txt['not_applicable'],
254
				'name' => $row_board['real_name'],
255
				'href' => $row_board['poster_name'] != '' && !empty($row_board['id_member']) ? $scripturl . '?action=profile;u=' . $row_board['id_member'] : '',
256
				'link' => $row_board['poster_name'] != '' ? (!empty($row_board['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row_board['id_member'] . '">' . $row_board['real_name'] . '</a>' : $row_board['real_name']) : $txt['not_applicable'],
257
			),
258
			'start' => 'msg' . $row_board['new_from'],
259
			'topic' => $row_board['id_topic'],
260
			'href' => '',
261
			'link' => $row_board['id_topic'],
262
			'last_post_message' => '',
263
		);
264
265
		if (!empty($settings['avatars_on_boardIndex']))
266
			$this_last_post['member']['avatar'] = set_avatar_data(array(
267
				'avatar' => $row_board['avatar'],
268
				'email' => $row_board['email_address'],
269
				'filename' => !empty($row_board['member_filename']) ? $row_board['member_filename'] : '',
270
			));
271
272
		// Provide the href and link.
273
		if ($row_board['subject'] != '')
274
		{
275
			$this_last_post['href'] = $scripturl . '?topic=' . $row_board['id_topic'] . '.msg' . ($user_info['is_guest'] ? $row_board['id_msg'] : $row_board['new_from']) . (empty($row_board['is_read']) ? ';boardseen' : '') . '#new';
276
			$this_last_post['link'] = '<a href="' . $this_last_post['href'] . '" title="' . $row_board['subject'] . '">' . $row_board['short_subject'] . '</a>';
277
		}
278
279
		// Set the last post in the parent board.
280
		if ($isChild && !empty($row_board['poster_time'])
281
			&& $row_boards[$row_board['id_parent']]['poster_time'] < $row_board['poster_time'])
282
			$this_category[$row_board['id_parent']]['last_post'] = $this_last_post;
283
284
		// Set the last post in the root board
285
		if (!$isChild && !empty($row_board['poster_time'])
286
			&& (empty($this_category[$row_board['id_board']]['last_post']['timestamp'])
287
				|| $this_category[$row_board['id_board']]['last_post']['timestamp'] < forum_time(true, $row_board['poster_time'])
288
				)
289
			)
290
			$this_category[$row_board['id_board']]['last_post'] = $this_last_post;
291
292
		// Just in the child...?
293
		if ($isChild)
294
			$this_category[$row_board['id_parent']]['children'][$row_board['id_board']]['last_post'] = $this_last_post;
295
296
		// Determine a global most recent topic.
297
		if (!empty($boardIndexOptions['set_latest_post']) && !empty($row_board['poster_time']) && $row_board['poster_time'] > $latest_post['timestamp'] && !$ignoreThisBoard)
298
			$latest_post = array(
299
				'timestamp' => $row_board['poster_time'],
300
				'ref' => &$this_category[$isChild ? $row_board['id_parent'] : $row_board['id_board']]['last_post'],
301
			);
302
	}
303
304
	getBoardIndex_mods($boardIndexOptions, $boards, $categories, $this_category);
305
306
	if ($boardIndexOptions['include_categories'])
307
		sortCategories($categories);
308
	else
309
		sortBoards($this_category);
310
311
	// By now we should know the most recent post...if we wanna know it that is.
312
	if (!empty($boardIndexOptions['set_latest_post']) && !empty($latest_post['ref']))
313
	{
314
		$latest_post['ref']['time'] = timeformat($latest_post['ref']['time']);
315
		$context['latest_post'] = $latest_post['ref'];
316
	}
317
318
	// I can't remember why but trying to make a ternary to get this all in one line is actually a Very Bad Idea.
319
	if ($boardIndexOptions['include_categories'])
320
		call_integration_hook('integrate_getboardtree', array($boardIndexOptions, &$categories));
321
	else
322
		call_integration_hook('integrate_getboardtree', array($boardIndexOptions, &$this_category));
323
324
	return $boardIndexOptions['include_categories'] ? $categories : $this_category;
325
}
326
327
/**
328
 * Helper function for getBoardIndex() that fetches the moderators
329
 * and moderator groups for the boards.
330
 *
331
 * @param array $boardIndexOptions An array of boardindex options
332
 * @param array $boards List of board IDs
333
 * @param array &$categories
334
 * @param array &$this_category
335
 */
336
function getBoardIndex_mods(array $boardIndexOptions, array $boards, array &$categories, array &$this_category)
337
{
338
	global $sourcedir;
339
340
	require_once($sourcedir . '/Subs-Boards.php');
341
	$moderators = getBoardModerators($boards);
342
	$groups = getBoardModeratorGroups($boards);
343
344
	if ($boardIndexOptions['include_categories'])
345
	{
346
		foreach ($categories as &$category)
347
			getBoardIndex_assign_mods($category['boards'], $moderators, $groups);
348
	}
349
	else
350
		getBoardIndex_assign_mods($this_category, $moderators, $groups);
351
}
352
353
/**
354
 * Helper function for getBoardIndex_mods() that assigns the moderators
355
 * and moderator groups to the boards.
356
 *
357
 * @param array &$boards
358
 * @param array $moderators Result of getBoardModerators()
359
 * @param array $groups Result of getBoardModeratorGroups()
360
 */
361
function getBoardIndex_assign_mods(array &$boards, array $moderators, array $groups)
362
{
363
	global $txt;
364
365
	foreach ($boards as &$board)
366
	{
367
		if (!empty($moderators[$board['id']]))
368
		{
369
			$board['moderators'] = $moderators[$board['id']];
370
			foreach ($moderators[$board['id']] as $moderator)
371
				$board['link_moderators'][] = $moderator['link'];
372
		}
373
		if (!empty($groups[$board['id']]))
374
		{
375
			$board['moderator_groups'] = $groups[$board['id']];
376
			foreach ($groups[$board['id']] as $group)
377
			{
378
				$board['link_moderators'][] = $group['link'];
379
				$board['link_moderator_groups'][] = $group['link'];
380
			}
381
		}
382
		if (!empty($board['last_post']))
383
			$board['last_post']['last_post_message'] = sprintf($txt['last_post_message'], $board['last_post']['member']['link'], $board['last_post']['link'], $board['last_post']['time'] > 0 ? timeformat($board['last_post']['time']) : $txt['not_applicable']);
384
	}
385
}
386
387
/**
388
 * Helper function for getBoardIndex() that executes the xquery
389
 * required to fetch the boards.
390
 *
391
 * @param array $boardIndexOptions An array of boardindex options
392
 * @return array An array of board values directly from the SQL
393
 */
394
function getBoardIndex_query(array $boardIndexOptions)
395
{
396
	global $smcFunc, $modSettings, $user_info;
397
398
	// This setting is not allowed to be empty
399
	if (empty($modSettings['boardindex_max_depth']))
400
		$modSettings['boardindex_max_depth'] = 1;
401
402
	$query_select = array(
403
		'b.id_board',
404
		'b.name AS board_name',
405
		'b.description',
406
		'CASE WHEN b.redirect != {string:blank_string} THEN 1 ELSE 0 END AS is_redirect',
407
		'b.num_posts',
408
		'b.num_topics',
409
		'b.unapproved_posts',
410
		'b.unapproved_topics',
411
		'b.id_parent',
412
		'COALESCE(m.poster_time, 0) AS poster_time',
413
		'COALESCE(mem.member_name, m.poster_name) AS poster_name',
414
		'm.subject',
415
		'm.id_topic',
416
		'COALESCE(mem.real_name, m.poster_name) AS real_name',
417
		'COALESCE(mem.id_member, 0) AS id_member',
418
		'mem.avatar',
419
		'm.id_msg',
420
	);
421
	$query_join = array(
422
		'LEFT JOIN {db_prefix}messages AS m ON (m.id_msg = b.id_last_msg)',
423
		'LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)',
424
	);
425
	$query_sort = array(
426
		'b.child_level DESC',
427
		'b.board_order DESC',
428
	);
429
	$query_params = array(
430
		'current_member' => $user_info['id'],
431
		'child_level' => $boardIndexOptions['base_level'],
432
		'max_child_level' => $boardIndexOptions['base_level'] + $modSettings['boardindex_max_depth'],
433
		'blank_string' => '',
434
		'id_parent' => $boardIndexOptions['parent_id'],
435
	);
436
437
	if ($boardIndexOptions['include_categories'])
438
	{
439
		$query_select = array_merge($query_select, array(
440
			'c.id_cat',
441
			'c.name AS cat_name',
442
			'c.description AS cat_desc',
443
			'c.can_collapse',
444
		));
445
		$query_join[] = 'LEFT JOIN {db_prefix}categories AS c ON (c.id_cat = b.id_cat)';
446
		$query_sort[] = 'c.cat_order';
447
	}
448
449
	if ($user_info['is_guest'])
450
	{
451
		$query_select = array_merge($query_select, array(
452
			'1 AS is_read',
453
			'0 AS new_from',
454
		));
455
	}
456
	else
457
	{
458
		$query_select = array_merge($query_select, array(
459
			'CASE WHEN COALESCE(lb.id_msg, 0) >= b.id_last_msg THEN 1 ELSE 0 END AS is_read',
460
			'COALESCE(lb.id_msg, -1) + 1 AS new_from',
461
		));
462
		$query_join[] = 'LEFT JOIN {db_prefix}log_boards AS lb ON (lb.id_board = b.id_board AND lb.id_member = {int:current_member})';
463
	}
464
465
	if (!empty($settings['avatars_on_boardIndex']))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $settings seems to never exist and therefore empty should always be true.
Loading history...
466
	{
467
		$query_select = array_merge($query_select, array(
468
			'mem.email_address',
469
			'mem.avatar',
470
			'COALESCE(am.id_attach, 0) AS member_id_attach',
471
			'am.filename AS member_filename',
472
			'am.attachment_type AS member_attach_type',
473
		));
474
		$query_join[] = 'LEFT JOIN {db_prefix}attachments AS am ON (am.id_member = m.id_member)';
475
	}
476
477
478
	// Find all boards and categories, as well as related information.
479
	// This will be sorted by the natural order of boards and categories, which we control.
480
	if ($boardIndexOptions['parent_id'] != 0 && $smcFunc['db_cte_support']())
481
		$result_boards = $smcFunc['db_query']('', '
482
			WITH RECURSIVE
483
				boards_cte (child_level, id_board, name , description, redirect, num_posts, num_topics, unapproved_posts, unapproved_topics, id_parent, id_msg_updated, id_cat, id_last_msg, board_order)
484
			AS
485
			(
486
				SELECT b.child_level, b.id_board, b.name , b.description, b.redirect, b.num_posts, b.num_topics, b.unapproved_posts, b.unapproved_topics, b.id_parent, b.id_msg_updated, b.id_cat, b.id_last_msg, b.board_order
487
				FROM {db_prefix}boards as b
488
				WHERE {query_see_board} AND b.id_board = {int:id_parent}
489
					UNION ALL
490
				SELECT b.child_level, b.id_board, b.name , b.description, b.redirect, b.num_posts, b.num_topics, b.unapproved_posts, b.unapproved_topics, b.id_parent, b.id_msg_updated, b.id_cat, b.id_last_msg, b.board_order
491
				FROM {db_prefix}boards as b
492
					JOIN boards_cte as bc ON (b.id_parent = bc.id_board)
493
				WHERE {query_see_board}
494
					AND b.child_level BETWEEN {int:child_level} AND {int:max_child_level}
495
			)
496
			SELECT ' .  implode(', ', $query_select) . '
497
			FROM boards_cte AS b
498
				' .  implode('
499
				', $query_join) . '
500
			WHERE b.id_parent != 0
501
			ORDER BY ' . implode(', ', $query_sort),
502
			$query_params
503
		);
504
	else
505
		$result_boards = $smcFunc['db_query']('', '
506
			SELECT ' .  implode(', ', $query_select) . '
507
			FROM {db_prefix}boards AS b
508
				' .  implode('
509
				', $query_join) . '
510
			WHERE {query_see_board}
511
				AND b.child_level BETWEEN {int:child_level} AND {int:max_child_level}
512
			ORDER BY ' . implode(', ', $query_sort),
513
			$query_params
514
		);
515
516
	$row_boards = array();
517
	foreach ($smcFunc['db_fetch_all']($result_boards) as $row)
518
		$row_boards[$row['id_board']] = $row;
519
520
	$smcFunc['db_free_result']($result_boards);
521
522
	return $row_boards;
523
}
524
525
?>