MyBB Hacks

Full Version: Portal_announcement
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi there,
I have been doing a small experiment to show a separate latest announcement on portal where it will display announcements from XThread based forum id and display 'bonid' i.e. custom thread fields. I duplicated the code related to announcements in portal.php but my template is portal_bonlist. If I use the below variable in portal_announcement, it works but it doesn't work with portal_bonlist

Code:
{$GLOBALS['threadfields']['bonid']}


Any suggestions?
(I am okay with core edits for now)
Here is the code that I used in portal.php

Code:
$bonlist= '';
if(!empty($mybb->settings['portal_announcementsfid']))
{

	$query = $db->simple_select("threads t", "COUNT(t.tid) AS threads", "t.visible='1' AND t.fid='10' AND t.closed NOT LIKE 'moved|%'", array('limit' => 1));
	$announcementcount = $db->fetch_field($query, "threads");

	$numannouncements = 10; // Default back to 10
	$pids = '';
	$tids = '';
	$comma = '';
	$posts = array();
	$query = $db->query("
		SELECT p.pid, p.message, p.tid, p.smilieoff
		FROM ".TABLE_PREFIX."posts p
		LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
		WHERE t.visible='1' AND t.fid='10' AND t.closed NOT LIKE 'moved|%' AND t.firstpost=p.pid
		ORDER BY t.dateline DESC
		LIMIT 0, 10"
	);
	while($getid = $db->fetch_array($query))
	{
		$attachmentcount[$getid['tid']] = $getid['attachmentcount'];
		foreach($attachmentcount as $tid => $attach_count)
		{
			if($attach_count > 0)
			{
				$pids .= ",'{$getid['pid']}'";
			}

			$posts[$getid['tid']] = $getid;
		}

		$tids .= ",'{$getid['tid']}'";
	}
	if(!empty($posts))
	{
		if($pids != '' && $mybb->settings['enableattachments'] == 1)
		{
			$pids = "pid IN(0{$pids})";
			// Now lets fetch all of the attachments for these posts
			$query = $db->simple_select("attachments", "*", $pids);
			while($attachment = $db->fetch_array($query))
			{
				$attachcache[$attachment['pid']][$attachment['aid']] = $attachment;
			}
		}

		if(is_array($forum))
		{
			foreach($forum as $fid => $forumrow)
			{
				$forumpermissions[$fid] = forum_permissions($fid);
			}
		}

		$icon_cache = $cache->read("posticons");

		$query = $db->query("
			SELECT t.*, t.username AS threadusername, u.username, u.avatar, u.avatardimensions
			FROM ".TABLE_PREFIX."threads t
			LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid = t.uid)
		    LEFT JOIN ".TABLE_PREFIX."threadfields_data td ON (td.tid = t.tid)
			WHERE t.tid IN (0{$tids}) AND t.fid='10' AND t.visible='1' AND t.closed NOT LIKE 'moved|%'
			ORDER BY t.dateline DESC
			LIMIT 0, {$numannouncements}"
		);
		while($announcement = $db->fetch_array($query))
		{
			// Make sure we can view this announcement
			if(isset($forumpermissions[$announcement['fid']]['canonlyviewownthreads']) && $forumpermissions[$announcement['fid']]['canonlyviewownthreads'] == 1 && $announcement['uid'] != $mybb->user['uid'])
			{
				continue;
			}

			$announcement['message'] = $posts[$announcement['tid']]['message'];
			$announcement['pid'] = $posts[$announcement['tid']]['pid'];
			$announcement['smilieoff'] = $posts[$announcement['tid']]['smilieoff'];
			$announcement['threadlink'] = get_thread_link($announcement['tid']);
			$announcement['forumlink'] = get_forum_link($announcement['fid']);
			$announcement['forumname'] = $forum_cache[$announcement['fid']]['name'];
			$announcement['username'] = htmlspecialchars_uni($announcement['username']);
			if(!$announcement['uid'] && !$announcement['threadusername'])
			{
				$announcement['threadusername'] = htmlspecialchars_uni($lang->guest);
			}
			else
			{
				$announcement['threadusername'] = htmlspecialchars_uni($announcement['threadusername']);
			}

			if($announcement['uid'] == 0)
			{
				$profilelink = $announcement['threadusername'];
			}
			else
			{
				$profilelink = build_profile_link($announcement['username'], $announcement['uid']);
			}

			if(!$announcement['username'])
			{
				$announcement['username'] = $announcement['threadusername'];
			}
			$announcement['subject'] = htmlspecialchars_uni($parser->parse_badwords($announcement['subject']));

			$useravatar = format_avatar($announcement['avatar'], $announcement['avatardimensions']);
			eval("\$avatar = \"".$templates->get("portal_announcement_avatar")."\";");

			$anndate = my_date('relative', $announcement['dateline']);

			if($announcement['replies'])
			{
				eval("\$numcomments = \"".$templates->get("portal_announcement_numcomments")."\";");
			}
			else
			{
				eval("\$numcomments = \"".$templates->get("portal_announcement_numcomments_no")."\";");
				$lastcomment = '';
			}

			$senditem = '';
			if($mybb->user['uid'] > 0 && $mybb->usergroup['cansendemail'] == 1)
			{
				eval("\$senditem = \"".$templates->get("portal_announcement_send_item")."\";");
			}

			$plugins->run_hooks("portal_announcement");

			$parser_options = array(
				"allow_html" => $mybb->settings['announcementshtml'] && $forum[$announcement['fid']]['allowhtml'],
				"allow_mycode" => $forum[$announcement['fid']]['allowmycode'],
				"allow_smilies" => $forum[$announcement['fid']]['allowsmilies'],
				"allow_imgcode" => $forum[$announcement['fid']]['allowimgcode'],
				"allow_videocode" => $forum[$announcement['fid']]['allowvideocode'],
				"filter_badwords" => 1
			);
			if($announcement['smilieoff'] == 1)
			{
				$parser_options['allow_smilies'] = 0;
			}

			if($mybb->user['showimages'] != 1 && $mybb->user['uid'] != 0 || $mybb->settings['guestimages'] != 1 && $mybb->user['uid'] == 0)
			{
				$parser_options['allow_imgcode'] = 0;
			}

			if($mybb->user['showvideos'] != 1 && $mybb->user['uid'] != 0 || $mybb->settings['guestvideos'] != 1 && $mybb->user['uid'] == 0)
			{
				$parser_options['allow_videocode'] = 0;
			}

			$message = $parser->parse_message($announcement['message'], $parser_options);


			eval("\$bonlists.= \"".$templates->get("portal_bonlist")."\";");
			unset($post);
		}
	}
}

