<?php
/*-------------------------------------------------------+
| PHPFusion Content Management System
| Copyright (C) PHP Fusion Inc
| https://phpfusion.com/
+--------------------------------------------------------+
| Filename: threads.php
| Author: Chan (Frederick MC Chan)
+--------------------------------------------------------+
| This program is released as free software under the
| Affero GPL license. You can redistribute it and/or
| modify it under the terms of this license which you
| can read by viewing the included agpl.txt or online
| at www.gnu.org/licenses/agpl.html. Removal of this
| copyright header is strictly prohibited without
| written permission from the original author(s).
+--------------------------------------------------------*/
namespace PHPFusion\Forums\Threads;
use PHPFusion\Forums\ForumServer;
use PHPFusion\Forums\Moderator;
use PHPFusion\Forums\Post\QuickReply;
/**
* Class ForumThreads
* Forum threads functions
*
* @package PHPFusion\Forums\Threads
*/
class ForumThreads extends ForumServer {
protected $thread_info = []; // make a default
protected $thread_data = [];
private static $custom_query = '';
/**
* Get thread structure on specific forum id.
*
* @param int $forum_id
* @param bool $filter
*
* @return array
*/
public static function getForumThread($forum_id = 0, $filter = FALSE) {
$default_filter = [
'count_query' => '',
'query' => '',
];
$filter += $default_filter;
/* Redo and remove all joins */
$info = [];
$locale = fusion_get_locale();
$forum_settings = ForumServer::getForumSettings();
$userdata = fusion_get_userdata();
$userdata['user_id'] = !empty($userdata['user_id']) ? intval($userdata['user_id']) : 0;
$lastVisited = defined('LASTVISITED') ? LASTVISITED : time();
$join = '';
if (isset($_GET['type']) && $_GET['type'] == 'poll') {
$join = "LEFT JOIN ".DB_FORUM_POSTS." p1 ON p1.thread_id=t.thread_id AND tf.forum_id=p1.forum_id
LEFT JOIN ".DB_FORUM_POLLS." p ON p.thread_id = t.thread_id
LEFT JOIN ".DB_FORUM_VOTES." v ON v.thread_id = t.thread_id AND p1.post_id = v.post_id";
}
//print_p($filter);
/**
* Get threads with filter conditions (XSS prevention)
* The latest Post requires a simple query replacement.
* #AND tf.forum_lastpost = t.thread_lastpost AND tf.forum_lastpostid = t.thread_lastpostid
* The rows is thread that has the last post.... \\\\\\
*
*/
$thread_query = $filter['count_query'] ?: "
SELECT count(t.thread_id) 'thread_count',
t.thread_id
FROM ".DB_FORUM_THREADS." t
INNER JOIN ".DB_FORUMS." tf ON t.forum_id=tf.forum_id
LEFT JOIN ".DB_FORUM_ATTACHMENTS." a on a.thread_id = t.thread_id
".$join."
WHERE ".($forum_id ? " t.forum_id='".intval($forum_id)."' AND " : "")." t.thread_hidden='0' AND ".groupaccess('tf.forum_access')."
".(isset($filter['condition']) ? $filter['condition'] : '')." GROUP BY t.thread_id";
if (!empty($filter['debug'])) {
print_p($thread_query);
}
$thread_result = dbquery($thread_query);
$info['thread_max_rows'] = dbrows($thread_result);
$info['item'][$forum_id]['forum_threadcount'] = 0;
$info['item'][$forum_id]['forum_threadcount_word'] = format_word($info['thread_max_rows'], $locale['fmt_thread']);
if ($info['thread_max_rows']) {
$info['threads']['pagenav'] = '';
$info['threads']['pagenav2'] = '';
// anti-XSS filtered rowstart
$_GET['rowstart'] = isset($_GET['rowstart']) && isnum($_GET['rowstart']) && $_GET['rowstart'] <= $info['thread_max_rows'] ? $_GET['rowstart'] : 0;
$thread_query = $filter['query'] ?: "
SELECT t.*, tf.forum_type, tf.forum_name, tf.forum_cat,
IF (n.thread_id > 0, 1 , 0) 'user_tracked',
count(v.vote_user) 'thread_rated',
count(pv.forum_vote_user_id) 'poll_voted',
count(v.post_id) AS vote_count,
count(a.attach_id) AS attach_count, a.attach_id
FROM ".DB_FORUM_THREADS." t
INNER JOIN ".DB_FORUMS." tf ON tf.forum_id = t.forum_id
LEFT JOIN ".DB_FORUM_VOTES." v on v.thread_id = t.thread_id AND v.vote_user='".$userdata['user_id']."' AND v.forum_id = t.forum_id AND tf.forum_type='4'
LEFT JOIN ".DB_FORUM_POLL_VOTERS." pv on pv.thread_id = t.thread_id AND pv.forum_vote_user_id='".$userdata['user_id']."' AND t.thread_poll=1
LEFT JOIN ".DB_FORUM_ATTACHMENTS." a on a.thread_id = t.thread_id
LEFT JOIN ".DB_FORUM_THREAD_NOTIFY." n on n.thread_id = t.thread_id and n.notify_user = '".$userdata['user_id']."'
WHERE ".($forum_id ? "t.forum_id='".$forum_id."' AND " : "")."t.thread_hidden='0' AND ".groupaccess('tf.forum_access')."
".(isset($filter['condition']) ? $filter['condition'] : '')." ".(multilang_table("FO") ? "AND ".in_group('tf.forum_language', LANGUAGE) : '')."
GROUP BY t.thread_id
".(isset($filter['order']) ? $filter['order'] : '');
$thread_query .= " LIMIT ".intval($_GET['rowstart']).", ".$forum_settings['threads_per_page'];
if (!empty($filter['debug']))
print_p($thread_query);
$cthread_result = dbquery($thread_query);
$rows = dbrows($cthread_result);
if ($rows) {
while ($threads = dbarray($cthread_result)) {
if (iMEMBER) {
$threads['track_button'] = [
"link" => FORUM."postify.php?post=on&forum_id=".$threads['forum_id']."&thread_id=".$threads['thread_id'],
"title" => $locale['forum_0175'],
"onclick" => "",
];
if (isset($threads['user_tracked']) && $threads['user_tracked']) {
$threads['track_button'] = [
"link" => FORUM."postify.php?post=off&forum_id=".$threads['forum_id']."&thread_id=".$threads['thread_id'],
"title" => $locale['forum_0174'],
"onclick" => "onclick=\"return confirm('".$locale['global_060']."');\"",
];
}
}
if (!isset($threads['attach_count'])) {
$threads['attach_count'] = dbcount("(attach_id)", DB_FORUM_ATTACHMENTS, "thread_id=:current_thread", [':current_thread' => $threads['thread_id']]);
}
if (!isset($threads['vote_count'])) {
$threads['vote_count'] = dbcount("(post_id)", DB_FORUM_VOTES, "thread_id=:current_thread", [':current_thread' => $threads['thread_id']]);
}
$threads += [
'author_name' => '',
'author_status' => '',
'author_avatar' => '',
'last_user_name' => '',
'last_user_status' => '',
'last_user_avatar' => '',
];
$user1 = fusion_get_user($threads['thread_author']);
if (!empty($user1['user_id'])) {
$threads['author_name'] = $user1['user_name'];
$threads['author_status'] = $user1['user_status'];
$threads['author_avatar'] = $user1['user_avatar'];
}
$user2 = fusion_get_user($threads['thread_lastuser']);
if (!empty($user2['user_id'])) {
$threads['last_user_name'] = $user2['user_name'];
$threads['last_user_status'] = $user2['user_status'];
$threads['last_user_avatar'] = $user2['user_avatar'];
}
$icon = "";
$match_regex = $threads['thread_id']."\|".$threads['thread_lastpost']."\|".$threads['forum_id'];
if ($threads['thread_lastpost'] > $lastVisited) {
if (iMEMBER && ($threads['thread_lastuser'] == $userdata['user_id'] ||
preg_match("(^\.$match_regex$|\.$match_regex\.|\.$match_regex$)", $userdata['user_threads']))
) {
$icon = "<i class='".self::getForumIcons('thread')."' title='".$locale['forum_0261']."'></i>";
} else {
$icon = "<i class='".self::getForumIcons('new')."' title='".$locale['forum_0260']."'></i>";
}
}
$author = [
'user_id' => $threads['thread_author'],
'user_name' => $threads['author_name'],
'user_status' => $threads['author_status'],
'user_avatar' => $threads['author_avatar']
];
$lastuser = [
'user_id' => $threads['thread_lastuser'],
'user_name' => $threads['last_user_name'],
'user_status' => $threads['last_user_status'],
'user_avatar' => $threads['last_user_avatar']
];
// Automatic link to the latest post
$thread_rowstart = '';
if (!empty($threads['thread_postcount']) && !empty($forum_settings['posts_per_page'])) {
if ($threads['thread_postcount'] > $forum_settings['posts_per_page']) {
$thread_rowstart = $forum_settings['posts_per_page'] * floor(($threads['thread_postcount'] - 1) / $forum_settings['posts_per_page']);
$thread_rowstart = "&rowstart=".$thread_rowstart;
}
}
$threads += [
"thread_link" => [
"link" => FORUM."viewthread.php?thread_id=".$threads['thread_id'].$thread_rowstart."&pid=".$threads['thread_lastpostid']."#post_".$threads['thread_lastpostid'],
"title" => $threads['thread_subject']
],
"forum_type" => $threads['forum_type'],
"thread_pages" => makepagenav(0, $forum_settings['posts_per_page'], $threads['thread_postcount'], 3, FORUM."viewthread.php?thread_id=".$threads['thread_id']."&"),
"thread_icons" => [
'lock' => $threads['thread_locked'] ? "<i class='".self::getForumIcons('lock')."' title='".$locale['forum_0263']."'></i>" : '',
'sticky' => $threads['thread_sticky'] ? "<i class='".self::getForumIcons('sticky')."' title='".$locale['forum_0103']."'></i>" : '',
'poll' => $threads['thread_poll'] ? "<i class='".self::getForumIcons('poll')."' title='".$locale['forum_0314']."'></i>" : '',
'hot' => $threads['thread_postcount'] >= 20 ? "<i class='".self::getForumIcons('hot')."' title='".$locale['forum_0311']."'></i>" : '',
'reads' => $threads['thread_views'] >= 100 ? "<i class='".self::getForumIcons('reads')."' title='".$locale['forum_0311']."'></i>" : '',
'attach' => $threads['attach_count'] > 0 ? "<i class='".self::getForumIcons('image')."' title='".$locale['forum_0312']."'></i>" : '',
'icon' => $icon,
],
"thread_starter_text" => $locale['forum_0006'].' '.$locale['by']." ".profile_link($author['user_id'], $author['user_name'], $author['user_status'])."</span>",
//"thread_starter" => $locale['forum_0006'].' '.timer($threads['first_post_datestamp'])." ".$locale['by']." ".profile_link($author['user_id'], $author['user_name'], $author['user_status'])."</span>", // Very slow
"thread_starter" => [
'author' => $author,
'profile_link' => profile_link($author['user_id'], $author['user_name'], $author['user_status']),
'avatar' => display_avatar($author, '20px', '', FALSE, 'img-rounded'),
],
"thread_last" => [
'user' => $lastuser,
'avatar' => display_avatar($lastuser, '35px', '', FALSE),
'profile_link' => profile_link($lastuser['user_id'], $lastuser['user_name'], $lastuser['user_status']),
'time' => $threads['thread_lastpost'],
"formatted" => "<div class='pull-left'>".display_avatar($lastuser, '30px', '', '')."</div>
<div class='overflow-hide'>".$locale['forum_0373']." <span class='forum_profile_link'>".profile_link($lastuser['user_id'], $lastuser['user_name'], $lastuser['user_status'])."</span><br/>
".timer($threads['thread_lastpost'])."
</div>"
],
];
if ($threads['thread_sticky']) {
$info['threads']['sticky'][$threads['thread_id']] = $threads;
} else {
$info['threads']['item'][$threads['thread_id']] = $threads;
}
}
}
if ($info['thread_max_rows'] > $rows) {
$info['threads']['pagenav'] = makepagenav($_GET['rowstart'],
$forum_settings['threads_per_page'],
$info['thread_max_rows'],
3,
clean_request("", ["rowstart"], FALSE)."&"
);
$info['threads']['pagenav2'] = makepagenav($_GET['rowstart'],
$forum_settings['threads_per_page'],
$info['thread_max_rows'],
3,
clean_request("", ["rowstart"], FALSE)."&",
'rowstart',
TRUE
);
}
}
return $info;
}
/**
* Returns thread variables
*
* @return array
*/
public function getThreadInfo() {
return $this->thread_info;
}
/**
* @param string $query
*/
public static function setThreadQuery($query) {
self::$custom_query = $query;
}
/**
* Thread Class constructor - This builds all essential data on load.
*/
public function setThreadInfo() {
if (!isset($_GET['thread_id']) or !isnum($_GET['thread_id'])) {
redirect(FORUM.'index.php');
}
if (isset($_GET['forum_id'])) {
if (isnum($_GET['forum_id'])) {
if (!dbcount('(forum_id)', DB_FORUM_THREADS, "forum_id=:forum_id AND thread_id=:thread_id",
[
':forum_id' => $_GET['forum_id'],
':thread_id' => $_GET['thread_id']]
)
) {
redirect(FORUM.'index.php');
}
} else {
redirect(FORUM.'index.php');
}
}
$forum_settings = self::getForumSettings();
$locale = fusion_get_locale('', [FORUM_LOCALE, FORUM_TAGS_LOCALE]);
$userdata = fusion_get_userdata();
$forum_index = dbquery_tree(DB_FORUMS, 'forum_id', 'forum_cat');
$this->thread_data = self::getThread($_GET['thread_id']); // fetch query and define iMOD
if (!empty($this->thread_data) && !empty($_GET['thread_id']) && isnum($_GET['thread_id']) && $this->checkForumAccess($forum_index, 0, $_GET['thread_id'])) {
// get post_count, lastpost_id, first_post_id.
$thread_stat = self::getThreadStats($_GET['thread_id']);
// Set the thread permissions
$this->setThreadPermission();
if ($this->thread_data['forum_type'] == 1) {
if (fusion_get_settings("site_seo")) {
redirect(fusion_get_settings("siteurl")."infusions/forum/index.php");
}
redirect(FORUM.'index.php');
}
if ($thread_stat['post_count'] < 1) {
if (fusion_get_settings("site_seo")) {
redirect(fusion_get_settings("siteurl")."infusions/forum/index.php");
}
redirect(FORUM.'index.php');
}
// Set meta
add_to_title($this->thread_data['thread_subject']);
add_to_meta($locale['forum_0000']);
if ($this->thread_data['forum_description'] !== '') {
add_to_meta('description', $this->thread_data['forum_description']);
}
if ($this->thread_data['forum_meta'] !== '') {
add_to_meta('keywords', $this->thread_data['forum_meta']);
}
add_breadcrumb(['link' => FORUM.'index.php', 'title' => $locale['forum_0000']]);
$this->forumBreadcrumbs($forum_index, $this->thread_data['forum_id']);
add_breadcrumb(['link' => FORUM.'viewthread.php?forum_id='.$this->thread_data['forum_id'].'&thread_id='.$this->thread_data['thread_id'], 'title' => $this->thread_data['thread_subject']]);
// Override $_GET['forum_id'] against tampering
$_GET['forum_id'] = intval($this->thread_data['forum_id']);
/**
* Generate User Tracked Buttons
*/
$this->thread_info['buttons']['notify'] = [];
if ($this->getThreadPermission("can_access")) {
// only member can track the thread
if ($this->thread_data['user_tracked']) {
$this->thread_info['buttons']['notify'] = [
'link' => INFUSIONS."forum/postify.php?post=off&forum_id=".$this->thread_data['forum_id']."&thread_id=".$this->thread_data['thread_id'],
'title' => $locale['forum_0174']
];
} else {
$this->thread_info['buttons']['notify'] = [
'link' => INFUSIONS."forum/postify.php?post=on&forum_id=".$this->thread_data['forum_id']."&thread_id=".$this->thread_data['thread_id'],
'title' => $locale['forum_0175']
];
}
}
$this->thread_info['thread'] = $this->thread_data;
/**
* Generate Quick Reply Form
*/
$qr_form = ($this->getThreadPermission("can_reply") == TRUE && $this->thread_data['forum_quick_edit'] == TRUE ? QuickReply::displayQuickReply($this->thread_data) : '');
/**
* Generate Poll Form
*/
$poll = new Poll($this->thread_info);
$poll_form = $poll->generatePoll($this->thread_data);
$poll_info = $poll->getPollInfo();
/**
* Generate Attachment
*/
$attach = new Attachment($this->thread_info);
$attachments = $attach::getAttachments($this->thread_data);
/**
* Display thread bounty
*/
$bounty = new Forum_Bounty($this->thread_info);
$bounty_display = $bounty->displayBounty();
/**
* Generate Mod Form
*/
if (iMOD) {
$this->moderator()->setForumID($this->thread_data['forum_id']);
$this->moderator()->setThreadId($this->thread_data['thread_id']);
$this->moderator()->setModActions();
/**
* Thread moderation form template
*/
$addition = isset($_GET['rowstart']) ? "&rowstart=".intval($_GET['rowstart']) : "";
$this->thread_info['form_action'] = fusion_get_settings('siteurl')."infusions/forum/viewthread.php?thread_id=".intval($this->thread_data['thread_id']).$addition;
$this->thread_info['mod_options'] = [
'renew' => $locale['forum_0207'],
'delete' => $locale['forum_0201'],
$this->thread_data['thread_locked'] ? "unlock" : "lock" => $this->thread_data['thread_locked'] ? $locale['forum_0203'] : $locale['forum_0202'],
$this->thread_data['thread_sticky'] ? "nonsticky" : "sticky" => $this->thread_data['thread_sticky'] ? $locale['forum_0205'] : $locale['forum_0204'],
'move' => $locale['forum_0206']
];
$this->thread_info['mod_form'] = openform('moderator_menu', 'post', $this->thread_info['form_action']);
$this->thread_info['mod_form'] .= form_hidden('delete_item_post');
$this->thread_info['mod_form'] .= "<div class='btn-group m-r-10'>\n
".form_button("check_all", $locale['forum_0080'], $locale['forum_0080'], ['class' => 'btn-default btn-sm', "type" => "button"])."
".form_button("check_none", $locale['forum_0081'], $locale['forum_0080'], ['class' => 'btn-default btn-sm', "type" => "button"])."
</div>\n
".form_button('move_posts', $locale['forum_0176'], $locale['forum_0176'], ['class' => 'btn-default btn-sm m-r-10'])."
".form_button('delete_posts', $locale['delete'], $locale['forum_0177'], ['class' => 'btn-default btn-sm'])."
<div class='pull-right'>
".form_button('go', $locale['forum_0208'], $locale['forum_0208'], ['class' => 'btn-default btn-sm pull-right m-l-10'])
.form_select('step', '', '', [
'options' => $this->thread_info['mod_options'],
'placeholder' => $locale['forum_0200'],
'width' => '250px',
'allowclear' => TRUE,
'class' => 'pull-right m-b-0 m-t-5',
'inline' => TRUE
])."
</div>\n";
$this->thread_info['mod_form'] .= closeform();
add_to_jquery("
$('#check_all').bind('click', function() {
var allVal = [];
var thread_posts = $('input[name^=delete_post]:checkbox').prop('checked', true);
$('input[name^=delete_post]:checked').each(function(e) {
var val = $(this).val();
allVal.push($(this).val());
});
$('#delete_item_post').val(allVal);
});
$('#check_none').bind('click', function() {
$('#delete_item_post').val('');
var thread_posts = $('input[name^=delete_post]:checkbox').prop('checked', false); });
");
}
$this->thread_info += [
'thread' => $this->thread_data,
'thread_id' => $this->thread_data['thread_id'],
'forum_id' => $this->thread_data['forum_id'],
'thread_tags' => $this->thread_data['thread_tags'],
'thread_tags_display' => '',
'buttons' => [],
'forum_cat' => isset($_GET['forum_cat']) && self::verifyForum($_GET['forum_cat']) ? $_GET['forum_cat'] : 0,
'forum_branch' => isset($_GET['forum_branch']) && self::verifyForum($_GET['forum_branch']) ? $_GET['forum_branch'] : 0,
'forum_link' => [
'link' => FORUM.'index.php?viewforum&forum_id='.$this->thread_data['forum_id'].'&forum_cat='.$this->thread_data['forum_cat'].'&forum_branch='.$this->thread_data['forum_branch'],
'title' => $this->thread_data['forum_name']
],
'thread_attachments' => $attachments,
'post_id' => isset($_GET['post_id']) && self::verifyPost($_GET['post_id']) ? $_GET['post_id'] : 0,
'pid' => isset($_GET['pid']) && isnum($_GET['pid']) ? $_GET['pid'] : 0,
'section' => isset($_GET['section']) ? $_GET['section'] : '',
'sort_post' => isset($_GET['sort_post']) ? $_GET['sort_post'] : '',
'forum_moderators' => $this->moderator()->parseForumMods($this->thread_data['forum_mods']),
'max_post_items' => $thread_stat['post_count'],
'post_firstpost' => $thread_stat['first_post_id'],
'post_lastpost' => $thread_stat['last_post_id'],
'posts_per_page' => $forum_settings['posts_per_page'],
'threads_per_page' => $forum_settings['threads_per_page'],
'lastvisited' => (isset($userdata['user_lastvisit']) && isnum($userdata['user_lastvisit'])) ? $userdata['user_lastvisit'] : time(),
'allowed_post_filters' => ['oldest', 'latest', 'high'],
'attachtypes' => explode(',', $forum_settings['forum_attachtypes']),
'quick_reply_form' => $qr_form,
'thread_bounty' => $bounty_display,
'poll_form' => $poll_form,
'poll_info' => $poll_info,
'post-filters' => [],
'mod_options' => [],
'form_action' => '',
'open_post_form' => '',
'close_post_form' => '',
'mod_form' => '',
'permissions' => $this->getThreadPermission()
];
if (!empty($this->thread_info['thread_tags'])) {
$this->thread_info['thread_tags_display'] = $this->tag(FALSE)->displayThreadTags($this->thread_info['thread_tags']);
}
/**
* Generate All Thread Buttons
*/
$this->thread_info['buttons'] += [
'print' => [
'link' => BASEDIR.'print.php?type=F&item_id='.$this->thread_data['thread_id'].'&rowstart='.$_GET['rowstart'],
'title' => $locale['forum_0178']
],
'newthread' => $this->getThreadPermission('can_post') == TRUE ?
[
'link' => FORUM.'newthread.php?forum_id='.$this->thread_data['forum_id'],
'title' => $this->thread_data['forum_type'] == 4 ? $locale['forum_0058'] : $locale['forum_0057']
] : [],
'reply' => $this->getThreadPermission('can_reply') == TRUE ?
[
'link' => FORUM.'viewthread.php?action=reply&forum_id='.$this->thread_data['forum_id'].'&thread_id='.$this->thread_data['thread_id'],
'title' => $locale['forum_0360']
] : [],
'poll' => $this->getThreadPermission('can_create_poll') == TRUE ?
[
'link' => FORUM.'viewthread.php?action=newpoll&forum_id='.$this->thread_data['forum_id'].'&thread_id='.$this->thread_data['thread_id'],
'title' => $locale['forum_0366']
] : [],
'bounty' => $this->getThreadPermission('can_start_bounty') == TRUE ? [
'link' => FORUM.'viewthread.php?action=newbounty&forum_id='.$this->thread_data['forum_id'].'&thread_id='.$this->thread_data['thread_id'],
'title' => $locale['forum_0399'],
] : [],
];
/**
* Generate Post Filters
*/
$this->thread_info['post-filters'][0] = [
'value' => FORUM.'viewthread.php?thread_id='.$this->thread_data['thread_id'].'&sort_post=oldest',
'locale' => $locale['forum_0180']
];
$this->thread_info['post-filters'][1] = [
'value' => FORUM.'viewthread.php?thread_id='.$this->thread_data['thread_id'].'&sort_post=latest',
'locale' => $locale['forum_0181']
];
if ($this->getThreadPermission("can_rate") == TRUE) {
$this->thread_info['allowed-post-filters'][2] = 'high';
$this->thread_info['post-filters'][2] = [
'value' => FORUM.'viewthread.php?thread_id='.$this->thread_info['thread_id'].'&sort_post=high',
'locale' => $locale['forum_0182']
];
}
$this->handleQuickReply();
$this->getThreadPost();
//showBenchmark(TRUE);
} else {
redirect(FORUM.'index.php');
}
}
/**
* Get the entire thread structure on specific thread id.
*
* @param int $thread_id
*
* @return array
*/
public static function getThread($thread_id = 0) {
$userdata = fusion_get_userdata();
$userid = !empty($userdata['user_id']) ? (int)$userdata['user_id'] : 0;
$query = !empty(self::$custom_query) ? self::$custom_query : "SELECT t.*, f.*,
u.user_id, u.user_name, u.user_status, u.user_avatar, u.user_joined,
IF (n.thread_id > 0, 1 , 0) 'user_tracked',
count(v.vote_user) 'thread_rated',
count(p.forum_vote_user_id) 'poll_voted'
FROM ".DB_FORUM_THREADS." t
LEFT JOIN ".DB_USERS." u on t.thread_author = u.user_id
INNER JOIN ".DB_FORUMS." f ON t.forum_id=f.forum_id
LEFT JOIN ".DB_FORUM_VOTES." v on v.thread_id = t.thread_id AND v.vote_user='".$userid."' AND v.forum_id=f.forum_id AND f.forum_type='4'
LEFT JOIN ".DB_FORUM_POLL_VOTERS." p on p.thread_id = t.thread_id AND p.forum_vote_user_id='".$userid."' AND t.thread_poll='1'
LEFT JOIN ".DB_FORUM_THREAD_NOTIFY." n on n.thread_id = t.thread_id and n.notify_user = '".$userid."'
".(multilang_table('FO') ? " WHERE ".in_group('f.forum_language', LANGUAGE)." AND " : " WHERE ")."
".groupaccess('f.forum_access')." AND t.thread_id='".intval($thread_id)."' AND t.thread_hidden='0'";
$result = dbquery($query);
if (dbrows($result)) {
$data = dbarray($result);
if ($data['forum_id']) {
Moderator::defineForumMods($data);
return $data;
} else {
redirect(FORUM.'index.php');
}
} else {
redirect(FORUM.'index.php');
}
return NULL;
}
/**
* Get post count, lastpost_id and first_post_id
*
* @param int $thread_id
*
* @return array
*/
private static function getThreadStats($thread_id) {
list($array['post_count'], $array['last_post_id'], $array['first_post_id']) = dbarraynum(dbquery("SELECT COUNT(post_id), MAX(post_id), MIN(post_id) FROM ".DB_FORUM_POSTS." WHERE thread_id='".intval($thread_id)."' AND post_hidden='0' GROUP BY thread_id"));
if (!$array['post_count']) {
redirect(FORUM.'index.php');
} // exit no.2
$_GET['rowstart'] = isset($_GET['rowstart']) && isnum($_GET['rowstart']) && $_GET['rowstart'] <= $array['last_post_id'] ? $_GET['rowstart'] : 0; // secure against XSS
return $array;
}
/**
* Set in full extent of forum permissions and current user thread permissions
*/
private function setThreadPermission() {
// Access the forum
$this->thread_info['permissions']['can_access'] = (iMOD || checkgroup($this->thread_data['forum_access']));
// Create another thread under the same forum
$this->thread_info['permissions']['can_post'] = $this->thread_info['permissions']['can_access'] && (iMOD || (checkgroup($this->thread_data['forum_post']) && $this->thread_data['forum_lock'] == FALSE));
// Upload an attachment in this thread
$this->thread_info['permissions']['can_upload_attach'] = $this->thread_data['forum_allow_attach'] == TRUE && (iMOD || (checkgroup($this->thread_data['forum_attach']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE));
// Download an attachment in this thread
$this->thread_info['permissions']['can_download_attach'] = iMOD || ($this->thread_data['forum_allow_attach'] == TRUE && checkgroup($this->thread_data['forum_attach_download']));
// Post a reply in this thread
$this->thread_info['permissions']['can_reply'] = $this->thread_data['thread_postcount'] > 0 && (iMOD || (checkgroup($this->thread_data['forum_reply']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE));
// Create a poll
$this->thread_info['permissions']['can_create_poll'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['thread_poll'] == FALSE && $this->thread_data['forum_allow_poll'] == TRUE && (iMOD || (checkgroup($this->thread_data['forum_poll']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE));
// Edit a poll (modify the poll)
$this->thread_info['permissions']['can_edit_poll'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['thread_poll'] == TRUE && (iMOD || (checkgroup($this->thread_data['forum_poll']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE && $this->thread_data['thread_author'] == fusion_get_userdata('user_id')));
// Can vote a poll
$this->thread_info['permissions']['can_vote_poll'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['poll_voted'] == FALSE && (iMOD || (checkgroup($this->thread_data['forum_vote']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE));
// Can vote in this thread
$this->thread_info['permissions']['can_rate'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['forum_type'] == 4 && (iMOD || (checkgroup($this->thread_data['forum_post_ratings']) && $this->thread_data['forum_lock'] == FALSE && $this->thread_data['thread_locked'] == FALSE));
// Can accept an answer
$this->thread_info['permissions']['can_answer'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['forum_type'] == 4 && $this->thread_data['thread_answered'] == FALSE && $this->thread_data['thread_locked'] == FALSE && ($this->thread_data['thread_author'] == fusion_get_userdata('user_id') || iMOD);
// Can start a bounty
$this->thread_info['permissions']['can_start_bounty'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['forum_type'] == 4 && iMEMBER && !$this->thread_data['thread_bounty'] && $this->thread_data['thread_locked'] == FALSE && fusion_get_userdata('user_reputation') >= self::getForumSettings('min_rep_points');
// Can edit a bounty
$this->thread_info['permissions']['can_edit_bounty'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['forum_type'] == 4 && iMEMBER && $this->thread_data['thread_bounty'] && $this->thread_data['thread_locked'] == FALSE && ($this->thread_data['thread_bounty_user'] == fusion_get_userdata('user_id') || iMOD);
// Can award bounty
$this->thread_info['permissions']['can_award_bounty'] = $this->thread_info['permissions']['can_post'] && $this->thread_data['forum_type'] == 4 && iMEMBER && $this->thread_data['thread_bounty'] && ($this->thread_data['thread_bounty_user'] == fusion_get_userdata('user_id'));
}
/**
* Get the relevant permissions of the current thread permission configuration
*
* @param null $key
*
* @return null
*/
public function getThreadPermission($key = NULL) {
if (!empty($this->thread_info['permissions'])) {
if (isset($this->thread_info['permissions'][$key])) {
return $this->thread_info['permissions'][$key];
}
return $this->thread_info['permissions'];
}
return NULL;
}
/**
* Handle post of Quick Reply Form
*/
private function handleQuickReply() {
$forum_settings = self::getForumSettings();
$locale = fusion_get_locale();
$thread = self::thread();
$userdata = fusion_get_userdata();
if (isset($_POST['post_quick_reply'])) {
if ($this->getThreadPermission("can_reply") && fusion_safe()) {
$this->thread_data = $this->thread_info['thread'];
require_once INCLUDES."flood_include.php";
if (!flood_control("post_datestamp", DB_FORUM_POSTS, "post_author='".$userdata['user_id']."'")) { // have notice
$post_data = [
'post_id' => 0,
'forum_id' => $this->thread_data['forum_id'],
'thread_id' => $this->thread_data['thread_id'],
'post_message' => form_sanitizer($_POST['post_message'], '', 'post_message'),
'post_showsig' => isset($_POST['post_showsig']) ? 1 : 0,
'post_smileys' => isset($_POST['post_smileys']) || preg_match("#(\[code\](.*?)\[/code\]|\[geshi=(.*?)\](.*?)\[/geshi\]|\[php\](.*?)\[/php\])#si", $_POST['post_message']) ? 1 : 0,
'post_author' => $userdata['user_id'],
'post_datestamp' => time(),
'post_ip' => USER_IP,
'post_ip_type' => USER_IP_TYPE,
'post_edituser' => 0,
'post_edittime' => 0,
'post_editreason' => '',
'post_hidden' => 0,
'post_locked' => $forum_settings['forum_edit_lock'] || isset($_POST['post_locked']) ? 1 : 0
];
if (fusion_safe()) { // post message is invalid or whatever is invalid
$update_forum_lastpost = FALSE;
// Prepare forum merging action
$last_post_author = dbarray(dbquery("SELECT post_author FROM ".DB_FORUM_POSTS." WHERE thread_id='".$this->thread_data['thread_id']."' ORDER BY post_id DESC LIMIT 1"));
if ($last_post_author['post_author'] == $post_data['post_author'] && $this->thread_data['forum_merge']) {
$last_message = dbarray(dbquery("SELECT post_id, post_message FROM ".DB_FORUM_POSTS." WHERE thread_id='".$this->thread_data['thread_id']."' ORDER BY post_id DESC"));
$post_data['post_id'] = $last_message['post_id'];
$post_data['post_message'] = $last_message['post_message']."\n\n".$locale['forum_0640']." ".showdate("longdate", time()).":\n".$post_data['post_message'];
dbquery_insert(DB_FORUM_POSTS, $post_data, 'update', ['primary_key' => 'post_id', 'keep_session' => TRUE]);
dbquery("UPDATE ".DB_FORUMS." SET forum_lastpost='".time()."', forum_lastpostid='".$post_data['post_id']."', forum_lastuser='".$post_data['post_author']."' WHERE forum_id='".$this->thread_data['forum_id']."'");
// update current thread
dbquery("UPDATE ".DB_FORUM_THREADS." SET thread_lastpost='".time()."', thread_lastpostid='".$post_data['post_id']."', thread_lastuser='".$post_data['post_author']."' WHERE thread_id='".$this->thread_data['thread_id']."'");
} else {
$update_forum_lastpost = TRUE;
dbquery_insert(DB_FORUM_POSTS, $post_data, 'save', ['primary_key' => 'post_id', 'keep_session' => TRUE]);
$post_data['post_id'] = dblastid();
dbquery("UPDATE ".DB_USERS." SET user_posts=user_posts+1 WHERE user_id='".$post_data['post_author']."'");
}
if (!empty($_FILES)
&& is_uploaded_file($_FILES['file_attachments']['tmp_name'][0])
&& $thread->getThreadPermission("can_upload_attach")
) {
$upload = form_sanitizer($_FILES['file_attachments'], '', 'file_attachments');
if ($upload['error'] == 0) {
foreach ($upload['target_file'] as $arr => $file_name) {
$attach_data = [
'thread_id' => intval($this->thread_data['thread_id']),
'post_id' => $post_data['post_id'],
'attach_name' => $file_name,
'attach_mime' => $upload['type'][$arr],
'attach_size' => $upload['source_size'][$arr],
'attach_count' => 0, // downloaded times
];
dbquery_insert(DB_FORUM_ATTACHMENTS, $attach_data, "save", ['keep_session' => TRUE]);
}
}
}
// Update stats in forum and threads
if ($update_forum_lastpost) {
// find all parents and update them
$list_of_forums = get_all_parent(dbquery_tree(DB_FORUMS, 'forum_id', 'forum_cat'), $this->thread_data['forum_id']);
if (!empty($list_of_forums)) {
foreach ($list_of_forums as $fid) {
dbquery("UPDATE ".DB_FORUMS." SET forum_lastpost='".time()."', forum_postcount=forum_postcount+1, forum_lastpostid='".$post_data['post_id']."', forum_lastuser='".$post_data['post_author']."' WHERE forum_id='".$fid."'");
}
}
// update current forum
dbquery("UPDATE ".DB_FORUMS." SET forum_lastpost='".time()."', forum_postcount=forum_postcount+1, forum_lastpostid='".$post_data['post_id']."', forum_lastuser='".$post_data['post_author']."' WHERE forum_id='".$this->thread_data['forum_id']."'");
// update current thread
dbquery("UPDATE ".DB_FORUM_THREADS." SET thread_lastpost='".time()."', thread_lastpostid='".$post_data['post_id']."', thread_postcount=thread_postcount+1, thread_lastuser='".$post_data['post_author']."' WHERE thread_id='".$this->thread_data['thread_id']."'");
}
// set notify
if ($forum_settings['thread_notify'] == TRUE && isset($_POST['notify_me']) && $this->thread_data['thread_id']) {
if (!dbcount("(thread_id)", DB_FORUM_THREAD_NOTIFY,
"thread_id='".$this->thread_data['thread_id']."' AND notify_user='".$post_data['post_author']."'")
) {
dbquery("INSERT INTO ".DB_FORUM_THREAD_NOTIFY." (thread_id, notify_datestamp, notify_user, notify_status) VALUES('".$this->thread_data['thread_id']."', '".time()."', '".$post_data['post_author']."', '1')");
}
}
}
if (fusion_safe()) {
redirect(INFUSIONS."forum/postify.php?post=reply&error=0&forum_id=".intval($post_data['forum_id'])."&thread_id=".intval($post_data['thread_id'])."&post_id=".intval($post_data['post_id']));
}
}
}
}
}
/**
* Get thread posts info
*
* @todo: optimize post reply with a subnested query to reduce post^n queries.
*/
private function getThreadPost() {
global $pid;
$forum_settings = self::getForumSettings();
$userdata = fusion_get_userdata();
$locale = fusion_get_locale();
switch ($this->thread_info['sort_post']) {
case 'oldest':
$sortCol = 'p.post_datestamp ASC';
break;
case 'latest':
$sortCol = 'p.post_datestamp DESC';
break;
case 'high':
$sortCol = 'v.vote_points DESC';
break;
default:
$sortCol = 'p.post_datestamp ASC';
}
require_once INCLUDES."mimetypes_include.php";
// post query
$result = dbquery("
SELECT p.*,
SUM(v.vote_points) 'vote_points',
IF(v2.vote_id, 1, 0) 'has_voted',
v2.vote_points 'has_voted_points',
COUNT(a.attach_id) 'attach_count'
FROM ".DB_FORUM_POSTS." p
LEFT JOIN ".DB_FORUM_VOTES." v ON v.post_id=p.post_id
LEFT JOIN ".DB_FORUM_VOTES." v2 ON v2.post_id=p.post_id AND v2.vote_user='".fusion_get_userdata('user_id')."'
LEFT JOIN ".DB_FORUM_ATTACHMENTS." a ON p.thread_id=a.thread_id AND a.post_id=p.post_id
WHERE p.thread_id='".intval($_GET['thread_id'])."' AND p.post_hidden='0'
".($this->thread_info['thread']['forum_type'] == '4' ? "OR p.post_id='".intval($this->thread_info['post_firstpost'])."'" : '')."
GROUP by p.post_id
ORDER BY $sortCol LIMIT ".intval($_GET['rowstart']).", ".intval($forum_settings['posts_per_page'])
);
$this->thread_info['post_rows'] = dbrows($result);
if ($this->thread_info['post_rows'] > 0) {
$mood = self::mood();
$response = $mood->postMood();
if ($response) {
redirect(FUSION_REQUEST);
}
/* Set Threads Navigation */
$this->thread_info['thread_posts'] = format_word($this->thread_info['post_rows'], $locale['fmt_post']);
$this->thread_info['page_nav'] = '';
if ($this->thread_info['max_post_items'] > $this->thread_info['posts_per_page']) {
$this->thread_info['page_nav'] = "<div class='pull-right'>".makepagenav($_GET['rowstart'],
$this->thread_info['posts_per_page'],
$this->thread_info['max_post_items'],
3,
FORUM."viewthread.php?thread_id=".$this->thread_info['thread']['thread_id'].(isset($_GET['highlight']) ? "&highlight=".urlencode($_GET['highlight']) : '')."&")."</div>";
}
add_to_jquery("
$('.reason_button').on('click', function(e) {
var reason_div = $(this).data('target');
if ($('#'+reason_div).is(':visible')) {
$('#'+reason_div).show();
} else {
$('#'+reason_div).hide();
}
});
");
if (iMOD) {
// pass the checkbox value to an input field
add_to_jquery("
var checks = $('input[name^=delete_post]:checkbox');
checks.on('change', function() {
var string = checks.filter(':checked').map(function(i,v){
return this.value;
}).get().join(',');
$('#delete_item_post').val(string);
});
");
}
$i = 1;
// Cache the user fields in the system
$enabled_uf_fields = [];
$module = [];
$sql_condition = "";
if (!empty($forum_settings['forum_enabled_userfields'])) {
$enabled_uf_fields = explode(',', $forum_settings['forum_enabled_userfields']);
foreach ($enabled_uf_fields as $key => $values) {
if ($sql_condition)
$sql_condition .= " OR ";
$sql_condition .= "fd.field_name='".$values."'";
}
$uf_result = dbquery("
SELECT fd.*, ufc.*
FROM ".DB_USER_FIELDS." fd
INNER JOIN ".DB_USER_FIELD_CATS." ufc ON fd.field_cat=ufc.field_cat_id
WHERE $sql_condition
ORDER BY field_name ASC
");
if (dbrows($uf_result)) {
while ($ufData = dbarray($uf_result)) {
$module[$ufData['field_name']] = $ufData;
}
}
}
while ($pdata = dbarray($result)) {
$user = fusion_get_user($pdata['post_author']);
$default_author = [
'user_id' => '',
'user_name' => '',
'user_status' => '',
'user_avatar' => '',
'user_level' => '',
'user_posts' => '',
'user_groups' => '',
'user_joined' => '',
'user_lastvisit' => 0,
'user_ip' => '0.0.0.0',
'user_sig' => ''
];
if (!empty($user)) {
$author = [
'user_id' => $user['user_id'],
'user_name' => $user['user_name'],
'user_status' => $user['user_status'],
'user_avatar' => $user['user_avatar'],
'user_level' => $user['user_level'],
'user_posts' => $user['user_posts'],
'user_groups' => $user['user_groups'],
'user_joined' => $user['user_joined'],
'user_lastvisit' => $user['user_lastvisit'],
'user_ip' => $user['user_ip'],
'user_sig' => !empty($user['user_sig']) ? $user['user_sig'] : ''
];
if (!$pdata['post_showsig']) {
unset($module['user_sig']);
}
/*
* Build ['user_profiles'] info
*/
if (!empty($enabled_uf_fields)) {
foreach ($module as $field_name => $fieldAttr) {
if (!empty($user[$field_name])) {
$field_value = $user[$field_name];
if ($fieldAttr['field_type'] == 'file') {
$module_file_path = INCLUDES.'user_fields/'.$fieldAttr['field_name'].'_include.php';
$module_locale_file_path = LOCALE.LOCALESET.'user_fields/'.$fieldAttr['field_name'].'.php';
if (file_exists($module_file_path) && file_exists($module_locale_file_path)) {
$profile_method = 'display';
$user_fields = [];
include($module_locale_file_path);
include($module_file_path);
if (!empty($user_fields) && is_array($user_fields)) {
$user_fields['field_cat_name'] = $fieldAttr['field_cat_name'];
$author['user_profiles'][$field_name] = $user_fields;
}
}
} else {
// this is just normal type
$author['user_profiles'][$field_name] = [
'field_cat_name' => $fieldAttr['field_cat_name'],
'title' => $field_name['field_name'],
'value' => $field_value
];
}
}
}
}
// add author pdata in.
$pdata += $author;
}
$pdata += $default_author;
$pid = $pdata['post_id'];
// Format Post Message
$post_message = empty($pdata['post_smileys']) ? parsesmileys($pdata['post_message']) : $pdata['post_message'];
$post_message = nl2br(parseubb($post_message, '', FALSE));
$post_message = fusion_parse_user($post_message);
if (isset($_GET['highlight'])) {
$post_message = "<div class='search_result'>".$post_message."</div>\n";
}
// Marker
$marker = [
'link' => "#post_".$pdata['post_id'],
"title" => "#".($i + $_GET['rowstart']),
'id' => "post_".$pdata['post_id']
];
$post_marker = "<a class='marker' href='".$marker['link']."' id='".$marker['id']."'>".$marker['title']."</a>";
$post_marker .= "<a title='".$locale['forum_0241']."' href='#top'><i class='fa fa-angle-up'></i></a>\n";
// Post Attachments
$post_attachments = '';
if ($pdata['attach_count']) {
if ($this->getThreadPermission("can_download_attach")) {
$attachResult = dbquery("SELECT * FROM ".DB_FORUM_ATTACHMENTS." WHERE post_id='".intval($pdata['post_id'])."'");
if (dbrows($attachResult) > 0) {
$aImage = "";
$aFiles = "";
$aFiles_Count = 0;
$aImage_Count = 0;
while ($attachData = dbarray($attachResult)) {
if (in_array($attachData['attach_mime'], img_mimetypes())) {
$aImage .= display_image_attach($attachData['attach_name'], "70", "70", $pdata['post_id'])."\n";
$aFiles_Count++;
} else {
$current_file = FORUM.'attachments/'.$attachData['attach_name'];
$aFiles .= "<div class='display-inline-block'><i class='fa fa-paperclip'></i><a href='".INFUSIONS."forum/viewthread.php?thread_id=".$pdata['thread_id']."&getfiles=".$attachData['attach_id']."'>".$attachData['attach_name']."</a> ";
$aFiles .= "[<span class='small'>".(file_exists($current_file) ? parsebytesize(filesize($current_file)) : $locale['na'])." / ".$attachData['attach_count'].$locale['forum_0162']."</span>]</div>\n";
$aImage_Count++;
}
}
if (!empty($aFiles)) {
$post_attachments .= "<div class='emulated-fieldset'>\n";
$post_attachments .= "<span class='emulated-legend'>".profile_link($pdata['user_id'], $pdata['user_name'], $pdata['user_status']).' '.$locale['forum_0154'].($aFiles_Count > 1 ? $locale['forum_0158'] : $locale['forum_0157'])."</span>\n";
$post_attachments .= "<div class='attachments-list m-t-10'>".$aFiles."</div>\n";
$post_attachments .= "</div>\n";
}
if (!empty($aImage)) {
$post_attachments .= "<div class='emulated-fieldset'>\n";
$post_attachments .= "<span class='emulated-legend'>".profile_link($pdata['user_id'], $pdata['user_name'], $pdata['user_status']).' '.$locale['forum_0154'].($aImage_Count > 1 ? $locale['forum_0156'] : $locale['forum_0155'])."</span>\n";
$post_attachments .= "<div class='attachments-list'>".$aImage."</div>\n";
$post_attachments .= "</div>\n";
if (!defined('COLORBOX')) {
define('COLORBOX', TRUE);
add_to_head("<link rel='stylesheet' href='".INCLUDES."jquery/colorbox/colorbox.css' type='text/css' media='screen' />");
add_to_head("<script type='text/javascript' src='".INCLUDES."jquery/colorbox/jquery.colorbox.js'></script>");
add_to_jquery("$('a[rel^=\"attach\"]').colorbox({ current: '".$locale['forum_0159']." {current} ".$locale['forum_0160']." {total}',width:'80%',height:'80%'});");
}
}
} else {
$post_attachments = $locale['forum_0163a'];
}
} else {
$post_attachments = "<small><i class='fa fa-clipboard'></i> ".$locale['forum_0184']."</small>\n";
}
}
$pdata['user_ip'] = ($forum_settings['forum_ips'] && iMOD) ? $locale['forum_0268'].' '.$pdata['post_ip'] : '';
$pdata += [
'user_online' => $pdata['user_lastvisit'] >= time() - 300,
'is_first_post' => $pdata['post_id'] == $this->thread_info['post_firstpost'],
'is_last_post' => $pdata['post_id'] == $this->thread_info['post_lastpost'],
'user_profile_link' => profile_link($pdata['user_id'], $pdata['user_name'], $pdata['user_status']),
'user_avatar_image' => display_avatar($pdata, '50px', FALSE, FALSE, 'img-rounded'),
'user_post_count' => format_word($pdata['user_posts'], $locale['fmt_post']),
'print' => [
'link' => BASEDIR.'print.php?type=F&item_id='.$_GET['thread_id'].'&post='.$pdata['post_id'].'&nr='.($i + $_GET['rowstart']),
'title' => $locale['forum_0179']
],
'post_marker' => $post_marker,
'marker' => $marker,
'post_attachments' => $post_attachments,
'post_reply_message' => '',
'post_bounty' => [],
];
$pdata['post_message'] = $post_message;
/**
* Who has replied to this post?
* This will drag the entire forum down with +1 query per forum post. Each is 0.04s
*
* @todo:
* Many to many search very slow (TURN OFF to implement it in next release)
* Increment DB_FORUM_POSTS with 'post_replied' column and have postify set it.
*/
$replies_sql = "SELECT post_id FROM ".DB_FORUM_POSTS." WHERE post_cat=:post_id AND thread_id=:thread_id AND forum_id=:forum_id LIMIT 1";
$replies_param = [
':post_id' => $pdata['post_id'],
':thread_id' => $pdata['thread_id'],
':forum_id' => $pdata['forum_id']
];
if (dbrows(dbquery($replies_sql, $replies_param))) {
$replies_sql = "SELECT post_id, post_datestamp, post_author FROM ".DB_FORUM_POSTS." WHERE post_cat=:post_id AND thread_id=:thread_id AND forum_id=:forum_id GROUP BY post_author ORDER BY post_datestamp DESC";
$reply_result = dbquery($replies_sql, $replies_param);
if (dbrows($reply_result)) {
// who has replied
$reply_sender = [];
$last_datestamp = 0;
while ($r_data = dbarray($reply_result)) {
$user_replied = fusion_get_user($r_data['post_author']);
$r_data += [
'user_id' => $user_replied['user_id'],
'user_name' => $user_replied['user_name'],
'user_status' => $user_replied['user_status']
];
$reply_sender[$r_data['post_id']] = "
<a class='reply_sender' href='".FUSION_REQUEST."#post_".$r_data['post_id']."'>\n
".profile_link($r_data['user_id'], $r_data['user_name'], $r_data['user_status'], "", FALSE)."
</a>
";
$last_datestamp = $r_data['post_datestamp'];
}
$senders = implode(", ", $reply_sender);
$pdata['post_reply_message'] = "<i class='fa fa-reply fa-fw'></i>".sprintf($locale['forum_0527'], $senders, timer($last_datestamp));
}
}
/**
* Displays mood buttons
* This will drag the forum down with +1 query per post.
*/
$pdata['post_mood_buttons'] = $this->mood()->setPostData($pdata)->displayMoodButtons();
$pdata['post_moods'] = $this->mood()->getMoodMessage();
/*
* Bounty payment
*/
if ($this->getThreadPermission('can_award_bounty') && $pdata['post_author'] !== fusion_get_userdata('user_id')) {
$pdata['post_bounty'] = [
'link' => FORUM.'viewthread.php?action=award&forum_id='.$pdata['forum_id'].'&thread_id='.$pdata['thread_id'].'&post_id='.$pdata['post_id'],
'title' => $locale['forum_4107']
];
}
/**
* User Stuffs, Sig, User Message, Web
*/
// Quote & Edit Link
if ($this->getThreadPermission('can_reply')) {
if (!$this->thread_info['thread']['thread_locked']) {
$pdata['post_quote'] = [
'link' => INFUSIONS."forum/viewthread.php?action=reply&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'].""e=".$pdata['post_id'],
'title' => $locale['forum_0266']
];
if (iMOD || (
(($forum_settings['forum_edit_lock'] == TRUE && $pdata['is_last_post'] || $forum_settings['forum_edit_lock'] == FALSE))
&& ($userdata['user_id'] == $pdata['post_author'])
&& (self::getEditTimelimit() <= 0 || (time() - self::getEditTimelimit()) < $pdata['post_datestamp'])
)
) {
$pdata['post_edit'] = [
'link' => INFUSIONS."forum/viewthread.php?action=edit&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
'title' => $locale['edit']
];
}
$pdata['post_reply'] = [
'link' => INFUSIONS."forum/viewthread.php?action=reply&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
'title' => $locale['forum_0509']
];
} else if (iMOD) {
$pdata['post_edit'] = [
'link' => INFUSIONS."forum/viewthread.php?action=edit&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
'title' => $locale['edit']
];
}
}
// rank img
if ($pdata['user_level'] <= USER_LEVEL_ADMIN) {
if ($forum_settings['forum_ranks']) {
$pdata['user_rank'] = self::showForumRank($pdata['user_posts'], $pdata['user_level'], $pdata['user_groups']);
} else {
$pdata['user_rank'] = getuserlevel($pdata['user_level']);
}
} else {
if ($forum_settings['forum_ranks']) {
$pdata['user_rank'] = self::showForumRank($pdata['user_posts'], iMOD ? 104 : $pdata['user_level'], $pdata['user_groups']);
} else {
$pdata['user_rank'] = getuserlevel($pdata['user_level']);
}
}
// Website
if (!empty($pdata['user_web']) && (iADMIN || $pdata['user_status'] != 6 && $pdata['user_status'] != 5)) {
$user_web_url = !preg_match("@^http(s)?\:\/\/@i", $pdata['user_web']) ? "http://".$pdata['user_web'] : $pdata['user_web'];
$pdata['user_web'] = [
'link' => $user_web_url,
'title' => $locale['forum_0364']
];
} else {
$pdata['user_web'] = ['link' => '', 'title' => ''];
}
// PM link
$pdata['user_message'] = ['link' => '', 'title' => ''];
if (iMEMBER && $pdata['user_id'] != $userdata['user_id'] && (iADMIN || $pdata['user_status'] != 6 && $pdata['user_status'] != 5)) {
$pdata['user_message'] = [
'link' => BASEDIR.'messages.php?msg_send='.$pdata['user_id'],
"title" => $locale['send_message']
];
}
// User Sig
if (!empty($pdata['user_sig']) && $pdata['user_sig'] && isset($pdata['post_showsig']) && $pdata['post_showsig'] == 1 && $pdata['user_status'] != 6 && $pdata['user_status'] != 5) {
$pdata['user_sig'] = nl2br(parsesmileys(parseubb(stripslashes($pdata['user_sig']))));
} else {
$pdata['user_sig'] = "";
}
// Voting - need up or down link - accessible to author also the vote
// answered and ongoing questions.
// Answer rating
$pdata['vote_message'] = '';
//echo $data['forum_type'] == 4 ? "<br/>\n".(number_format($data['thread_postcount']-1)).$locale['forum_0365']."" : ''; // answers
// form components
$pdata['post_checkbox'] = iMOD ? "<input type='checkbox' name='delete_post[]' value='".$pdata['post_id']."'/>" : '';
// Voting up
$pdata['post_votebox'] = '';
$pdata['vote_answered'] = '';
$pdata['post_answer_check'] = '';
// Support Type
if ($this->thread_info['thread']['forum_type'] == 4) {
// If I am author, I can mark as answered
if ($this->thread_info['thread']['thread_author'] == fusion_get_userdata('user_id') or iMOD) {
// all post items have checkbox greyed.
// if thread is answered, then just this post is answer have checkbox
//print_p($this->thread_info);
if ($this->thread_info['thread']['thread_answered'] && $pdata['post_answer']) {
// Is Answer
$pdata['vote_answered'] = [
'link' => FORUM."postify.php?post=answer&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
'title' => $locale['forum_0513'] //0513
];
$pdata['post_answer_check'] = "<a href='".$pdata['vote_answered']['link']."' class='answer_button answer_checked' title='".$pdata['vote_answered']['title']."'><i class='fa fa-check fa-2x'></i></a>";
} else {
// Is not an answer
$pdata['vote_answered'] = [
'link' => FORUM."postify.php?post=answer&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
'title' => $locale['forum_0512'] //0512
];
$pdata['post_answer_check'] = "<a href='".$pdata['vote_answered']['link']."' class='answer_button answer_unchecked' title='".$pdata['vote_answered']['title']."'><i class='fa fa-check fa-2x'></i></a>";
}
}
if ($this->getThreadPermission('can_rate')) { // can vote.
$pdata['vote_up'] = [
'link' => INFUSIONS."forum/postify.php?post=voteup&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
"title" => $locale['forum_0510'],
'active' => $pdata['has_voted'] && $pdata['has_voted_points'] > 0,
];
$pdata['vote_down'] = [
'link' => INFUSIONS."forum/postify.php?post=votedown&forum_id=".$pdata['forum_id']."&thread_id=".$pdata['thread_id']."&post_id=".$pdata['post_id'],
"title" => $locale['forum_0511'],
'active' => $pdata['has_voted'] && $pdata['has_voted_points'] < 0,
];
}
$pdata['post_votebox'] = "<div class='text-center post_vote_box'>\n";
$pdata['post_votebox'] .= "<a ".(!empty($pdata['vote_up']['link']) ? "href='".$pdata['vote_up']['link']."'" : 'disabled')." class='text-center vote_up".(!empty($pdata['vote_up']['active']) && $pdata['vote_up']['active'] ? " text-warning" : '').(!empty($pdata['vote_up']['link']) ? '' : ' disabled')."' title='".$locale['forum_0510']."'>\n<i class='fa fa-caret-up fa-2x'></i></a>";
$pdata['post_votebox'] .= "<h3 class='m-0'>".(!empty($pdata['vote_points']) ? $pdata['vote_points'] : 0)."</h3>\n";
$pdata['post_votebox'] .= "<a ".(!empty($pdata['vote_down']['link']) ? "href='".$pdata['vote_down']['link']."'" : 'disabled')." class='text-center vote_down".(!empty($pdata['vote_down']['active']) && $pdata['vote_down']['active'] ? " text-warning" : '').(!empty($pdata['vote_down']['link']) ? '' : ' disabled')."' title='".$locale['forum_0511']."'>\n<i class='fa fa-caret-down fa-2x'></i></a>";
$pdata['post_votebox'] .= "</div>\n";
}
$pdata['post_edit_reason'] = '';
if ($pdata['post_edittime']) {
$e_user = fusion_get_user($pdata['post_edituser']);
$edit_reason = "<div class='edit_reason small'>".$locale['forum_0164']." ";
if (!empty($e_user)) {
$edit_user = [
'edit_userid' => $e_user['user_id'],
'edit_username' => $e_user['user_name'],
'edit_userstatus' => $e_user['user_status'],
];
$pdata += $edit_user;
$edit_reason .= profile_link($edit_user['edit_userid'], $edit_user['edit_username'], $edit_user['edit_userstatus']);
} else {
$edit_reason .= $locale['user_na'];
}
$edit_reason .= " ".$locale['forum_0167']." ".showdate("forumdate", $pdata['post_edittime']).", ".timer($pdata['post_edittime']);
if ($pdata['post_editreason'] && iMEMBER) {
$edit_reason .= " - <a id='reason_pid_".$pdata['post_id']."' rel='".$pdata['post_id']."' class='reason_button pointer' data-target='reason_div_pid_".$pdata['post_id']."'>";
$edit_reason .= "<strong>".$locale['forum_0165']."</strong>";
$edit_reason .= "</a></div>";
$edit_reason .= "<div id='reason_div_pid_".$pdata['post_id']."' class='post_reason' style='display:none;'><span class='text-lighter'>- ".$pdata['post_editreason']."</span></div>\n";
} else {
$edit_reason .= "</div>";
}
$pdata['post_edit_reason'] = $edit_reason;
}
// Custom Post Message Link/Buttons
$pdata['post_links'] = !empty($pdata['post_quote']) ? "<a class='btn btn-xs btn-default' title='".$pdata['post_quote']["title"]."' href='".$pdata['post_quote']['link']."'>".$pdata['post_quote']['title']."</a>\n" : '';
$pdata['post_links'] .= !empty($pdata['post_edit']) ? "<a class='btn btn-xs btn-default' title='".$pdata['post_edit']["title"]."' href='".$pdata['post_edit']['link']."'>".$pdata['post_edit']['title']."</a>\n" : '';
$pdata['post_links'] .= !empty($pdata['print']) ? "<a class='btn btn-xs btn-default' title='".$pdata['print']["title"]."' href='".$pdata['print']['link']."'>".$pdata['print']['title']."</a>\n" : '';
$pdata['post_links'] .= !empty($pdata['user_web']) ? "<a class='btn btn-xs btn-default forum_user_actions' href='".$pdata['user_web']['link']."' target='_blank'>".$pdata['user_web']['title']."</a>\n" : '';
$pdata['post_links'] .= !empty($pdata['user_message']) ? "<a class='btn btn-xs btn-default' href='".$pdata['user_message']['link']."' target='_blank'>".$pdata['user_message']['title']."</a>\n" : '';
// Post Date
$pdata['post_date'] = $locale['forum_0524']." ".timer($pdata['post_datestamp'])." - ".showdate('forumdate', $pdata['post_datestamp']);
$pdata['post_shortdate'] = $locale['forum_0524']." ".timer($pdata['post_datestamp']);
$pdata['post_longdate'] = $locale['forum_0524']." ".showdate('forumdate', $pdata['post_datestamp']);
$this->thread_info['post_items'][$pdata['post_id']] = $pdata;
$i++;
}
}
}
/**
* New Status
*/
public function setThreadVisitor() {
if (iMEMBER) {
$userdata = fusion_get_userdata();
$thread_match = $this->thread_info['thread_id']."\|".$this->thread_info['thread']['thread_lastpost']."\|".$this->thread_info['thread']['forum_id'];
if (($this->thread_info['thread']['thread_lastpost'] < $this->thread_info['lastvisited']) && !preg_match("(^\.$thread_match$|\.$thread_match\.|\.$thread_match$)", $userdata['user_threads'])) {
dbquery("UPDATE ".DB_USERS." SET user_threads='".$userdata['user_threads'].".".stripslashes($thread_match)."' WHERE user_id='".$userdata['user_id']."'");
}
}
}
}