Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/AbstractNotifier.php
<?php

namespace XF\Service;

use function
array_slice;

abstract class
AbstractNotifier extends AbstractService
{
    const
USERS_PER_CYCLE = 100;

    protected
$notifyData = [];

   
/**
     * @var \XF\Notifier\AbstractNotifier[]|null
     */
   
protected $notifiers = null;

    protected
$alerted = [];
    protected
$emailed = [];

    abstract protected function
getExtraJobData();
    abstract protected function
loadNotifiers();
    abstract protected function
loadExtraUserData(array $users);
    abstract protected function
canUserViewContent(\XF\Entity\User $user);

    public static function
createForJob(array $extraData)
    {
        throw new \
LogicException('createForJob must be overridden');
    }

    public function
notify($timeLimit = null)
    {
       
$this->ensureDataLoaded();

       
$endTime = $timeLimit > 0 ? microtime(true) + $timeLimit : null;

        foreach (
$this->getNotifiers() AS $type => $notifier)
        {
           
$data = $this->notifyData[$type];
            if (!
$data)
            {
               
// already processed or nothing to do
               
continue;
            }

           
$newData = $this->notifyType($notifier, $data, $endTime);
           
$this->notifyData[$type] = $newData;

            if (
$endTime && microtime(true) >= $endTime)
            {
                break;
            }
        }
    }

    public function
notifyAndEnqueue($timeLimit = null)
    {
       
$this->notify($timeLimit);
        return
$this->enqueueJobIfNeeded();
    }

    protected function
notifyType(\XF\Notifier\AbstractNotifier $notifier, array $data, $endTime = null)
    {
        do
        {
           
$notifyUsers = array_slice($data, 0, self::USERS_PER_CYCLE, true);
           
$users = $notifier->getUserData(array_keys($notifyUsers));

           
$this->loadExtraUserData($users);

            foreach (
$notifyUsers AS $userId => $notify)
            {
                unset(
$data[$userId]);

                if (!isset(
$users[$userId]))
                {
                    continue;
                }

               
$user = $users[$userId];

                if (!
$this->canUserViewContent($user) || !$notifier->canNotify($user))
                {
                    continue;
                }

               
$alert = ($notify['alert'] && empty($this->alerted[$userId]));
                if (
$alert && $notifier->sendAlert($user))
                {
                   
$this->alerted[$userId] = true;
                }

               
$email = ($notify['email'] && empty($this->emailed[$userId]));
                if (
$email && $notifier->sendEmail($user))
                {
                   
$this->emailed[$userId] = true;
                }

                if (
$endTime && microtime(true) >= $endTime)
                {
                    return
$data;
                }
            }
        }
        while (
$data);

        return
$data;
    }

    public function
enqueueJobIfNeeded()
    {
        if (
$this->hasMore())
        {
           
$this->app->jobManager()->enqueue('XF:Notifier', $this->getJobData());

            return
true;
        }
        else
        {
            return
false;
        }
    }

    public function
getJobData()
    {
       
$this->ensureDataLoaded();

        return [
           
'service' => $this->app->extension()->resolveExtendedClassToRoot($this),
           
'extra' => $this->getExtraJobData(),
           
'notifyData' => $this->notifyData,
           
'alerted' => $this->alerted,
           
'emailed' => $this->emailed
       
];
    }

    public function
setupFromJobData(array $data)
    {
       
$this->notifyData = $data['notifyData'];
       
$this->alerted = $data['alerted'];
       
$this->emailed =  $data['emailed'];
    }

    public function
hasMore()
    {
       
$this->ensureDataLoaded();
       
$notifiers = $this->getNotifiers();
        if (!
$notifiers)
        {
            return
false;
        }

        foreach (
$notifiers AS $type => $notifier)
        {
            if (!empty(
$this->notifyData[$type]))
            {
                return
true;
            }
        }

        return
false;
    }

    public function
addNotification($type, $userId, $alert = true, $email = false)
    {
       
$notifiers = $this->getNotifiers();

        if (!isset(
$notifiers[$type]))
        {
            throw new \
InvalidArgumentException("Unknown notification type '$type'");
        }

       
$this->notifyData[$type][$userId] = [
           
'alert' => $alert,
           
'email' => $email
       
];
    }

    public function
addNotifications($type, array $userIds, $alert = true, $email = false)
    {
       
$notifiers = $this->getNotifiers();

        if (!isset(
$notifiers[$type]))
        {
            throw new \
InvalidArgumentException("Unknown notification type '$type'");
        }

       
$value = [
           
'alert' => $alert,
           
'email' => $email
       
];

        foreach (
$userIds AS $userId)
        {
           
$this->notifyData[$type][$userId] = $value;
        }
    }

    public function
setQuotedUserIds(array $userIds)
    {
       
$this->addNotifications('quote', $userIds, true, false);
    }

    public function
setMentionedUserIds(array $userIds)
    {
       
$this->addNotifications('mention', $userIds, true, false);
    }

    public function
setNotifyDataRaw(array $data)
    {
       
$this->notifyData = $data;
    }

    public function
getNotifyData()
    {
        return
$this->notifyData;
    }

    public function
setUserAsAlerted($userId)
    {
       
$this->alerted[$userId] = true;
    }

    public function
setAlertedRaw(array $alerted)
    {
       
$this->alerted = $alerted;
    }

    public function
getAlerted()
    {
        return
$this->alerted;
    }

    public function
setUserAsEmailed($userId)
    {
       
$this->emailed[$userId] = true;
    }

    public function
setEmailedRaw(array $alerted)
    {
       
$this->emailed = $alerted;
    }

    public function
getEmailed()
    {
        return
$this->emailed;
    }

    protected function
getNotifiers()
    {
        if (
$this->notifiers === null)
        {
           
$this->notifiers = $this->loadNotifiers();
        }

        return
$this->notifiers;
    }

    protected function
ensureDataLoaded()
    {
        foreach (
$this->getNotifiers() AS $type => $notifier)
        {
            if (!isset(
$this->notifyData[$type]))
            {
               
$this->notifyData[$type] = $notifier->getDefaultNotifyData();
            }
        }
    }
}