You need to load the XThreads data (the fields name) in your SELECT query, and use codes to display the XThreads data properly.
There are some plugins to load XThreads data into other pages (index and/or portal) in this forum for your references, but it is a bit hard to find it.
Here are some of them:
http://mybbhacks.zingaburga.com/showthread.php?tid=1347
http://mybbhacks.zingaburga.com/showthread.php?tid=1283
http://mybbhacks.zingaburga.com/showthre...http://mybbhacks.zingaburga.com/showthread.php?tid=531&pid=1092
(06-03-2020 03:38 AM)RateU Wrote: [ -> ]You need to load the XThreads data (the fields name) in your SELECT query, and use codes to display the XThreads data properly.
There are some plugins to load XThreads data into other pages (index and/or portal) in this forum for your references, but it is a bit hard to find it.
Here are some of them:
http://mybbhacks.zingaburga.com/showthread.php?tid=1347
http://mybbhacks.zingaburga.com/showthread.php?tid=1283
http://mybbhacks.zingaburga.com/showthre...http://mybbhacks.zingaburga.com/showthread.php?tid=531&pid=1092
Yay, I will give it a try today. Yipi
Hey RateU,
Thanks for your suggestion, I managed to get it to work. Now I wanted to know if I had two different XThreads based forums and I wanted both of them on the portal in separate sections. One option is to copy the below code and replicate it with replacing templates but that feels loading extra SQL query again. Is there a way I can get different templates so that I can display them in their own style on the portal?

