Уведомления

Есть два способа отправки уведомлений в Elgg:
  • Мгновенные уведомления

  • Уведомления на основе событий отправляются с использованием очереди уведомлений

Мгновенные уведомления

Общий метод отправки уведомления пользователю — через функцию elgg_notify_user(). Обычно он используется, когда мы хотим уведомить только одного пользователя. Такое уведомление, например, может сообщить, что кто-то лайкнул или прокомментировал пост пользователя.

Функция обычно вызывается в файле action.

Пример:

В этом примере пользователь ($user) запускает действие для оценки поста, созданного другим пользователем ($owner). После сохранения оценки (ElggAnnotation $rating) в базе данных мы можем использовать следующий код для отправки уведомления о новой оценке владельцу.

// register a notification handler
elgg_register_notification_event('annotation', 'rating', 'rate', MyNotificationHandler::class);

// The notification handler
class MyNotificationHandler extends \Elgg\Notifications\InstantNotificationEventHandler {

    protected function getNotificationSubject(\ElggUser $recipient, string $method): string {
        return elgg_echo('ratings:notification:subject');
    }

    protected function getNotificationSummary(\ElggUser $recipient, string $method): string {
        return elgg_echo('ratings:notification:summary', [
            $this->getEventActor()->getDisplayName(),
        ]);
    }

    protected function getNotificationBody(\ElggUser $recipient, string $method): string {
        $object = $this->event->getObject();

        return elgg_echo('ratings:notification:body', [
            $this->getEventActor()->getDisplayName(),
            $object->getEntity()->getOwnerEntity()->getDisplayName(),
            $rating->getValue() // A value between 1-5
        ]);
    }
}

// now notify the owner
$owner->notify('rate', $rating, [], $user);

Примечание

Во время обработки уведомления язык автоматически переключается на язык получателя.

Уведомления в очереди

На крупных сайтах может быть много пользователей, которые подписались на получение уведомлений о конкретном событии. Отправка уведомлений немедленно, когда пользователь запускает такое событие, может значительно замедлить скорость загрузки страницы. Именно поэтому отправку таких уведомлений следует оставить для очереди уведомлений Elgg.

Новые события уведомлений можно зарегистрировать с помощью функции elgg_register_notification_event() или в конфигурации elgg-plugin. Уведомления о зарегистрированных событиях будут автоматически отправляться всем подписанным пользователям.

Это рабочий процесс системы уведомлений:

  1. Кто-то выполняет действие, которое запускает событие в Elgg
    • Действие может быть create, update или delete

    • Целью действия может быть любой экземпляр класса ElggEntity (например, пост в блоге)

  2. Система уведомлений сохраняет это событие в очередь уведомлений в базе данных

  3. Когда запускается обработчик событий для одноминутного интервала, событие извлекается из очереди и обрабатывается

  4. Подписки извлекаются для пользователя, который запустил событие
    • По умолчанию это включает всех пользователей, которые включили любой метод уведомления для пользователя на www.site.com/notifications/personal/<username>

  5. Плагинам разрешено изменять подписки с помощью события [get, subscriptions]

  6. Плагинам разрешено завершать обработку очереди уведомлений с помощью события [send:before, notifications]

  7. Плагинам разрешено изменять параметры уведомления с помощью события [prepare, notification]

  8. Плагинам разрешено изменять тему/сообщение/резюме уведомления с помощью события [prepare, notification:<action>:<type>:<subtype>]

  9. Плагинам разрешено форматировать тему/сообщение/резюме уведомления для отдельных методов доставки с помощью события [format, notification:<method>]

  10. Уведомления отправляются каждому подписчику с использованием выбранных ими методов
    • Плагины могут перехватить или предотвратить отправку каждого отдельного уведомления с помощью события [send, notification:<method>]

  11. Событие [send:after, notifications] запускается для события после отправки всех уведомлений

Пример регистрации события уведомления

Указать Elgg отправлять уведомления, когда создаётся новый объект подтипа «photo»:

/**
 * Initialize the photos plugin
 */
function photos_init() {
        elgg_register_notification_event('object', 'photo');
}

Или в elgg-plugin.php:

'notifications' => [
        'object' => [
                'photo' => [
                        'create' => [
                                Elgg\Notifications\NotificationEventHandler::class => [],
                        ],
                ],
        ],
],

Примечание

Для отправки уведомлений на основе событий у вас должен быть настроен одноминутный интервал CRON.

Содержимое сообщения уведомления можно определить с помощью события 'prepare', 'notification:[action]:[type]:[subtype]'.

Пример регистрации пользовательского события уведомления

Указать Elgg отправлять уведомления, когда создаётся новый объект подтипа «album»:

// in the elgg-plugin.php
'notifications' => [
        'object' => [
                'photo' => [
                        'create' => PhotoAlbumCreateNotificationHandler::class, // this needs to be an extension of the \Elgg\Notifications\NotificationEventHandler class
                ],
        ],
],

//PhotoAlbumCreateNotificationHandler.php

class PhotoAlbumCreateNotificationHandler extends \Elgg\Notifications\NotificationEventHandler {

