MSZ_FORUM_ROOT, 'forum_name' => 'Forums', 'forum_children' => 0, 'forum_type' => MSZ_FORUM_TYPE_CATEGORY, 'forum_colour' => null, 'forum_permissions' => MSZ_FORUM_PERM_SET_READ, ]); function forum_is_valid_type(int $type): bool { return in_array($type, MSZ_FORUM_TYPES, true); } function forum_may_have_children(int $forumType): bool { return in_array($forumType, MSZ_FORUM_MAY_HAVE_CHILDREN); } function forum_may_have_topics(int $forumType): bool { return in_array($forumType, MSZ_FORUM_MAY_HAVE_TOPICS); } function forum_fetch(int $forumId, bool $showDeleted = false): array { $getForum = db_prepare(sprintf( ' SELECT `forum_id`, `forum_name`, `forum_type`, `forum_link`, `forum_archived`, `forum_link_clicks`, `forum_parent`, `forum_colour`, ( SELECT COUNT(`topic_id`) FROM `msz_forum_topics` WHERE `forum_id` = f.`forum_id` %1$s ) as `forum_topic_count` FROM `msz_forum_categories` as f WHERE `forum_id` = :forum_id ', $showDeleted ? '' : 'AND `topic_deleted` IS NULL' )); $getForum->bindValue('forum_id', $forumId); return db_fetch($getForum); } function forum_get_root_categories(int $userId): array { $getCategories = db_prepare(sprintf( ' SELECT f.`forum_id`, f.`forum_name`, f.`forum_type`, f.`forum_colour`, ( SELECT COUNT(`forum_id`) FROM `msz_forum_categories` AS sf WHERE sf.`forum_parent` = f.`forum_id` ) AS `forum_children`, (%2$s) AS `forum_permissions` FROM `msz_forum_categories` AS f WHERE f.`forum_parent` = 0 AND f.`forum_type` = %1$d AND f.`forum_hidden` = 0 GROUP BY f.`forum_id` HAVING (`forum_permissions` & %3$d) > 0 ORDER BY f.`forum_order` ', MSZ_FORUM_TYPE_CATEGORY, forum_perms_get_user_sql(MSZ_FORUM_PERMS_GENERAL, 'f.`forum_id`'), MSZ_FORUM_PERM_SET_READ )); $getCategories->bindValue('perm_user_id_user', $userId); $getCategories->bindValue('perm_user_id_role', $userId); $categories = array_merge([MSZ_FORUM_ROOT_DATA], db_fetch_all($getCategories)); $getRootForumCount = db_prepare(sprintf( " SELECT COUNT(`forum_id`) FROM `msz_forum_categories` WHERE `forum_parent` = %d AND `forum_type` != %d AND (%s & %d) > 0 ", MSZ_FORUM_ROOT, MSZ_FORUM_TYPE_CATEGORY, forum_perms_get_user_sql(MSZ_FORUM_PERMS_GENERAL, '`forum_id`'), MSZ_FORUM_PERM_SET_READ )); $getRootForumCount->bindValue('perm_user_id_user', $userId); $getRootForumCount->bindValue('perm_user_id_role', $userId); $categories[0]['forum_children'] = (int)($getRootForumCount->execute() ? $getRootForumCount->fetchColumn() : 0); return $categories; } function forum_get_breadcrumbs( int $forumId, string $linkFormat = '/forum/forum.php?f=%d', string $rootFormat = '/forum/#f%d', array $indexLink = ['Forums' => '/forum/'] ): array { $breadcrumbs = []; $getBreadcrumbs = db_prepare(' WITH RECURSIVE breadcrumbs(forum_id, forum_name, forum_parent, forum_type) as ( SELECT c.`forum_id`, c.`forum_name`, c.`forum_parent`, c.`forum_type` FROM `msz_forum_categories` as c WHERE `forum_id` = :forum_id UNION ALL SELECT p.`forum_id`, p.`forum_name`, p.`forum_parent`, p.`forum_type` FROM `msz_forum_categories` as p INNER JOIN breadcrumbs ON p.`forum_id` = breadcrumbs.forum_parent ) SELECT * FROM breadcrumbs '); $getBreadcrumbs->bindValue('forum_id', $forumId); $breadcrumbsDb = db_fetch_all($getBreadcrumbs); if (!$breadcrumbsDb) { return [$indexLink]; } foreach ($breadcrumbsDb as $breadcrumb) { $breadcrumbs[$breadcrumb['forum_name']] = sprintf( $breadcrumb['forum_parent'] === MSZ_FORUM_ROOT && $breadcrumb['forum_type'] === MSZ_FORUM_TYPE_CATEGORY ? $rootFormat : $linkFormat, $breadcrumb['forum_id'] ); } return array_reverse($breadcrumbs + $indexLink); } function forum_get_colour(int $forumId): int { $getColours = db_prepare(' WITH RECURSIVE breadcrumbs(forum_id, forum_parent, forum_colour) as ( SELECT c.`forum_id`, c.`forum_parent`, c.`forum_colour` FROM `msz_forum_categories` as c WHERE `forum_id` = :forum_id UNION ALL SELECT p.`forum_id`, p.`forum_parent`, p.`forum_colour` FROM `msz_forum_categories` as p INNER JOIN breadcrumbs ON p.`forum_id` = breadcrumbs.forum_parent ) SELECT * FROM breadcrumbs '); $getColours->bindValue('forum_id', $forumId); $colours = db_fetch_all($getColours); if ($colours) { foreach ($colours as $colour) { if ($colour['forum_colour'] !== null) { return $colour['forum_colour']; } } } return colour_none(); } function forum_increment_clicks(int $forumId): void { $incrementLinkClicks = db_prepare(sprintf(' UPDATE `msz_forum_categories` SET `forum_link_clicks` = `forum_link_clicks` + 1 WHERE `forum_id` = :forum_id AND `forum_type` = %d AND `forum_link_clicks` IS NOT NULL ', MSZ_FORUM_TYPE_LINK)); $incrementLinkClicks->bindValue('forum_id', $forumId); $incrementLinkClicks->execute(); } function forum_read_status_sql( string $topic_id_param, string $user_param_sub, string $forum_id_param = 'f.`forum_id`', string $user_param = '`target_user_id`' ): string { return sprintf( ' SELECT %1$s > 0 AND %2$s IS NOT NULL AND ( SELECT COUNT(ti.`topic_id`) FROM `msz_forum_topics` AS ti LEFT JOIN `msz_forum_topics_track` AS tt ON tt.`topic_id` = ti.`topic_id` AND tt.`user_id` = %4$s WHERE ti.`forum_id` = %3$s AND ti.`topic_deleted` IS NULL AND ti.`topic_bumped` >= NOW() - INTERVAL 1 MONTH AND ( tt.`track_last_read` IS NULL OR tt.`track_last_read` < ti.`topic_bumped` ) ) ', $user_param, $topic_id_param, $forum_id_param, $user_param_sub ); } define( 'MSZ_FORUM_GET_CHILDREN_QUERY_SMALL', ' SELECT :user_id AS `target_user_id`, f.`forum_id`, f.`forum_name`, (%1$s) AS `forum_unread`, (%4$s) AS `forum_permissions` FROM `msz_forum_categories` AS f LEFT JOIN `msz_forum_topics` AS t ON t.`topic_id` = ( SELECT `topic_id` FROM `msz_forum_topics` WHERE `forum_id` = f.`forum_id` AND `topic_deleted` IS NULL ORDER BY `topic_bumped` DESC LIMIT 1 ) WHERE `forum_parent` = :parent_id AND `forum_hidden` = false GROUP BY f.`forum_id` HAVING (`forum_permissions` & %5$d) > 0 ORDER BY f.`forum_order` ' ); define( 'MSZ_FORUM_GET_CHILDREN_QUERY_STANDARD', ' SELECT :user_id AS `target_user_id`, f.`forum_id`, f.`forum_name`, f.`forum_description`, f.`forum_type`, f.`forum_link`, f.`forum_link_clicks`, f.`forum_archived`, f.`forum_colour`, t.`topic_id` AS `recent_topic_id`, p.`post_id` AS `recent_post_id`, t.`topic_title` AS `recent_topic_title`, t.`topic_bumped` AS `recent_topic_bumped`, p.`post_created` AS `recent_post_created`, u.`user_id` AS `recent_post_user_id`, u.`username` AS `recent_post_username`, COALESCE(u.`user_colour`, r.`role_colour`) AS `recent_post_user_colour`, ( SELECT COUNT(`topic_id`) FROM `msz_forum_topics` WHERE `forum_id` = f.`forum_id` %6$s ) AS `forum_topic_count`, ( SELECT COUNT(`post_id`) FROM `msz_forum_posts` WHERE `forum_id` = f.`forum_id` %7$s ) AS `forum_post_count`, (%1$s) AS `forum_unread`, (%4$s) AS `forum_permissions` FROM `msz_forum_categories` AS f LEFT JOIN `msz_forum_topics` AS t ON t.`topic_id` = ( SELECT `topic_id` FROM `msz_forum_topics` WHERE `forum_id` = f.`forum_id` %6$s ORDER BY `topic_bumped` DESC LIMIT 1 ) LEFT JOIN `msz_forum_posts` AS p ON p.`post_id` = ( SELECT `post_id` FROM `msz_forum_posts` WHERE `topic_id` = t.`topic_id` %7$s ORDER BY `post_id` DESC LIMIT 1 ) LEFT JOIN `msz_users` AS u ON u.`user_id` = p.`user_id` LEFT JOIN `msz_roles` AS r ON r.`role_id` = u.`display_role` WHERE f.`forum_parent` = :parent_id AND f.`forum_hidden` = 0 AND ( (f.`forum_parent` = %2$d AND f.`forum_type` != %3$d) OR f.`forum_parent` != %2$d ) GROUP BY f.`forum_id` HAVING (`forum_permissions` & %5$d) > 0 ORDER BY f.`forum_order` ' ); function forum_get_children_query(bool $showDeleted = false, bool $small = false): string { return sprintf( $small ? MSZ_FORUM_GET_CHILDREN_QUERY_SMALL : MSZ_FORUM_GET_CHILDREN_QUERY_STANDARD, forum_read_status_sql('t.`topic_id`', ':user_for_check'), MSZ_FORUM_ROOT, MSZ_FORUM_TYPE_CATEGORY, forum_perms_get_user_sql(MSZ_FORUM_PERMS_GENERAL, 'f.`forum_id`'), MSZ_FORUM_PERM_SET_READ, $showDeleted ? '' : 'AND `topic_deleted` IS NULL', $showDeleted ? '' : 'AND `post_deleted` IS NULL' ); } function forum_get_children(int $parentId, int $userId, bool $showDeleted = false, bool $small = false): array { $getListing = db_prepare(forum_get_children_query($showDeleted, $small)); $getListing->bindValue('user_id', $userId); $getListing->bindValue('perm_user_id_user', $userId); $getListing->bindValue('perm_user_id_role', $userId); $getListing->bindValue('user_for_check', $userId); $getListing->bindValue('parent_id', $parentId); return db_fetch_all($getListing); } function forum_timeout(int $forumId, int $userId): int { $checkTimeout = db_prepare(' SELECT TIMESTAMPDIFF(SECOND, COALESCE(MAX(`post_created`), NOW() - INTERVAL 1 YEAR), NOW()) FROM `msz_forum_posts` WHERE `forum_id` = :forum_id AND `user_id` = :user_id '); $checkTimeout->bindValue('forum_id', $forumId); $checkTimeout->bindValue('user_id', $userId); return (int)($checkTimeout->execute() ? $checkTimeout->fetchColumn() : 0); }