'IS NULL'],
['fp.read_forum' => '1']
];
if (!User::get()->is_guest) {
$curForum['select'] = ['f.forum_name', 'f.redirect_url', 'f.moderators', 'f.num_topics', 'f.sort_by', 'fp.post_topics', 'is_subscribed' => 's.user_id'];
$curForum = DB::table('forums')->tableAlias('f')
->selectMany($curForum['select'])
->leftOuterJoin('forum_subscriptions', 'f.id=s.forum_id AND s.user_id='.User::get()->id, 's')
->leftOuterJoin('forum_perms', 'fp.forum_id=f.id AND fp.group_id='.User::get()->g_id, 'fp')
->whereAnyIs($curForum['where'])
->where('f.id', $id);
} else {
$curForum['select'] = ['f.forum_name', 'f.redirect_url', 'f.moderators', 'f.num_topics', 'f.sort_by', 'fp.post_topics'];
$curForum = DB::table('forums')->tableAlias('f')
->selectMany($curForum['select'])
->selectExpr(0, 'is_subscribed')
->leftOuterJoin('forum_perms', 'fp.forum_id=f.id AND fp.group_id='.User::get()->g_id, 'fp')
->whereAnyIs($curForum['where'])
->where('f.id', $id);
}
$curForum = Hooks::fireDB('model.forum.get_info_forum_query', $curForum);
$curForum = $curForum->findOne();
if (!$curForum) {
throw new Error(__('Bad request'), '404');
}
$curForum['forum_url'] = Url::slug($curForum['forum_name']);
$curForum = Hooks::fire('model.forum.get_info_forum', $curForum);
return $curForum;
}
public static function getModerators($fid)
{
$moderators = DB::table('forums')
->where('id', $fid);
$moderators = Hooks::fireDB('model.forum.get_moderators', $moderators);
$moderators = $moderators->findOneCol('moderators');
return $moderators;
}
public static function getId($tid)
{
$fid = DB::table('topics')
->where('id', $tid);
$fid = Hooks::fireDB('model.forum.get_moderators', $fid);
$fid = $fid->findOneCol('forum_id');
return $fid;
}
// Returns the text required by the query to sort the forum
public function sortForumBy($sortBySql)
{
$sortBySql = Hooks::fire('model.forum.sort_forum_by_start', $sortBySql);
switch ($sortBySql) {
case 0:
$sortBy = 'last_post DESC';
break;
case 1:
$sortBy = 'posted DESC';
break;
case 2:
$sortBy = 'subject ASC';
break;
default:
$sortBy = 'last_post DESC';
break;
}
$sortBy = Hooks::fire('model.forum.sort_forum_by', $sortBy);
return $sortBy;
}
// Returns forum action
public function getForumActions($forumId, $forumUrl, $isSubscribed)
{
$forumActions = [];
$forumActions = Hooks::fire('model.forum.get_page_head_start', $forumActions, $forumId, $forumUrl, $isSubscribed);
if (!User::get()->is_guest) {
if (ForumSettings::get('o_forum_subscriptions') == 1) {
if ($isSubscribed) {
$forumActions[] = ''.__('Is subscribed').' - '.__('Unsubscribe').'';
} else {
$forumActions[] = ''.__('Subscribe').'';
}
}
$forumActions[] = ''.__('Mark forum read').'';
}
$forumActions = Hooks::fire('model.forum.get_page_head', $forumActions);
return $forumActions;
}
// Returns the elements needed to display topics
public function printTopics($forumId, $sortBy, $startFrom)
{
$forumId = Hooks::fire('model.forum.print_topics_start', $forumId, $sortBy, $startFrom);
// Get topic/forum tracking data
if (!User::get()->is_guest) {
$trackedTopics = Track::getTrackedTopics();
}
// Retrieve a list of topic IDs, LIMIT is (really) expensive so we only fetch the IDs here then later fetch the remaining data
$result = DB::table('topics')
->select('id')
->where('forum_id', $forumId)
->orderByDesc('sticky')
->orderByExpr($sortBy)
->orderByDesc('id')
->limit(User::getPref('disp.topics'))
->offset($startFrom);
$result = Hooks::fire('model.forum.print_topics_ids_query', $result);
$result = $result->findMany();
$forumData = [];
// If there are topics in this forum
if ($result) {
$topicIds = [];
foreach ($result as $curTopicId) {
$topicIds[] = $curTopicId['id'];
}
// Fetch list of topics to display on this page
if (User::get()->is_guest || ForumSettings::get('o_show_dot') == '0') {
// Without "the dot"
$result['select'] = ['id', 'poster', 'subject', 'posted', 'last_post', 'last_post_id', 'last_poster', 'num_views', 'num_replies', 'closed', 'sticky', 'moved_to'];
$result = DB::table('topics')
->selectMany($result['select'])
->whereIn('id', $topicIds)
->orderByDesc('sticky')
->orderByExpr($sortBy)
->orderByDesc('id');
} else {
// With "the dot"
$result['select'] = ['has_posted' => 'p.poster_id', 't.id', 't.subject', 't.poster', 't.posted', 't.last_post', 't.last_post_id', 't.last_poster', 't.num_views', 't.num_replies', 't.closed', 't.sticky', 't.moved_to'];
$result = DB::table('topics')
->tableAlias('t')
->selectMany($result['select'])
->leftOuterJoin('posts', ['t.id', '=', 'p.topic_id'], 'p')
->leftOuterJoin('posts', ['p.poster_id', '=', User::get()->id], null, true)
->whereIn('t.id', $topicIds)
->groupBy('t.id')
->orderByDesc('sticky')
->orderByExpr($sortBy)
->orderByDesc('id');
}
$result = Hooks::fireDB('model.forum.print_topics_query', $result);
$result = $result->findMany();
$topicCount = 0;
foreach ($result as $curTopic) {
++$topicCount;
$statusText = [];
$curTopic['item_status'] = ($topicCount % 2 == 0) ? 'roweven' : 'rowodd';
$curTopic['icon_type'] = 'icon';
$urlSubject = Url::slug($curTopic['subject']);
if (is_null($curTopic['moved_to'])) {
$curTopic['last_post_formatted'] = ''.Utils::formatTime($curTopic['last_post']).' '.__('by').' '.Utils::escape($curTopic['last_poster']).'';
} else {
$curTopic['last_post_formatted'] = '- - -';
}
if (ForumSettings::get('o_censoring') == '1') { // TODO: correct ?
$curTopic['subject'] = Utils::censor($curTopic['subject']);
}
if ($curTopic['moved_to'] != 0) {
$curTopic['subject_formatted'] = ''.Utils::escape($curTopic['subject']).' '.__('by').' '.Utils::escape($curTopic['poster']).'';
$statusText[] = ''.__('Moved').'';
$curTopic['item_status'] .= ' imoved';
} else {
$curTopic['subject_formatted'] = ''.Utils::escape($curTopic['subject']).' '.__('by').' '.Utils::escape($curTopic['poster']).'';
}
// Include separate icon, label and background for sticky and closed topics
if ($curTopic['sticky'] == '1') {
$curTopic['item_status'] .= ' isticky';
if ($curTopic['closed'] == '1') {
$statusText[] = ''.__('Sticky and closed').'';
$curTopic['icon_type'] = 'icon icon-closed';
} else {
$statusText[] = ''.__('Sticky').'';
$curTopic['icon_type'] = 'icon icon-sticky';
}
} elseif ($curTopic['closed'] == '1') {
$statusText[] = ''.__('Closed').'';
$curTopic['item_status'] .= ' iclosed';
$curTopic['icon_type'] = 'icon icon-closed';
}
if (!User::get()->is_guest && $curTopic['last_post'] > User::get()->last_visit && (!isset($trackedTopics['topics'][$curTopic['id']]) || $trackedTopics['topics'][$curTopic['id']] < $curTopic['last_post']) && (!isset($trackedTopics['forums'][$forumId]) || $trackedTopics['forums'][$forumId] < $curTopic['last_post']) && is_null($curTopic['moved_to'])) {
$curTopic['item_status'] .= ' inew';
$curTopic['icon_type'] = 'icon icon-new';
$curTopic['subject_formatted'] = ''.$curTopic['subject_formatted'].'';
$subjectNewPosts = '[ '.__('New posts').' ]';
} else {
$subjectNewPosts = null;
}
// Insert the status text before the subject
$curTopic['subject_formatted'] = implode(' ', $statusText).' '.$curTopic['subject_formatted'];
// Should we display the dot or not? :)
if (!User::get()->is_guest && ForumSettings::get('o_show_dot') == '1') {
if ($curTopic['has_posted'] == User::get()->id) {
$curTopic['subject_formatted'] = 'ยท '.$curTopic['subject_formatted'];
$curTopic['item_status'] .= ' iposted';
}
}
$numPagesTopic = ceil(($curTopic['num_replies'] + 1) / User::getPref('disp.posts'));
if ($numPagesTopic > 1) {
$subjectMultipage = '[ '.Url::paginate($numPagesTopic, -1, 'topic/'.$curTopic['id'].'/'.$urlSubject.'/#').' ]';
} else {
$subjectMultipage = null;
}
// Should we show the "New posts" and/or the multipage links?
if (!empty($subjectNewPosts) || !empty($subjectMultipage)) {
$curTopic['subject_formatted'] .= !empty($subjectNewPosts) ? ' '.$subjectNewPosts : '';
$curTopic['subject_formatted'] .= !empty($subjectMultipage) ? ' '.$subjectMultipage : '';
}
$forumData[] = $curTopic;
}
}
$forumData = Hooks::fire('model.forum.print_topics', $forumData);
return $forumData;
}
public function displayTopicsModerate($fid, $sortBy, $startFrom)
{
Hooks::fire('model.forum.display_topics_start', $fid, $sortBy, $startFrom);
$topicData = [];
// Get topic/forum tracking data
if (!User::get()->is_guest) {
$trackedTopics = Track::getTrackedTopics();
}
// Retrieve a list of topic IDs, LIMIT is (really) expensive so we only fetch the IDs here then later fetch the remaining data
$result = DB::table('topics')->select('id')
->where('forum_id', $fid)
->orderByExpr('sticky DESC, '.$sortBy)
->limit(User::getPref('disp.topics'))
->offset($startFrom);
$result = Hooks::fireDB('model.forum.display_topics_list_ids', $result);
$result = $result->findMany();
// If there are topics in this forum
if ($result) {
foreach ($result as $id) {
$topicIds[] = $id['id'];
}
unset($result);
// Select topics
$result['select'] = ['id', 'poster', 'subject', 'posted', 'last_post', 'last_post_id', 'last_poster', 'num_views', 'num_replies', 'closed', 'sticky', 'moved_to'];
$result = DB::table('topics')->selectMany($result['select'])
->whereIn('id', $topicIds)
->orderByDesc('sticky')
->orderByExpr($sortBy)
->orderByDesc('id');
$result = Hooks::fireDB('model.forum.display_topics_query', $result);
$result = $result->findMany();
$topicCount = 0;
foreach ($result as $curTopic) {
++$topicCount;
$statusText = [];
$curTopic['item_status'] = ($topicCount % 2 == 0) ? 'roweven' : 'rowodd';
$curTopic['icon_type'] = 'icon';
$urlTopic = Url::slug($curTopic['subject']);
if (is_null($curTopic['moved_to'])) {
$curTopic['last_post_disp'] = ''.Utils::formatTime($curTopic['last_post']).' '.__('by').' '.Utils::escape($curTopic['last_poster']).'';
$curTopic['ghost_topic'] = false;
} else {
$curTopic['last_post_disp'] = '- - -';
$curTopic['ghost_topic'] = true;
}
if (ForumSettings::get('o_censoring') == '1') {
$curTopic['subject'] = Utils::censor($curTopic['subject']);
}
if ($curTopic['moved_to'] != 0) {
$curTopic['subject_disp'] = ''.Utils::escape($curTopic['subject']).' '.__('by').' '.Utils::escape($curTopic['poster']).'';
$statusText[] = ''.__('Moved').'';
$curTopic['item_status'] .= ' imoved';
} else {
$curTopic['subject_disp'] = ''.Utils::escape($curTopic['subject']).' '.__('by').' '.Utils::escape($curTopic['poster']).'';
}
// Include separate icon, label and background for sticky and closed topics
if ($curTopic['sticky'] == '1') {
$curTopic['item_status'] .= ' isticky';
if ($curTopic['closed'] == '1') {
$statusText[] = ''.__('Sticky and closed').'';
$curTopic['icon_type'] = 'icon icon-closed';
} else {
$statusText[] = ''.__('Sticky').'';
$curTopic['icon_type'] = 'icon icon-sticky';
}
} elseif ($curTopic['closed'] == '1') {
$statusText[] = ''.__('Closed').'';
$curTopic['item_status'] .= ' iclosed';
$curTopic['icon_type'] = 'icon icon-closed';
}
if (!$curTopic['ghost_topic'] && $curTopic['last_post'] > User::get()->last_visit && (!isset($trackedTopics['topics'][$curTopic['id']]) || $trackedTopics['topics'][$curTopic['id']] < $curTopic['last_post']) && (!isset($trackedTopics['forums'][$fid]) || $trackedTopics['forums'][$fid] < $curTopic['last_post'])) {
$curTopic['item_status'] .= ' inew';
$curTopic['icon_type'] = 'icon icon-new';
$curTopic['subject_disp'] = ''.$curTopic['subject_disp'].'';
$subjectNewPosts = '[ '.__('New posts').' ]';
} else {
$subjectNewPosts = null;
}
// Insert the status text before the subject
$curTopic['subject_disp'] = implode(' ', $statusText).' '.$curTopic['subject_disp'];
$numPagesTopic = ceil(($curTopic['num_replies'] + 1) / User::getPref('disp.posts'));
if ($numPagesTopic > 1) {
$subjectMultipage = '[ '.Url::paginate($numPagesTopic, -1, 'topic/'.$curTopic['id'].'/'.$urlTopic.'/#').' ]';
} else {
$subjectMultipage = null;
}
// Should we show the "New posts" and/or the multipage links?
if (!empty($subjectNewPosts) || !empty($subjectMultipage)) {
$curTopic['subject_disp'] .= !empty($subjectNewPosts) ? ' '.$subjectNewPosts : '';
$curTopic['subject_disp'] .= !empty($subjectMultipage) ? ' '.$subjectMultipage : '';
}
$topicData[] = $curTopic;
}
}
$topicData = Hooks::fire('model.forum.display_topics', $topicData);
return $topicData;
}
//
// Update posts, topics, last_post, last_post_id and last_poster for a forum
//
public static function update($forumId)
{
$statsQuery = DB::table('topics')
->where('forum_id', $forumId)
->selectExpr('COUNT(id)', 'total_topics')
->selectExpr('SUM(num_replies)', 'total_replies')
->findOne();
$numTopics = intval($statsQuery['total_topics']);
$numReplies = intval($statsQuery['total_replies']);
$numPosts = $numReplies + $numTopics; // $numPosts is only the sum of all replies (we have to add the topic posts)
$selectUpdateForum = ['last_post', 'last_post_id', 'last_poster'];
$result = DB::table('topics')->selectMany($selectUpdateForum)
->where('forum_id', $forumId)
->whereNull('moved_to')
->orderByDesc('last_post')
->findOne();
if ($result) {
// There are topics in the forum
$insertUpdateForum = [
'num_topics' => $numTopics,
'num_posts' => $numPosts,
'last_post' => $result['last_post'],
'last_post_id' => $result['last_post_id'],
'last_poster' => $result['last_poster'],
];
} else {
// There are no topics
$insertUpdateForum = [
'num_topics' => $numTopics,
'num_posts' => $numPosts,
'last_post' => 'NULL',
'last_post_id' => 'NULL',
'last_poster' => 'NULL',
];
}
DB::table('forums')
->where('id', $forumId)
->findOne()
->set($insertUpdateForum)
->save();
}
public function unsubscribe($forumId)
{
$forumId = Hooks::fire('model.forum.unsubscribe_forum_start', $forumId);
if (ForumSettings::get('o_forum_subscriptions') != '1') {
throw new Error(__('No permission'), 403);
}
$isSubscribed = DB::table('forum_subscriptions')
->where('user_id', User::get()->id)
->where('forum_id', $forumId);
$isSubscribed = Hooks::fireDB('model.forum.unsubscribe_forum_subscribed_query', $isSubscribed);
$isSubscribed = $isSubscribed->findOne();
if (!$isSubscribed) {
throw new Error(__('Not subscribed forum'), 400);
}
// Delete the subscription
$delete = DB::table('forum_subscriptions')
->where('user_id', User::get()->id)
->where('forum_id', $forumId);
$delete = Hooks::fireDB('model.forum.unsubscribe_forum_query', $delete);
$delete->deleteMany();
}
public function subscribe($forumId)
{
$forumId = Hooks::fire('model.forum.subscribe_forum_start', $forumId);
if (ForumSettings::get('o_forum_subscriptions') != '1') {
throw new Error(__('No permission'), 403);
}
// Make sure the user can view the forum
$authorized['where'] = [
['fp.read_forum' => 'IS NULL'],
['fp.read_forum' => '1']
];
$authorized = DB::table('forums')
->tableAlias('f')
->leftOuterJoin('forum_perms', 'fp.forum_id=f.id AND fp.group_id='.User::get()->g_id, 'fp')
->whereAnyIs($authorized['where'])
->where('f.id', $forumId);
$authorized = Hooks::fireDB('model.forum.subscribe_forum_authorized_query', $authorized);
$authorized = $authorized->findOne();
if (!$authorized) {
throw new Error(__('Bad request'), 404);
}
$isSubscribed = DB::table('forum_subscriptions')
->where('user_id', User::get()->id)
->where('forum_id', $forumId);
$isSubscribed = Hooks::fireDB('model.forum.subscribe_forum_subscribed_query', $isSubscribed);
$isSubscribed = $isSubscribed->findOne();
if ($isSubscribed) {
throw new Error(__('Already subscribed forum'), 400);
}
// Insert the subscription
$subscription['insert'] = [
'user_id' => User::get()->id,
'forum_id' => $forumId
];
$subscription = DB::table('forum_subscriptions')
->create()
->set($subscription['insert']);
$subscription = Hooks::fireDB('model.forum.subscribe_forum_query', $subscription);
$subscription->save();
}
public function closeMultiple($action, $topics)
{
$closeMultipleTopics = DB::table('topics')
->whereIn('id', $topics);
$closeMultipleTopics = Hooks::fireDB('model.forum.open_topic', $closeMultipleTopics);
$closeMultipleTopics = $closeMultipleTopics->updateMany('closed', $action);
}
public function stickMultiple($action, $topics)
{
$stickMultipleTopics = DB::table('topics')
->whereIn('id', $topics);
$stickMultipleTopics = Hooks::fireDB('model.forum.stick_topic', $stickMultipleTopics);
$stickMultipleTopics = $stickMultipleTopics->updateMany('sticky', $action);
}
public function delete($topics, $fid)
{
Hooks::fire('model.forum.delete_topics', $topics, $fid);
if (@preg_match('%[^0-9,]%', $topics)) {
throw new Error(__('Bad request'), 400);
}
$topicsSql = explode(',', $topics);
// Verify that the topic IDs are valid
$result = DB::table('topics')
->whereIn('id', $topicsSql)
->where('forum_id', $fid);
$result = Hooks::fireDB('model.forum.delete_topics_verify_id', $result);
$result = $result->findMany();
if (count($result) != substr_count($topics, ',') + 1) {
throw new Error(__('Bad request'), 400);
}
// Verify that the posts are not by admins
if (User::get()->g_id != ForumEnv::get('FEATHER_ADMIN')) {
$authorized = DB::table('posts')
->whereIn('topic_id', $topicsSql)
->where('poster_id', Utils::getAdminIds());
$authorized = Hooks::fireDB('model.forum.delete_topics_authorized', $authorized);
$authorized = $authorized->findMany();
if ($authorized) {
throw new Error(__('No permission'), 403);
}
}
// Delete the topics
$deleteTopics = DB::table('topics')
->whereIn('id', $topicsSql);
$deleteTopics = Hooks::fireDB('model.forum.delete_topics_query', $deleteTopics);
$deleteTopics = $deleteTopics->deleteMany();
// Delete any redirect topics
$deleteRedirectTopics = DB::table('topics')
->whereIn('moved_to', $topicsSql);
$deleteRedirectTopics = Hooks::fireDB('model.forum.delete_topics_redirect', $deleteRedirectTopics);
$deleteRedirectTopics = $deleteRedirectTopics->deleteMany();
// Delete any subscriptions
$deleteSubscriptions = DB::table('topic_subscriptions')
->whereIn('topic_id', $topicsSql);
$deleteSubscriptions = Hooks::fireDB('model.forum.delete_topics_subscriptions', $deleteSubscriptions);
$deleteSubscriptions = $deleteSubscriptions->deleteMany();
// Create a list of the post IDs in this topic and then strip the search index
$findIds = DB::table('posts')
->select('id')
->whereIn('topic_id', $topicsSql);
$findIds = Hooks::fireDB('model.forum.delete_topics_find_ids', $findIds);
$findIds = $findIds->findMany();
$idsPost = [];
foreach ($findIds as $id) {
$idsPost[] = $id['id'];
}
$postIds = implode(', ', $idsPost);
// We have to check that we actually have a list of post IDs since we could be deleting just a redirect topic
if ($postIds != '') {
$search = new \FeatherBB\Core\Search();
$search->stripSearchIndex($postIds);
}
// Delete posts
$deletePosts = DB::table('posts')
->whereIn('topic_id', $topicsSql);
$deletePosts = Hooks::fireDB('model.forum.delete_topics_delete_posts', $deletePosts);
$deletePosts = $deletePosts->deleteMany();
self::update($fid);
}
public function merge($fid)
{
$fid = Hooks::fire('model.forum.merge_topics_start', $fid);
if (@preg_match('%[^0-9,]%', Input::post('topics'))) {
throw new Error(__('Bad request'), 404);
}
$topics = explode(',', Input::post('topics'));
if (count($topics) < 2) {
throw new Error(__('Not enough topics selected'), 400);
}
// Verify that the topic IDs are valid (redirect links will point to the merged topic after the merge)
$result = DB::table('topics')
->whereIn('id', $topics)
->where('forum_id', $fid);
$result = Hooks::fireDB('model.forum.merge_topics_topic_ids', $result);
$result = $result->findMany();
if (count($result) != count($topics)) {
throw new Error(__('Bad request'), 400);
}
// The topic that we are merging into is the one with the smallest ID
$mergeToTid = DB::table('topics')
->whereIn('id', $topics)
->where('forum_id', $fid)
->orderByAsc('id')
->findOneCol('id');
$mergeToTid = Hooks::fire('model.forum.merge_topics_tid', $mergeToTid);
// Make any redirect topics point to our new, merged topic
$query = 'UPDATE '.ForumEnv::get('DB_PREFIX').'topics SET moved_to='.$mergeToTid.' WHERE moved_to IN('.implode(',', $topics).')';
// Should we create redirect topics?
if (Input::post('with_redirect')) {
$query .= ' OR (id IN('.implode(',', $topics).') AND id != '.$mergeToTid.')';
}
// TODO ?
DB::table('topics')->rawExecute($query);
// Merge the posts into the topic
$mergePosts = DB::table('posts')
->whereIn('topic_id', $topics);
$mergePosts = Hooks::fireDB('model.forum.merge_topics_merge_posts', $mergePosts);
$mergePosts = $mergePosts->updateMany('topic_id', $mergeToTid);
// Update any subscriptions
$findIds = DB::table('topic_subscriptions')->select('user_id')
->distinct()
->whereIn('topic_id', $topics);
$findIds = Hooks::fireDB('model.forum.merge_topics_find_ids', $findIds);
$findIds = $findIds->findMany();
$subscribedUsers = [];
foreach ($findIds as $id) {
$subscribedUsers[] = $id['user_id'];
}
// Delete the subscriptions
$deleteSubscriptions = DB::table('topic_subscriptions')
->whereIn('topic_id', $topics);
$deleteSubscriptions = Hooks::fireDB('model.forum.merge_topics_delete_subscriptions', $deleteSubscriptions);
$deleteSubscriptions = $deleteSubscriptions->deleteMany();
// If users subscribed to one of the topics, keep subscription for merged topic
foreach ($subscribedUsers as $curUserId) {
$subscriptions['insert'] = [
'topic_id' => $mergeToTid,
'user_id' => $curUserId,
];
// Insert the subscription
$subscriptions = DB::table('topic_subscriptions')
->create()
->set($subscriptions['insert']);
$subscriptions = Hooks::fireDB('model.forum.merge_topics_insert_subscriptions', $subscriptions);
$subscriptions = $subscriptions->save();
}
// Without redirection the old topics are removed
if (Input::post('with_redirect') == 0) {
$deleteTopics = DB::table('topics')
->whereIn('id', $topics)
->whereNotEqual('id', $mergeToTid);
$deleteTopics = Hooks::fireDB('model.forum.merge_topics_delete_topics', $deleteTopics);
$deleteTopics = $deleteTopics->deleteMany();
}
// Count number of replies in the topic
$numReplies = DB::table('posts')->where('topic_id', $mergeToTid)->count('id') - 1;
$numReplies = Hooks::fire('model.forum.merge_topics_num_replies', $numReplies);
// Get last_post, last_post_id and last_poster
$lastPost['select'] = ['posted', 'id', 'poster'];
$lastPost = DB::table('posts')
->selectMany($lastPost['select'])
->where('topic_id', $mergeToTid)
->orderByDesc('id');
$lastPost = Hooks::fireDB('model.forum.merge_topics_last_post', $lastPost);
$lastPost = $lastPost->findOne();
// Update topic
$updateTopic['insert'] = [
'num_replies' => $numReplies,
'last_post' => $lastPost['posted'],
'last_post_id' => $lastPost['id'],
'last_poster' => $lastPost['poster'],
];
$topic = DB::table('topics')
->where('id', $mergeToTid)
->findOne()
->set($updateTopic['insert']);
$topic = Hooks::fireDB('model.forum.merge_topics_update_topic', $topic);
$topic = $topic->save();
Hooks::fire('model.forum.merge_topics');
// Update the forum FROM which the topic was moved and redirect
self::update($fid);
}
public static function canModerate($fid)
{
$moderators = self::getModerators($fid);
$modsArray = ($moderators != '') ? unserialize($moderators) : [];
// Sort out who has permission to moderate
$permission = (User::isAdmin() || (User::isAdminMod() && array_key_exists(User::get()->username, $modsArray))) ? true : false;
return $permission;
}
}