        /**
         * Overrule this function if you wish to modify the subscribers of this notification
         *
         * This will influence which subscribers are available in the 'get', 'subscribers' event
         */
        public function getSubscriptions(): array {
        }

        /**
         * Overrule this function if you wish to modify the subject of the notification
         *
         * A magic language key is checked for a default notification:
         * 'notification:<action>:<type>:<subtype>:subject'
         */
        protected function getNotificationSubject(\ElggUser $recipient, string $method): string {
        }

        /**
         * Overrule this function if you wish to modify the body of the notification
         *
         * A magic language key is checked for a default notification:
         * 'notification:<action>:<type>:<subtype>:body'
         */
        protected function getNotificationBody(\ElggUser $recipient, string $method): string {
        }

        /**
         * Overrule this function if you wish to modify the summary of the notification
         *
         * default: ''
         */
        protected function getNotificationSummary(\ElggUser $recipient, string $method): string {
        }

        /**
         * Overrule this function if you wish to modify the target url of the notification
         *
         * default: $event->object->getURL()
         */
        protected function getNotificationURL(\ElggUser $recipient, string $method): string {
        }

        /**
         * Overrule this function if you don't wish to allow the notification event to be configurable on the user notification settings page
         *
         * default: true
         */
        public static function isConfigurableByUser(): bool {
        }
}

Примечание

Во время обработки уведомления язык автоматически переключается на язык получателя.

Несколько обработчиков событий уведомлений

Возможно иметь несколько обработчиков уведомлений для одного и того же события. Это может быть полезно, когда вы хотите отправить разное сообщение разным получателям.

// in the elgg-plugin.php
'notifications' => [
        'user' => [
                'user' => [
                        'ban' => [
                                UserBanNotification::class => [], // send a notification to the banned user
                                AdminBanNotification::class => [], // send a notification to site admins that the user was banned
                        ],
                ],
        ],
],

Пример пользовательского содержимого уведомления

Указать Elgg использовать функцию photos_prepare_notification() для форматирования содержимого уведомления, когда создаётся новый объект подтипа „photo“:

/**
 * Initialize the photos plugin
 */
function photos_init() {
    elgg_register_notification_event('object', 'photo');
    elgg_register_event_handler('prepare', 'notification:create:object:photo', 'photos_prepare_notification');
}

/**
 * Prepare a notification message about a new photo
 *
 * @param \Elgg\Event $event 'prepare', 'notification:create:object:photo'

 * @return \Elgg\Notification\Notification
 */
function photos_prepare_notification(\Elgg\Event $event) {
    $notification_event = $event->getParam('event');

    $entity = $notification_event->getObject();
    $owner = $notification_event->getActor();
    $recipient = $event->getParam('recipient');
    $language = $event->getParam('language');
    $method = $event->getParam('method');

    /* @var $notification \Elgg\Notification\Notification */
    $notification = $event->getValue();

    // Title for the notification
    $notification->subject = elgg_echo('photos:notify:subject', [$entity->getDisplayName()], $language);

    // Message body for the notification
    $notification->body = elgg_echo('photos:notify:body', [
        $owner->getDisplayName(),
        $entity->getDisplayName(),
        $entity->getExcerpt(),
        $entity->getURL()
    ], $language);

    // Short summary about the notification
    $notification->summary = elgg_echo('photos:notify:summary', [$entity->getDisplayName()], $language);

    return $notification;
}

Примечание

Убедитесь, что уведомление будет на правильном языке, передав язык получателя в функцию elgg_echo().

Приветствие и подпись в уведомлении

Elgg по умолчанию добавляет приветствие ко всему исходящему тексту тела уведомления. Также добавляется подпись. Это означает, что вам не нужно добавлять текст типа Привет, Админ, или С уважением, ваш дружелюбный администратор сайта в тело ваших уведомлений. Если по какой-то причине вам не нужно, чтобы это происходило, вы можете предотвратить это, установив параметр уведомления add_salutation в false. Вы можете сделать это как часть параметров в elgg_notify_user() или в событии prepare, notifications. Вы можете изменить тексты приветствия и подписи в переводах.

Вы также можете настроить приветствие, переопределив представление notifications/elements/salutation. Подпись можно настроить, переопределив представление notifications/elements/sign-off.

Методы уведомлений

По умолчанию Elgg имеет три метода уведомлений: email, delayed_email и встроенный плагин site_notifications.

Email

Отправит уведомление по электронной почте получателю.

Отложенная электронная почта

Сохранит уведомления и доставит их в одном объединённом письме с интервалом, настроенным получателем (ежедневно или еженедельно).

Доступность этого метода доставки можно настроить администратором сайта в разделе Настройки сайта.

Макет объединённого письма можно настроить, переопределив представление email/delayed_email/plain_text для текстовой части письма и email/delayed_email/html для HTML-части письма.

Уведомление на сайте

Покажет уведомление на сайте.

Регистрация нового метода уведомлений

Вы можете зарегистрировать новый метод уведомлений с помощью функции elgg_register_notification_method().

Пример:

Зарегистрируйте обработчик, который будет отправлять уведомления через SMS.

