I have been working on extending a plugin (favourite threads by Starpaul). I wanted to show on forumdisplay to a user if they had already favourited a thread.
I was able to do that, but at the cost of 2 queries per thread; the user and the tid. Not a good plan.
I looked at how MyBB get the doticons out as that seemed like a similar function, and indeed I was able to hack the core file to repurpose the doticons. But that feels like a wrong thing to do, as now I dont have any doticons.
So I added a function to the plugin, trying to get my data added to the threadcache so I could have less queries on my page.
$plugins->add_hook("forumdisplay_thread","favorites_added");//Starpaul code is all here
//My function
function favorites_added(){global$db,$mybb,$templates,$thread,$theme,$lang,$favorites;$lang->load("favorites");// Check faves by the current user in any of these threads
if($mybb->user['uid']&&!empty($threadcache)){$query=$db->simple_select("favorites","tid,uid","uid='{$mybb->user['uid']}' AND tid IN ({$tids})");while($thread=$db->fetch_array($query)){if($threadcache[$thread['tid']]){$threadcache[$thread['tid']]['favorites']=1;}}}if($thread['favorites']==1){$thread['fave']="HELLO";}}
and unsurprisingly it does not work. Please can you help me get this right as I think this would be useful for other plugins I might make. Thank you.
ok, I have reached a point where things are sort of working, but I am struggling on the way hooks actually work in MyBB. If this was a custom page I would get a bit further, but yea, its forumdisplay. My foreach is a disaster and I am unsure how to actually find the values of the array I get from the database so I know what the code is that I have extracted. I have tried with var_dump but no dice.
How does the hook actually work? Does it take into account/ allow access to all variables arrays etc after the hook or before the hook?
forumdisplay_thread will give you access to the $thread variable, which basically is the whole thread it self.
I would rather investigate the possibility of hooking at forumdisplay_get_threads to hijack or modify the query to join the favorites table. If that works (it should one way or another, even if dirty) then just hook at forumdisplay_thread with something like:
PHP Code:
1 2 3 4 5 6 7 8 9
function favorites_added(){global$thread;if(isset($thread['favorite'])){$thread['favorite']='HELLO';}}
If you are unable to hijack/modify the query you can simple run your own in there appending its value to $threadcache. You already have this query in your original code.
Thanks Omar, I have been looking at the hooks and trying to figure it out and did try forumdisplay_get_threads but no result.
It does seem indeed that I need to add two functions; one at forumdisplay_start (maybe) or in get_threads and then another in forumdisplay_thread. I have had a look at a couple of plugins that use a cache, but they so far they all seem to actually query on every thread on the page (so not what I saw as a cache).
Not giving up, but still a bit confused on which point of the hook the code works on.
For example, get threads starts the foreach for thread cache
Code:
foreach($threadcache as $thread)
{
$plugins->run_hooks("forumdisplay_thread");
So If I use that hook is my code already part of the foreach loop?
Focus only in the forumdisplay_thread hook Leefish, that is everything you need. I tried what I commented before and failed (forumdisplay_get_threads).
If you have worked with postbit hooks then a foreach loop isn't going to be an issue to understand.
If I use the forumdisplay hook then the code runs for each thread - which is pointless to have a cache. Can I use the &$thread like I would on a postbit plugin?
(03-01-2015 02:20 PM)leefish Wrote: If I use the forumdisplay hook then the code runs for each thread - which is pointless to have a cache.
You can still have a cache. You just need to ensure that it's only ever loaded once. Typical pattern looks something like
PHP Code:
1 2 3 4 5 6 7 8 9
function bleh(){static$something_cache;if(!isset($something_cache)){$something_cache= load_cache();}$item['value']=$something_cache[$item['id']]['verifiability'];}
Quote:Can I use the &$thread like I would on a postbit plugin?
Something like that, just than only instead of:
Quote:function bleh(&$thread)
{
You will use:
Quote:function bleh()
{
global $thread;
$thread is not passes by reference here but is on the global scope.
Mege with Zinga Burga's code and you will have something like this:
PHP Code:
1 2 3 4 5 6 7 8 9 10
function bleh(){global$thread;static$something_cache;if(!isset($something_cache)){$something_cache= load_cache();}$thread['favorites']=$something_cache[$thread['tid']]['favorites'];}