XF 2.0 How do you create an instance of an object from one class file to another?

In the type of add-on you're doing, in the beginning you will have a larger number of writes to your table. It's unavoidable because each time the highest number of users changes to a higher value, you'll have to write that value to your table. Once the number stabilizes, it would usually only be an occasional write, if it ever gets written again at all.

And so far as your theory about all add-ons creating queries (if I understood you correctly) you're wrong. Here's a comparison with one of my add-ons turned off and turned on, look at the query counts...

Add-on off...
without.webp

Add-on on...
with.webp

I did not add any fields to the thread table. That is entirely with a separate table containing the movie info. No queries added.
 
Last edited:
In the type of add-on you're doing, in the beginning you will have a larger number of writes to your table. It's unavoidable because each time the highest number of users changes to a higher value, you'll have to write that value to your table. Once the number stabilizes, it would usually only be an occasional write, if it ever gets written again at all.

Actually, I disagree. While in general you are correct, I can forsee a case where a sudden large number of new visitors (eg some content is linked to on another site like Reddit - it does happen!) will cause almost continual updating of the database as every new session causes the a new high.

Most of the time it won't be an issue - but when you do get a lot of new users, it's going to add a lot of extra writes exactly when you don't really want them. The additional load from these simple writes won't be huge - but it all adds up and if we're optimising a very large site, that's one thing I'd generally avoid.

I propose the best method for this would be to use the CRON updating. Do you know where the CRON functions are stored in the Xenforo \src\XF files? I was actually planning to use the CRON for this once I found out how. You don't need to give me a huge explanation or anything, just if you would tell me where the source files for it are stored. I could easily set the CRON to update the cache automatically. Either way I will look for it.

You got a point there no worries I was planning on using the CRON for this. I'll check back and thank you

Cron is generally the best approach to limiting unforseen database writes.