/**
 * Initialize the plugin
 */
function sms_notifications_init() {
        elgg_register_notification_method('sms');
}

После регистрации нового метода он появится на странице настроек уведомлений по адресу www.example.com/notifications/personal/[username].

Отправка уведомлений с использованием вашего собственного метода

Помимо регистрации метода уведомления, вам также необходимо зарегистрировать обработчик, который занимается фактической отправкой уведомлений по SMS. Это происходит с помощью события 'send', 'notification:[method]'.

Пример:

/**
 * Initialize the plugin
 */
function sms_notifications_init () {
        elgg_register_notification_method('sms');
        elgg_register_event_handler('send', 'notification:sms', 'sms_notifications_send');
}

/**
 * Send an SMS notification
 *
 * @param \Elgg\Event $event 'send', 'notification:sms'
 *
 * @return bool
 * @internal
 */
function sms_notifications_send(\Elgg\Event $event) {
        /* @var \Elgg\Notifications\Notification $message */
        $message = $event->getParam('notification');

        $recipient = $message->getRecipient();

        if (!$recipient || !$recipient->mobile) {
                return false;
        }

        // (A pseudo SMS API class)
        $sms = new SmsApi();

        return $sms->send($recipient->mobile, $message->body);
}

Подписки

В большинстве случаев ядро Elgg берёт на себя обработку подписок, поэтому плагинам уведомлений обычно не нужно их изменять.

Однако подписки могут быть:
  • Добавлены с помощью функции \ElggEntity::addSubscription()

  • Удалены с помощью функции \ElggEntity::removeSubscription()

Возможно динамически изменять получателей уведомления с помощью события 'get', 'subscriptions'.

Пример:

/**
 * Initialize the plugin
 */
function discussion_init() {
        elgg_register_event_handler('get', 'subscriptions', 'discussion_get_subscriptions');
}

/**
 * Get subscriptions for group notifications
 *
 * @param \Elgg\Event $event 'get', 'subscriptions'
 *
 * @return void|array
 */
function discussion_get_subscriptions(\Elgg\Event $event) {
        $reply = $event->getParam('event')->getObject();

        if (!$reply instanceof \ElggDiscussionReply) {
                return;
        }

        $subscriptions = $event->getValue();

        $group_guid = $reply->getContainerEntity()->container_guid;
        $group_subscribers = elgg_get_subscriptions_for_container($group_guid);

        return ($subscriptions + $group_subscribers);
}

Заглушённые уведомления

Уведомления можно заглушить, чтобы больше не получать уведомления, например, больше не получать уведомления о новых комментариях к обсуждению.

Чтобы заглушить уведомления, вызовите \ElggEntity::muteNotifications($user_guid); $user_guid по умолчанию равен текущему авторизованному пользователю. Это приведёт к удалению всех подписок на сущность и установке специального флага, чтобы знать, что уведомления заглушены.

Правила заглушения применяются после запроса подписчиков события уведомления и применяются для следующих сущностей события уведомления: - актёр события \Elgg\Notifications\NotificationEvent::getActor() - сущность объекта события \Elgg\Notifications\NotificationEvent::getObject() - сущность контейнера объекта события \Elgg\Notifications\NotificationEvent::getObject()::getContainerEntity() - сущность владельца объекта события \Elgg\Notifications\NotificationEvent::getObject()::getOwnerEntity()

Чтобы разглушить уведомления, вызовите \ElggEntity::unmuteNotifications($user_guid); $user_guid по умолчанию равен текущему авторизованному пользователю.

Чтобы проверить, заглушены ли у пользователя уведомления, вызовите \ElggEntity::hasMutedNotifications($user_guid); $user_guid по умолчанию равен текущему авторизованному пользователю.

Вспомогательная страница

Добавлена вспомогательная страница, на которую можно ссылаться (например, в футере электронного письма) для управления заглушением на основе уведомления.

Страница должна быть подписана и использовать маршрут notifications:mute, который требует: - entity_guid — сущность, о которой уведомление - recipient_guid — получатель уведомления

Временно отключить уведомления

Пользователи могут временно отключить все уведомления, перейдя в настройки уведомлений и установив дату начала и окончания периода, в течение которого они не хотят получать никакие уведомления.

Настройки уведомлений

Вы можете хранить и извлекать настройки уведомлений пользователей с помощью \ElggUser::setNotificationSetting() и \ElggUser::getNotificationSettings().

// Setting a notification preference
// notification method: mail
// notification is enabled
// for the purpose 'group_join' (when omitted this is 'default')
$user->setNotificationSetting('mail', true, 'group_join');

// retrieving the preference
$settings = $user->getNotificationSettings('group_join');
// this wil result in an array with all the current notification methods and their state like:
// [
//      'mail' => true,
//      'site' => false,
//      'sms' => false,
// ]

Когда у пользователя ещё нет настройки для не по умолчанию цели, система откатится к настройке уведомлений „default“.

Управление уведомлениями

Когда сущность имеет возможность subscribable, элементы меню будут автоматически добавлены в меню title для управления подпиской. Это требует, чтобы сущность была предоставлена странице, чтобы она была передана в меню title.