Here is the code if anyone needs finds this thread Smile

Code:
$bonthreads = '';
    $altbg = alt_trow();
    $bonlist = '';
    $fid = '10';
    
 		$threadfield_cache = xthreads_gettfcache($fid);
		if(!empty($threadfield_cache)){
			$xtfields = '';
			foreach($threadfield_cache as &$tf){
				$xtfields .= ', tf.'.$tf['field'].' AS xthreads_'.$tf['field'];
			}
		}

    $query = $db->query("
        SELECT t.tid, t.fid, t.uid, t.lastpost, t.lastposteruid, t.lastposter, t.subject, t.replies, t.views, u.username $xtfields
        FROM ".TABLE_PREFIX."threads t
		LEFT JOIN ".TABLE_PREFIX."threadfields_data tf ON (tf.tid = t.tid)
        LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=t.uid)
        WHERE fid=10 AND t.visible='1' AND t.closed NOT LIKE 'moved|%'
        ORDER BY t.lastpost DESC
        LIMIT 0, 10"
    );
    while($thread = $db->fetch_array($query))
    {
        $lastpostdate = my_date('relative', $thread['lastpost']);
        if(!$thread['lastposteruid'] && !$thread['lastposter'])
        {
            $lastposter = htmlspecialchars_uni($lang->guest);
        }
        else
        {
            $lastposter = htmlspecialchars_uni($thread['lastposter']);
        }
        $thread['replies'] = my_number_format($thread['replies']);
        $thread['views'] = my_number_format($thread['views']);
 
        // Don't link to guest's profiles (they have no profile).
        if($thread['lastposteruid'] == 0)
        {
            $lastposterlink = $lastposter;
        }
        else
        {
            $lastposterlink = build_profile_link($lastposter, $thread['lastposteruid']);
        }
 
        $thread['subject'] = $thread['fullsubject'] = $parser->parse_badwords($thread['subject']);
        if(my_strlen($thread['subject']) > 25)
        {
            $thread['subject'] = my_substr($thread['subject'], 0, 25) . "...";
        }
        $thread['subject'] = htmlspecialchars_uni($thread['subject']);
        $thread['fullsubject'] = htmlspecialchars_uni($thread['fullsubject']);
 
        $thread['threadlink'] = get_thread_link($thread['tid']);
        $thread['lastpostlink'] = get_thread_link($thread['tid'], 0, "lastpost");
        $thread['forumlink'] = get_forum_link($thread['fid']);
        $thread['forumname'] = $forum_cache[$thread['fid']]['name'];

        $threadfields = array();
        foreach($threadfield_cache as $k => &$v) {
            xthreads_get_xta_cache($v,$tids);
            $threadfields[$k] =& $thread['xthreads_'.$k];
            xthreads_sanitize_disp($threadfields[$k],$v,(!xthreads_empty($thread['username']) ? $thread['username'] : $thread['threadusername']));
        }

        eval("\$bonlist .= \"".$templates->get("portal_bonthreads_thread")."\";");
        $altbg = alt_trow();
    }
    if($bonlist)
    {
        eval("\$bonthreads = \"".$templates->get("portal_bonthreads")."\";");

    }

(06-07-2020 02:07 AM)Verilog Wrote: [ -> ]I managed to get it to work.

Great! You now can display XThreads data wherever you want Smile
Don't forget to cache the templates to reduce the query Biggrin

