MyBB Community Forums

Full Version: Plugin Hook Suggestion
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4
I'd like to suggest a hook for the showthread.php page. It's come to my attention there doesn't appear to be a way to add to the build_postbit() function without adding a new query to each and every post.

Example is my My Awards plugin. Currently each post with a user with awards has to do a query. I'm checking for a way to do a grab with all users WHERE IN($pids) before the build_postbit() in order to save 15-20 queries on the page. There appears to be sufficient hooks in the functions_post.php page inside build_postbit() function but not before I hit that function in showthread.php.

After carefully reviewing the code I've come to the conclusion that a hook is going to be needed. I also feel that this hook would benefit the plugin author community.

The hook has to appear before the build_postbit() but before the while statements to avoid looping queries.

Here is example existing code.
		// Get the actual posts from the database here.
		$posts = '';
		$query = $db->query("
			SELECT u.*, u.username AS userusername, p.*, f.*, eu.username AS editusername
			FROM ".TABLE_PREFIX."posts p
			LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid)
			LEFT JOIN ".TABLE_PREFIX."userfields f ON (f.ufid=u.uid)
			LEFT JOIN ".TABLE_PREFIX."users eu ON (eu.uid=p.edituid)
			WHERE $pids
			ORDER BY p.dateline
		");
		while($post = $db->fetch_array($query))
		{
			if($thread['firstpost'] == $post['pid'] && $thread['visible'] == 0)
			{
				$post['visible'] = 0;
			}
			$posts .= build_postbit($post);
			$post = '';
		}
		$plugins->run_hooks("showthread_linear");

And...

		// Build the threaded post display tree.
		$query = $db->query("
            SELECT p.username, p.uid, p.pid, p.replyto, p.subject, p.dateline
            FROM ".TABLE_PREFIX."posts p
            WHERE p.tid='$tid'
            $visible
            ORDER BY p.dateline
        ");
        while($post = $db->fetch_array($query))
        {
            if(!$postsdone[$post['pid']])
            {
                if($post['pid'] == $mybb->input['pid'] || ($isfirst && !$mybb->input['pid']))
                {
					$postcounter = count($postsdone);
                    $isfirst = 0;
                }
                $tree[$post['replyto']][$post['pid']] = $post;
                $postsdone[$post['pid']] = 1;
            }
        }
		
		$threadedbits = buildtree();
		$posts = build_postbit($showpost);
		eval("\$threadexbox = \"".$templates->get("showthread_threadedbox")."\";");
		$plugins->run_hooks("showthread_threaded");

Please note in the second example the hook that is there is AFTER the eval which I believe MyBB has begun to correct by moving these hooks before the eval statement.

I'm not sure the best method to add a hook there to execute my suggestion. Maybe the development team can review my post and consider my statements. I realize this might be a complicated request but I do 100% believe this will benefit authors providing a more efficient way to add postbit content.

Thank you.
Google SEO deals with the same problem, except not for pids, but for tids etc. It also predicts what's going to be shown on a page to do a WHERE x IN (1,2,3).

It currently hijacks the $query for that. Which is an ugly hack, but works. If you're not above fetching rows from the query twice, that's the solution you could use today without extra hooks or queries.

The alternative is putting a placeholder in the output and then replacing the final output. Which would work too, but risky (possible false matches) and expensive (modifying a possibly huge output string). In a good setup, queries might actually be faster.

Basically what you're suggesting would require MyBB to make a data grab run for each query. Something like $rows = $db->fetch_all_rows($query); And then the hook afterwards and you could pick the data you need from the $rows. I doubt that such a change will find its way into MyBB core.

Actually, don't you already have $pids in that particular place? Why not just use that... no need for extra hooks. Or did you mean WHERE IN ($uids)?
Quote:Actually, don't you already have $pids in that particular place? Why not just use that... no need for extra hooks. Or did you mean WHERE IN ($uids)?

I don't see a way to grab $pids without being in the loop with new queries. If I could then I could run a join query from mybb_posts, mybb_users, mybb_myawards, mybb_myawards_users. It wouldn't be the prettiest query but it should be better than a dozen queries in build_postbit I do now.

A way to do a WHERE pid IN ($pids) would rock. Then in postbit a hook would not require a query. Just a template variable.

For my next version of My Awards I want to work around this problem.

I'm not the most sophisticated coder. I simply manage by doing my best and learning as I go. If you can see a way around my predicament I'd love to hear it but it sounds like Google SEO suffers a similar problem. I think if you look at the code you'd have same conclusion about $pids.
(2011-01-21, 05:34 PM)labrocca Wrote: [ -> ]Example is my My Awards plugin. Currently each post with a user with awards has to do a query.

Why not just store a CSV list of the IDs of all the awards the user has in the users table?? Then you can query the awards table with showthread_start or something and create an array of the awards, or even fully cache them, then with the postbit hook, explode the list for the author of the current post, and output the awards based on the IDs that are stored in the column in the users table. That's what I do with my Social Sites plugin. Unless I'm completely misunderstanding your point here.
Quote:Why not just store a CSV list of the IDs of all the awards the user has in the users table??

I'm considering that too. Certainly it's an option. I still believe a hook suggestion is going to benefit authors. As you can see even the popular Google SEO has similar issues with $tid.

I may even use a hidden profile field. That might be my best option at this time.
Sorry - how is being in the loop a problem? You can still do something only the first time around, can't you?
Quote:Sorry - how is being in the loop a problem? You can still do something only the first time around, can't you?

Like I said..I'm not the most sophisticated coder.

Are you suggestion something like a big query the first time around then if exists continue/return? I suppose that's possible. I'm not sure in build_postbit that all the PIDS are given. Looking at it I don't think it does pass them at one time. I would need a full $pids list to do the query I want.
In the hello.php plugin
function hello_world_postbit($post)
{
        global $first_time_only, $pids;

        if(!$first_time_only)
        {
                $first_time_only = true;
                $post['message'] = "<strong>$pids</strong><br />{$post['message']}";
        }
}

It's not the cleanest of methods, but with MyBB you sometimes have to settle for whatever works.
Did you test that? And what hook would that work with because I don't think it will with postbit.
I tested it, you on the other hand apparently didn't... can't help you there, sorry.
Pages: 1 2 3 4