I'd execute a cron task every few minutes to check if we've got a new high count and then if so, update the highest number count in the Simple Cache. Worst case scenario is one new database query and write every minute (crons don't run more often than every minute - and you can choose to run them less frequently if you prefer).

Cron stuff is all in XF\Cron ... but you don't need to extend anything there - basically just create a static function and define a new Cron entry in the Tools > Cron entries screen which points to your function. Take a look at the existing Cron functions for examples of how they work.
 
In the type of add-on you're doing, in the beginning you will have a larger number of writes to your table. It's unavoidable because each time the highest number of users changes to a higher value, you'll have to write that value to your table. Once the number stabilizes, it would usually only be an occasional write, if it ever gets written again at all.

And so far as your theory about all add-ons creating queries (if I understood you correctly) you're wrong. Here's a comparison with one of my add-ons turned off and turned on, look at the query counts...

Add-on off...
View attachment 177963

Add-on on...
View attachment 177964

I did not add any fields to the thread table. That is entirely with a separate table containing the movie info. No queries added.

No I don't have any theory about all add-ons creating queries. You must have misunderstood me. I was just saying that this add-on would have some type of query in it no matter what I did.

And thanks for the info. Don't you think the best idea would be to use a CRON entry to update the counts? Where are the CRON function located.

If you're creating a widget, you don't use a controller - you extend XF\Widget\AbstractWidget ... or if you're modifying an existing widget, you extend that widget using the class proxy system.

And thanks, I figured as much. The controller worked perfectly. I currently have the text display under the Members Online widget.

Just wondering how I should implement the CRON currently
 
I'd execute a cron task every few minutes to check if we've got a new high count and then if so, update the highest number count in the Simple Cache. Worst case scenario is one new database query and write every minute (crons don't run more often than every minute - and you can choose to run them less frequently if you prefer).

Cron stuff is all in XF\Cron ... but you don't need to extend anything there - basically just create a static function and define a new Cron entry in the Tools > Cron entries screen which points to your function. Take a look at the existing Cron functions for examples of how they work.

Thank you @Sim that was what I wanted to know. I really appreciate you guys helping me.
 
Actually, I disagree. While in general you are correct, I can forsee a case where a sudden large number of new visitors (eg some content is linked to on another site like Reddit - it does happen!) will cause almost continual updating of the database as every new session causes the a new high.

Most of the time it won't be an issue - but when you do get a lot of new users, it's going to add a lot of extra writes exactly when you don't really want them. The additional load from these simple writes won't be huge - but it all adds up and if we're optimising a very large site, that's one thing I'd generally avoid.



Cron is generally the best approach to limiting unforseen database writes.

I'd execute a cron task every few minutes to check if we've got a new high count and then if so, update the highest number count in the Simple Cache. Worst case scenario is one new database query and write every minute (crons don't run more often than every minute - and you can choose to run them less frequently if you prefer).

Cron stuff is all in XF\Cron ... but you don't need to extend anything there - basically just create a static function and define a new Cron entry in the Tools > Cron entries screen which points to your function. Take a look at the existing Cron functions for examples of how they work.
I agree with you, but with the session table getting cleared from time to time, using a cron task to get the counts can give inaccurate results. It all depends on the timing. ;)

There's pros and cons to both methods I guess.
 
Here we go - note that I wrote this by hand (not in my IDE) and I have NOT tested this, so no guarantees it will work.

PHP:
<?php namespace MyAddon\Cron;

class MostOnline
{
    public static function update()
    {
        $app = \XF::app();

        /** @var \XF\Repository\SessionActivity $activityRepo */
        $activityRepo = $app->repository('XF:SessionActivity');

        $currentlyOnline = $activityRepo->getOnlineCounts();

        $mostEver = $app->simpleCache()->getSet('MyAddon')->getValue('most_ever_online');
        
        if (!isset($mostEver)) $mostEver = 0;
            
        if ($currentlyOnline['total'] > $mostEver)
        {
            $app->simpleCache()->getSet('MyAddon')->setValue('most_ever_online', $currentlyOnline['total']);
        }
    }
}

Then you create a cron entry, point the class at MyAddon\Cron\MostOnline and the function at update

Then in your widget code, you just call $mostEver = $app->simpleCache()->getSet('MyAddon')->getValue('most_ever_online'); to retrieve the value you can then display - no database query required.
 
I agree with you, but with the session table getting cleared from time to time, using a cron task to get the counts can give inaccurate results. It all depends on the timing. ;)

There's pros and cons to both methods I guess.

Exactly - it's a trade-off between potential database load vs accurate results.

I figure if you run the cron every minute - it's not going to add much load and the results are going to be reasonably accurate still, since sessions generally last 30 minutes don't they? You should get pretty accurate results even just running the cron once every 5-10 minutes.
 
Here we go - note that I wrote this by hand (not in my IDE) and I have NOT tested this, so no guarantees it will work.

PHP:
<?php namespace MyAddon\Cron;

class MostOnline
{
    public static function update()
    {
        $app = \XF::app();

        /** @var \XF\Repository\SessionActivity $activityRepo */
        $activityRepo = $app->repository('XF:SessionActivity');

        $currentlyOnline = $activityRepo->getOnlineCounts();

        $mostEver = $app->simpleCache()->getSet('MyAddon')->getValue('most_ever_online');
       
        if (!isset($mostEver)) $mostEver = 0;
           
        if ($currentlyOnline['total'] > $mostEver)
        {
            $app->simpleCache()->getSet('MyAddon')->setValue('most_ever_online', $currentlyOnline['total']);
        }
    }
}

Then you create a cron entry, point the class at MyAddon\Cron\MostOnline and the function at update

Then in your widget code, you just call $mostEver = $app->simpleCache()->getSet('MyAddon')->getValue('most_ever_online'); to retrieve the value you can then display - no database query required.

I will look into this code and test it soon. I really appreciate your help. If I finish the add-on (granted I want to take my time on it to add more options -> permissions.... etc) but once I finish it I will definitely add your name into the credits of the add-on for providing the code.

Xenforo 2 needs this add-on as a free add-on. It's a great idea to release one.

Give me some time to work on it though as I don't just want to release an unfinished add-on but I will definitely add your name into the credits. I just want to work hard on it and make sure it's perfect before I release it. I don't exactly know when it will be released, just know that I am working on it and thank you for all your help guys. It means a lot.
 
Hey guys I made the add-on. Check it out if you want. It's got some good features:

https://xenforo.com/community/resources/bp-mosteveronline.6499/
Great start!

But, you've effectively replaced the XF\Widget\MembersOnline render function, stopping anyone else from extending/adding data to it in another add-on.

You should be getting the view from the parent, adding to the viewParams and returning the parent view...
Code:
<?php

namespace BP\MostEverOnline\XF\Widget;

class MembersOnline extends XFCP_MembersOnline
{
   public function render()
   {
      $view = parent::render();

      $app = \XF::app();

      $visitor = \XF::visitor();

      $options = \XF::options();

      if ($view && $options->member_online_counts)
      {
         if ($visitor->hasPermission('MostEverOnline', 'Total'))
         {
            $mostEver = $app->simpleCache()->getSet('MostEverOnline')->getValue('total_count');
            $view->setViewParam('mostEver', $mostEver);
         }

         if ($visitor->hasPermission('MostEverOnline', 'Member_Totals'))
         {
            $mostEverMembers = $app->simpleCache()->getSet('MostEverOnline')->getValue('member_count');
            $view->setViewParam('mostEverMembers', $mostEverMembers);
         }

         if ($visitor->hasPermission('MostEverOnline', 'Guest_Totals'))
         {
            $mostEverGuests = $app->simpleCache()->getSet('MostEverOnline')->getValue('guest_count');
            $view->setViewParam('mostEverGuests', $mostEverGuests);
         }
      }

      return $view;
   }
}
 
I also just noticed you're not using your add-on ID for the simplecache, which is incorrect.

You're using...
Code:
$mostEver = $app->simpleCache()->getSet('MostEverOnline')->getValue('total_count');

You should be using...
Code:
$mostEver = $app->simpleCache()->getSet('BP/MostEverOnline')->getValue('total_count');

That should be changed everywhere in your add-on.

Without that being set properly, your cache data will not be deleted if someone uninstalls your add-on.
 
And the final thing, you're overwriting app.less with your template. So, when the add-on is uninstalled, that template is removed and XF doesn't display properly. Users will have to "rebuild master data" from the XF install system to fix that when they uninstall your add-on.

app.less is a stock XF template and you shouldn't be using that as a template name in your add-on.
 
And the final thing, you're overwriting app.less with your template. So, when the add-on is uninstalled, that template is removed and XF doesn't display properly. Users will have to "rebuild master data" from the XF install system to fix that when they uninstall your add-on.

app.less is a stock XF template and you shouldn't be using that as a template name in your add-on.

They wouldn't have to rebuild there master data. I just checked on a separate installation to make sure. That template was not even edited but had been previously altered and not reverted versus making a template modification so that was by mistake. However I had updated the add-on yesterday with a template modification since that's the correct way to do it.

Although I was a bit worried by you saying that so I installed the add-on on another site and then un-installed it and that didn't happen.

However, I am updating the add-on today with your suggestions and reverting that template like it should be.

I'll be updating it here shortly. Thanks @Snog
 
Actually @Snog you were right but I fixed it just now. New version has been released with your suggestions and also a fix for reverting that template that was directly edited. I noticed that app.less did get deleted on the default style requiring a rebuild of the master data but not any other styles I was using. Why I do not know but the add-on is good to go now.
 
Back
Top Bottom