(06-07-2020 02:07 AM)Verilog Wrote: [ -> ]Now I wanted to know if I had two different XThreads based forums and I wanted both of them on the portal in separate sections. One option is to copy the below code and replicate it with replacing templates but that feels loading extra SQL query again. Is there a way I can get different templates so that I can display them in their own style on the portal?

Well, technically, you can load the threads from different forums using WHERE t.fid IN (10,11) and load the $threadfield_cache not for a specific forum only.
The problem is, there is no guarantee threads from both forums will be displayed, because it depends on the ORDER BY and the LIMIT.

For example:
ORDER BY t.lastpost DESC
Threads from forum ID 10 and 11:
1. Threads from FID 10 - lastpost time 200
2. Threads from FID 10 - lastpost time 199
3. Threads from FID 11 - lastpost time 198
4. Threads from FID 11 - lastpost time 197

You want to load 2 threads from each forums, so you put 2 in the LIMIT of the query. But only 1st and 2nd threads will be displayed, not all of them, even though your intent is to load 2 threads from each forum (2 threads from forum ID 10 and 2 threads from forum ID 11 in separate templates).
(06-07-2020 03:46 AM)RateU Wrote: [ -> ]
(06-07-2020 02:07 AM)Verilog Wrote: [ -> ]I managed to get it to work.

Great! You now can display XThreads data wherever you want Smile
Don't forget to cache the templates to reduce the query Biggrin

I used global hook and templates to do caching of templates. Smile

(06-07-2020 03:46 AM)RateU Wrote: [ -> ]
(06-07-2020 02:07 AM)Verilog Wrote: [ -> ]Now I wanted to know if I had two different XThreads based forums and I wanted both of them on the portal in separate sections. One option is to copy the below code and replicate it with replacing templates but that feels loading extra SQL query again. Is there a way I can get different templates so that I can display them in their own style on the portal?

Well, technically, you can load the threads from different forums using WHERE t.fid IN (10,11) and load the $threadfield_cache not for a specific forum only.
The problem is, there is no guarantee threads from both forums will be displayed, because it depends on the ORDER BY and the LIMIT.

For example:
ORDER BY t.lastpost DESC
Threads from forum ID 10 and 11:
1. Threads from FID 10 - lastpost time 200
2. Threads from FID 10 - lastpost time 199
3. Threads from FID 11 - lastpost time 198
4. Threads from FID 11 - lastpost time 197

You want to load 2 threads from each forums, so you put 2 in the LIMIT of the query. But only 1st and 2nd threads will be displayed, not all of them, even though your intent is to load 2 threads from each forum (2 threads from forum ID 10 and 2 threads from forum ID 11 in separate templates).

Since I wanted to use a different template for both of them, I thought about using fid using template conditional plugin to separate the content in templates. For example, I load both threads from id 10 and 11 and use different templates for their style.
Do you think that would be a good choice and solve this without using duplicate extra queries?
That's what I told you above. You can separate the threads based on the FID in separate templates, but there is no guarantee threads from both forums will be displayed.
I tried your suggestion RateU, but it generated error even though I am not directly using query related to mybb_xtattachments in above code. Any idea what might be the reason for this?

Code:
SQL Error:
    1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
Query:
SELECT * FROM mybb_xtattachments WHERE tid IN ()

The query run by the xthreads_get_xta_cache in your code.
It needs the thread id(s), but you don't supply it, based on your codes here: http://mybbhacks.zingaburga.com/showthre...http://mybbhacks.zingaburga.com/showthread.php?tid=10234&pid=2508
Here is an example to supply it:
http://mybbhacks.zingaburga.com/showthre...http://mybbhacks.zingaburga.com/showthread.php?tid=531&pid=1096
It basically loads latest threads (including XThreads data) from specific forum(s) into user's profile.
If you can change it a bit (like hooks and some other things), maybe you can get closer to what you need.
Thanks RateU, you were right about the LIMIT after using the template conditional plugin. I have encountered this problem but I will think about it Smile

Thank you for your suggestions and help with this <3
Reference URL's