XF 2.2 Question on sending alerts

AndrewSimm

Well-known member
I have an article add-on and I am trying to add a feature to alert all users via XF and Push anytime a new article is posted. The code successfully sends alerts but is unable to finish my 20K+ user count. My article ends up not saving as _postSave never completes. How can I process these alerts more efficiently?

PHP:
 protected function _postSave()
 {

     if ($this->isInsert())
     {

         $extra = [
             'title' => $this->title,
             'article_id' => $this->article_id,
             'username' => $this->User->username
         ];

         $users = \XF::app()
             ->finder('XF:User')
             ->fetch();

         foreach($users as $sendTo)
         {
             if($sendTo->Option->doesReceiveAlert('article', 'article_article'))
             {
                 $alertRepo = $this->repository('XF:UserAlert');
                 $alertRepo->alert(
                     $sendTo,
                     $this->user_id, $this->User->username,
                     'article', $this->article_id,
                     'andrew_article', $extra
                 );
             }
         }

     }
 }
 
Look in the XF\Entity\Forum class to see how it handles a potentially long running task. In _postDelete(), you'll see this:

PHP:
$this->app()->jobManager()->enqueueUnique('forumDelete' . $this->node_id, 'XF:ForumDelete', [
        'node_id' => $this->node_id
 ]);

That is triggering a job (look at XF\Job\ForumDelete)... that class has a run method that does some stuff if a forum is deleted (like deleting potentially a lot of threads).

So in your case, get a group of user_ids, so whatever you want to do to them... loop to next group, and do whatever it is to those.

The job manager system runs behind the scenes so it's not going to block web pages or time out while it runs.
 
Look in the XF\Entity\Forum class to see how it handles a potentially long running task. In _postDelete(), you'll see this:

PHP:
$this->app()->jobManager()->enqueueUnique('forumDelete' . $this->node_id, 'XF:ForumDelete', [
        'node_id' => $this->node_id
 ]);

That is triggering a job (look at XF\Job\ForumDelete)... that class has a run method that does some stuff if a forum is deleted (like deleting potentially a lot of threads).

So in your case, get a group of user_ids, so whatever you want to do to them... loop to next group, and do whatever it is to those.

The job manager system runs behind the scenes so it's not going to block web pages or time out while it runs.
Thanks for helping and that makes sense. This is what I see in the admin panel for sending user alerts in mass.

PHP:
$this->app->jobManager()->enqueueUnique('userAlertSend', 'XF:UserAlert', [
    'criteria' => $data['criteria'],
    'alert' => $data['alert']
]);
 
Ya can be used for anything really... The UserAlert job is slightly more complex because it's extending the AbstractUserCriteriaJob class. Not necessarily a bad thing, I was just trying to keep the concept of loop + do something simple. But yes... since you are dealing with user_id as the ID and looping through users, it's probably a good route to go with it.
 
Top Bottom