497 lines
21 KiB
PHP
497 lines
21 KiB
PHP
<?php
|
|
namespace Misuzu\Forum;
|
|
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use stdClass;
|
|
use Index\Colour\Colour;
|
|
use Index\Db\{DbConnection,DbStatementCache,DbTools};
|
|
use Misuzu\Pagination;
|
|
use Misuzu\Users\UserInfo;
|
|
|
|
class ForumCategories {
|
|
private DbStatementCache $cache;
|
|
|
|
public function __construct(DbConnection $dbConn) {
|
|
$this->cache = new DbStatementCache($dbConn);
|
|
}
|
|
|
|
/**
|
|
* @param \Iterator<int, ForumCategoryInfo>|ForumCategoryInfo[] $catInfos
|
|
* @return object{info: ForumCategoryInfo, colour: Colour, children: mixed[], childIds: string[]}[]
|
|
*/
|
|
public static function convertCategoryListToTree(
|
|
iterable $catInfos,
|
|
ForumCategoryInfo|string|null $parentInfo = null,
|
|
?Colour $colour = null
|
|
): array {
|
|
if(!is_array($catInfos))
|
|
$catInfos = iterator_to_array($catInfos);
|
|
|
|
$colour ??= Colour::none();
|
|
$tree = [];
|
|
$predicate = $parentInfo
|
|
? fn($catInfo) => $catInfo->isDirectChildOf($parentInfo)
|
|
: fn($catInfo) => !$catInfo->hasParent;
|
|
|
|
foreach($catInfos as $catInfo) {
|
|
if(!$predicate($catInfo))
|
|
continue;
|
|
|
|
$tree[$catInfo->id] = $item = new stdClass;
|
|
$item->info = $catInfo;
|
|
$item->colour = $catInfo->hasColour ? $catInfo->colour : $colour;
|
|
$item->children = self::convertCategoryListToTree($catInfos, $catInfo, $item->colour);
|
|
$item->childIds = [];
|
|
foreach($item->children as $child) {
|
|
$item->childIds[] = $child->info->id;
|
|
$item->childIds += $child->childIds;
|
|
}
|
|
}
|
|
|
|
return $tree;
|
|
}
|
|
|
|
public function countCategories(
|
|
ForumCategoryInfo|string|null|false $parentInfo = false,
|
|
string|int|null $type = null,
|
|
?bool $hidden = null
|
|
): int {
|
|
if($parentInfo instanceof ForumCategoryInfo)
|
|
$parentInfo = $parentInfo->id;
|
|
|
|
$isRootParent = false;
|
|
$hasParentInfo = $parentInfo !== false;
|
|
$hasType = $type !== null;
|
|
$hasHidden = $hidden !== null;
|
|
|
|
$args = 0;
|
|
$query = 'SELECT COUNT(*) FROM msz_forum_categories';
|
|
if($hasParentInfo) {
|
|
++$args;
|
|
$isRootParent = $parentInfo === null;
|
|
if($isRootParent) { // make a migration that makes the field DEFAULT NULL and update all 0s to NULL
|
|
$query .= 'WHERE (forum_parent IS NULL OR forum_parent = 0)';
|
|
} else {
|
|
$query .= 'WHERE forum_parent = ?';
|
|
}
|
|
}
|
|
if($hasType) {
|
|
if(is_string($type)) {
|
|
if(!array_key_exists($type, ForumCategoryInfo::TYPE_ALIASES))
|
|
throw new InvalidArgumentException('$type is not a valid alias.');
|
|
$type = ForumCategoryInfo::TYPE_ALIASES[$type];
|
|
}
|
|
|
|
$query .= sprintf(' %s forum_type = ?', ++$args > 1 ? 'AND' : 'WHERE');
|
|
}
|
|
if($hasHidden)
|
|
$query .= sprintf(' %s forum_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '<>' : '=');
|
|
|
|
$stmt = $this->cache->get($query);
|
|
if($hasParentInfo && !$isRootParent)
|
|
$stmt->nextParameter($parentInfo);
|
|
if($hasType)
|
|
$stmt->nextParameter($type);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
return $result->next() ? $result->getInteger(0) : 0;
|
|
}
|
|
|
|
/** @return \Iterator<int, ForumCategoryInfo>|object{info: ForumCategoryInfo, colour: Colour, children: mixed[], childIds: string[]}[] */
|
|
public function getCategories(
|
|
ForumCategoryInfo|string|null|false $parentInfo = false,
|
|
string|int|null $type = null,
|
|
?bool $hidden = null,
|
|
bool $asTree = false,
|
|
?Pagination $pagination = null
|
|
): iterable {
|
|
$isRootParent = false;
|
|
$hasParentInfo = $parentInfo !== false;
|
|
$hasType = $type !== null;
|
|
$hasHidden = $hidden !== null;
|
|
$hasPagination = $pagination !== null;
|
|
|
|
if($hasParentInfo && $asTree)
|
|
throw new InvalidArgumentException('$asTree can only be used with $parentInfo set to false.');
|
|
|
|
$args = 0;
|
|
$query = 'SELECT forum_id, forum_order, forum_parent, forum_name, forum_type, forum_description, forum_icon, forum_colour, forum_link, forum_link_clicks, UNIX_TIMESTAMP(forum_created), forum_archived, forum_hidden, forum_count_topics, forum_count_posts FROM msz_forum_categories';
|
|
if($hasParentInfo) {
|
|
++$args;
|
|
$isRootParent = $parentInfo === null;
|
|
if($isRootParent) { // make a migration that makes the field DEFAULT NULL and update all 0s to NULL
|
|
$query .= ' WHERE (forum_parent IS NULL OR forum_parent = 0)';
|
|
} else {
|
|
$query .= ' WHERE forum_parent = ?';
|
|
}
|
|
}
|
|
if($hasType) {
|
|
if(is_string($type)) {
|
|
if(!array_key_exists($type, ForumCategoryInfo::TYPE_ALIASES))
|
|
throw new InvalidArgumentException('$type is not a valid alias.');
|
|
$type = ForumCategoryInfo::TYPE_ALIASES[$type];
|
|
}
|
|
|
|
$query .= sprintf(' %s forum_type = ?', ++$args > 1 ? 'AND' : 'WHERE');
|
|
}
|
|
if($hasHidden)
|
|
$query .= sprintf(' %s forum_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '<>' : '=');
|
|
$query .= ' ORDER BY forum_parent, forum_type <> 1, forum_order';
|
|
if($hasPagination)
|
|
$query .= ' LIMIT ? OFFSET ?';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
if($hasParentInfo && !$isRootParent) {
|
|
if($parentInfo instanceof ForumCategoryInfo)
|
|
$stmt->nextParameter($parentInfo->id);
|
|
else
|
|
$stmt->nextParameter($parentInfo);
|
|
}
|
|
if($hasType)
|
|
$stmt->nextParameter($type);
|
|
if($hasPagination)
|
|
$pagination->addToStatement($stmt);
|
|
$stmt->execute();
|
|
|
|
$cats = $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
|
|
|
|
if($asTree)
|
|
$cats = self::convertCategoryListToTree($cats);
|
|
|
|
return $cats;
|
|
}
|
|
|
|
public function getCategory(
|
|
?string $categoryId = null,
|
|
ForumTopicInfo|string|null $topicInfo = null,
|
|
ForumPostInfo|string|null $postInfo = null
|
|
): ForumCategoryInfo {
|
|
$hasCategoryId = $categoryId !== null;
|
|
$hasTopicInfo = $topicInfo !== null;
|
|
$hasPostInfo = $postInfo !== null;
|
|
|
|
if(!$hasCategoryId && !$hasTopicInfo && !$hasPostInfo)
|
|
throw new InvalidArgumentException('You must specify an argument.');
|
|
if(($hasCategoryId && ($hasTopicInfo || $hasPostInfo))
|
|
|| ($hasTopicInfo && ($hasCategoryId || $hasPostInfo))
|
|
|| ($hasPostInfo && ($hasCategoryId || $hasTopicInfo)))
|
|
throw new InvalidArgumentException('Only one argument may be specified.');
|
|
|
|
$value = null;
|
|
$query = 'SELECT forum_id, forum_order, forum_parent, forum_name, forum_type, forum_description, forum_icon, forum_colour, forum_link, forum_link_clicks, UNIX_TIMESTAMP(forum_created), forum_archived, forum_hidden, forum_count_topics, forum_count_posts FROM msz_forum_categories';
|
|
if($hasCategoryId) {
|
|
$query .= ' WHERE forum_id = ?';
|
|
$value = $categoryId;
|
|
}
|
|
if($hasTopicInfo) {
|
|
if($topicInfo instanceof ForumTopicInfo) {
|
|
$query .= ' WHERE forum_id = ?';
|
|
$value = $topicInfo->categoryId;
|
|
} else {
|
|
$query .= ' WHERE forum_id = (SELECT forum_id FROM msz_forum_topics WHERE topic_id = ?)';
|
|
$value = $topicInfo;
|
|
}
|
|
}
|
|
if($hasPostInfo) {
|
|
if($postInfo instanceof ForumPostInfo) {
|
|
$query .= ' WHERE forum_id = ?';
|
|
$value = $postInfo->categoryId;
|
|
} else {
|
|
$query .= ' WHERE forum_id = (SELECT forum_id FROM msz_forum_posts WHERE post_id = ?)';
|
|
$value = $postInfo;
|
|
}
|
|
}
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($value);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
if(!$result->next())
|
|
throw new RuntimeException('Forum category info not found.');
|
|
|
|
return ForumCategoryInfo::fromResult($result);
|
|
}
|
|
|
|
public function updateCategory(
|
|
ForumCategoryInfo|string $categoryInfo
|
|
): void {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
}
|
|
|
|
public function deleteCategory(ForumCategoryInfo|string $categoryInfo): void {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
}
|
|
|
|
public function incrementCategoryClicks(ForumCategoryInfo|string $categoryInfo): void {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
|
|
// previous implementation also WHERE'd for forum_type = link but i don't think there's any other way to get here anyhow
|
|
$stmt = $this->cache->get('UPDATE msz_forum_categories SET forum_link_clicks = forum_link_clicks + 1 WHERE forum_id = ? AND forum_link_clicks IS NOT NULL');
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function incrementCategoryTopics(ForumCategoryInfo|string $categoryInfo): void {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
|
|
$stmt = $this->cache->get('UPDATE msz_forum_categories SET forum_count_topics = forum_count_topics + 1 WHERE forum_id = ?');
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function incrementCategoryPosts(ForumCategoryInfo|string $categoryInfo): void {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
|
|
$stmt = $this->cache->get('UPDATE msz_forum_categories SET forum_count_posts = forum_count_posts + 1 WHERE forum_id = ?');
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
/** @return \Iterator<int, ForumCategoryInfo> */
|
|
public function getCategoryAncestry(
|
|
ForumCategoryInfo|ForumTopicInfo|ForumPostInfo|string $categoryInfo
|
|
): iterable {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
elseif($categoryInfo instanceof ForumTopicInfo || $categoryInfo instanceof ForumPostInfo)
|
|
$categoryInfo = $categoryInfo->categoryId;
|
|
|
|
$query = 'WITH RECURSIVE msz_cte_ancestry AS ('
|
|
. 'SELECT forum_id, forum_order, forum_parent, forum_name, forum_type, forum_description, forum_icon, forum_colour, forum_link, forum_link_clicks, UNIX_TIMESTAMP(forum_created), forum_archived, forum_hidden, forum_count_topics, forum_count_posts FROM msz_forum_categories WHERE forum_id = ?'
|
|
. ' UNION ALL'
|
|
. ' SELECT fc.forum_id, fc.forum_order, fc.forum_parent, fc.forum_name, fc.forum_type, fc.forum_description, fc.forum_icon, fc.forum_colour, fc.forum_link, fc.forum_link_clicks, UNIX_TIMESTAMP(fc.forum_created), fc.forum_archived, fc.forum_hidden, fc.forum_count_topics, fc.forum_count_posts FROM msz_forum_categories AS fc JOIN msz_cte_ancestry AS ca ON fc.forum_id = ca.forum_parent'
|
|
. ') SELECT * FROM msz_cte_ancestry';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
|
|
return $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
|
|
}
|
|
|
|
/** @return \Iterator<int, ForumCategoryInfo>|object{info: ForumCategoryInfo, colour: Colour, children: mixed[], childIds: string[]}[] */
|
|
public function getCategoryChildren(
|
|
ForumCategoryInfo|string $parentInfo,
|
|
bool $includeSelf = false,
|
|
?bool $hidden = null,
|
|
bool $asTree = false
|
|
): iterable {
|
|
if($parentInfo instanceof ForumCategoryInfo)
|
|
$parentInfo = $parentInfo->id;
|
|
|
|
$hasHidden = $hidden !== null;
|
|
|
|
$query = 'WITH RECURSIVE msz_cte_children AS ('
|
|
. 'SELECT forum_id, forum_order, forum_parent, forum_name, forum_type, forum_description, forum_icon, forum_colour, forum_link, forum_link_clicks, UNIX_TIMESTAMP(forum_created), forum_archived, forum_hidden, forum_count_topics, forum_count_posts FROM msz_forum_categories WHERE forum_id = ?'
|
|
. ' UNION ALL'
|
|
. ' SELECT fc.forum_id, fc.forum_order, fc.forum_parent, fc.forum_name, fc.forum_type, fc.forum_description, fc.forum_icon, fc.forum_colour, fc.forum_link, fc.forum_link_clicks, UNIX_TIMESTAMP(fc.forum_created), fc.forum_archived, fc.forum_hidden, fc.forum_count_topics, fc.forum_count_posts FROM msz_forum_categories AS fc JOIN msz_cte_children AS cc ON fc.forum_parent = cc.forum_id'
|
|
. ') SELECT * FROM msz_cte_children';
|
|
|
|
$args = 0;
|
|
if(!$includeSelf) {
|
|
++$args;
|
|
$query .= ' WHERE forum_id <> ?';
|
|
}
|
|
if($hasHidden)
|
|
$query .= sprintf(' %s forum_hidden %s 0', ++$args > 1 ? 'AND' : 'WHERE', $hidden ? '<>' : '=');
|
|
$query .= ' ORDER BY forum_parent, forum_order';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($parentInfo);
|
|
if(!$includeSelf)
|
|
$stmt->nextParameter($parentInfo);
|
|
$stmt->execute();
|
|
|
|
$cats = $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
|
|
|
|
if($asTree)
|
|
$cats = self::convertCategoryListToTree($cats, $parentInfo);
|
|
|
|
return $cats;
|
|
}
|
|
|
|
/** @param ForumCategoryInfo|string|array<ForumCategoryInfo|string|int> $categoryInfos */
|
|
public function checkCategoryUnread(
|
|
ForumCategoryInfo|string|array $categoryInfos,
|
|
UserInfo|string|null $userInfo
|
|
): bool {
|
|
if($userInfo === null)
|
|
return false;
|
|
|
|
if(!is_array($categoryInfos))
|
|
$categoryInfos = [$categoryInfos];
|
|
if($userInfo instanceof UserInfo)
|
|
$userInfo = $userInfo->id;
|
|
|
|
$stmt = $this->cache->get(sprintf(
|
|
'SELECT COUNT(*) FROM msz_forum_topics AS ft LEFT JOIN msz_forum_topics_track AS ftt ON ftt.topic_id = ft.topic_id AND ftt.user_id = ? WHERE ft.forum_id IN (%s) AND ft.topic_deleted IS NULL AND ft.topic_bumped >= NOW() - INTERVAL 1 MONTH AND (ftt.track_last_read IS NULL OR ftt.track_last_read < ft.topic_bumped)',
|
|
DbTools::prepareListString($categoryInfos)
|
|
));
|
|
$stmt->nextParameter($userInfo);
|
|
foreach($categoryInfos as $categoryInfo) {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$stmt->nextParameter($categoryInfo->id);
|
|
elseif(is_string($categoryInfo) || is_int($categoryInfo))
|
|
$stmt->nextParameter($categoryInfo);
|
|
else
|
|
throw new InvalidArgumentException('Invalid item in $categoryInfos.');
|
|
}
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
return $result->next() && $result->getInteger(0) > 0;
|
|
}
|
|
|
|
public function updateUserReadCategory(
|
|
UserInfo|string|null $userInfo,
|
|
ForumCategoryInfo|string $categoryInfo
|
|
): void {
|
|
if($userInfo === null)
|
|
return;
|
|
|
|
if($userInfo instanceof UserInfo)
|
|
$userInfo = $userInfo->id;
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
|
|
$stmt = $this->cache->get('REPLACE INTO msz_forum_topics_track (user_id, topic_id, forum_id, track_last_read) SELECT ?, topic_id, forum_id, NOW() FROM msz_forum_topics WHERE forum_id = ? AND topic_bumped >= NOW() - INTERVAL 1 MONTH');
|
|
$stmt->nextParameter($userInfo);
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function getCategoryColour(
|
|
ForumCategoryInfo|ForumTopicInfo|ForumPostInfo|string $categoryInfo
|
|
): Colour {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
elseif($categoryInfo instanceof ForumTopicInfo || $categoryInfo instanceof ForumPostInfo)
|
|
$categoryInfo = $categoryInfo->categoryId;
|
|
|
|
$query = 'WITH RECURSIVE msz_cte_colours AS ('
|
|
. 'SELECT forum_id, forum_parent, forum_colour FROM msz_forum_categories WHERE forum_id = ?'
|
|
. ' UNION ALL'
|
|
. ' SELECT fc.forum_id, fc.forum_parent, fc.forum_colour FROM msz_forum_categories AS fc JOIN msz_cte_colours AS cc ON fc.forum_id = cc.forum_parent'
|
|
. ') SELECT forum_colour FROM msz_cte_colours WHERE forum_colour IS NOT NULL';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
return $result->next() ? Colour::fromMisuzu($result->getInteger(0)) : Colour::none();
|
|
}
|
|
|
|
/**
|
|
* @param array<ForumCategoryInfo|string|int> $exceptCategoryInfos
|
|
* @param array<ForumTopicInfo|string|int> $exceptTopicInfos
|
|
*/
|
|
public function getMostActiveCategoryInfo(
|
|
UserInfo|string $userInfo,
|
|
array $exceptCategoryInfos = [],
|
|
array $exceptTopicInfos = [],
|
|
?bool $deleted = null
|
|
): object {
|
|
if($userInfo instanceof UserInfo)
|
|
$userInfo = $userInfo->id;
|
|
|
|
$hasExceptCategoryInfos = !empty($exceptCategoryInfos);
|
|
$hasExceptTopicInfos = !empty($exceptTopicInfos);
|
|
$hasDeleted = $deleted !== null;
|
|
|
|
$query = 'SELECT forum_id, COUNT(*) AS post_count FROM msz_forum_posts WHERE user_id = ?';
|
|
if($hasDeleted)
|
|
$query .= sprintf(' AND post_deleted %s NULL', $deleted ? 'IS NOT' : 'IS');
|
|
if($hasExceptCategoryInfos)
|
|
$query .= sprintf(' AND forum_id NOT IN (%s)', DbTools::prepareListString($exceptCategoryInfos));
|
|
if($hasExceptTopicInfos)
|
|
$query .= sprintf(' AND topic_id NOT IN (%s)', DbTools::prepareListString($exceptTopicInfos));
|
|
$query .= ' GROUP BY forum_id ORDER BY post_count DESC LIMIT 1';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($userInfo);
|
|
foreach($exceptCategoryInfos as $categoryInfo) {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$stmt->nextParameter($categoryInfo->id);
|
|
elseif(is_string($categoryInfo) || is_int($categoryInfo))
|
|
$stmt->nextParameter((string)$categoryInfo);
|
|
else
|
|
throw new InvalidArgumentException('$exceptCategoryInfos may only contain string ids or instances of ForumCategoryInfo.');
|
|
}
|
|
foreach($exceptTopicInfos as $topicInfo) {
|
|
if($topicInfo instanceof ForumTopicInfo)
|
|
$stmt->nextParameter($topicInfo->id);
|
|
elseif(is_string($topicInfo) || is_int($topicInfo))
|
|
$stmt->nextParameter((string)$topicInfo);
|
|
else
|
|
throw new InvalidArgumentException('$exceptTopicInfos may only contain string ids or instances of ForumTopicInfo.');
|
|
}
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
$info = new stdClass;
|
|
$info->success = $result->next();
|
|
if($info->success) {
|
|
$info->categoryId = $result->getString(0);
|
|
$info->postCount = $result->getInteger(1);
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
public function syncForumCounters(
|
|
ForumCategoryInfo|string|null $categoryInfo = null,
|
|
bool $updateCounters = true
|
|
): object {
|
|
if($categoryInfo instanceof ForumCategoryInfo)
|
|
$categoryInfo = $categoryInfo->id;
|
|
elseif($categoryInfo === null)
|
|
$categoryInfo = '0';
|
|
|
|
$counters = new stdClass;
|
|
|
|
$stmt = $this->cache->get('SELECT ? AS target_category_id, (SELECT COUNT(*) FROM msz_forum_topics WHERE forum_id = target_category_id AND topic_deleted IS NULL) AS count_topics, (SELECT COUNT(*) FROM msz_forum_posts WHERE forum_id = target_category_id AND post_deleted IS NULL) AS count_posts');
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
if(!$result->next())
|
|
throw new RuntimeException('Failed to fetch forum category counters.');
|
|
|
|
$counters->topics = $result->getInteger(1);
|
|
$counters->posts = $result->getInteger(2);
|
|
|
|
$stmt = $this->cache->get('SELECT forum_id FROM msz_forum_categories WHERE forum_parent = ?');
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
|
|
$children = [];
|
|
$result = $stmt->getResult();
|
|
while($result->next())
|
|
$children[] = $result->getString(0);
|
|
|
|
foreach($children as $childId) {
|
|
$childCounters = $this->syncForumCounters($childId, $updateCounters);
|
|
$counters->topics += $childCounters->topics;
|
|
$counters->posts += $childCounters->posts;
|
|
}
|
|
|
|
if($updateCounters && $categoryInfo !== '0') {
|
|
$stmt = $this->cache->get('UPDATE msz_forum_categories SET forum_count_topics = ?, forum_count_posts = ? WHERE forum_id = ?');
|
|
$stmt->nextParameter($counters->topics);
|
|
$stmt->nextParameter($counters->posts);
|
|
$stmt->nextParameter($categoryInfo);
|
|
$stmt->execute();
|
|
}
|
|
|
|
return $counters;
|
|
}
|
|
}
|