percipio.london :Notifications

Send notifications across a variety of delivery channels, including mail and Slack.

Send notifications across a variety of delivery channels, including mail and Slack. Notifications may also be stored in a database so they may be displayed in your web interface.

Requirements

This plugin requires Craft CMS 3.1.0 or later.

Installation

To install the plugin, follow these instructions.

1. Open your terminal and go to your Craft project:

bash
cd /path/to/project

2. Then tell Composer to load the plugin:

bash
composer require percipioglobal/craft-notifications

3. In the Control Panel, go to Settings → Plugins and click the Install” button for Notifications.

4. Copy the config.php file to config/notifications.php in your application.

5. Make sure your notifications are autoloaded by adding the following to your composer.json and runnning composer dump -o

json
"autoload": {
    "psr-4": {
        "app\\notifications\\": "./notifications"
    }
},

Introduction

Typically, notifications should be short, informational messages that notify users of something that occurred in your application. For example, if you are writing a billing application, you might send an Invoice Paid” notification to your users via the email and SMS channels.

Creating notifications

Each notification is represented by a single class (stored in the notifications directory of your application). You will have to create it manually or it will be created for you when you run the notifications/make command:

bash
./craft notifications/make BlogPostAdded

This command will place a fresh notification class in your notifications directory. Each notification class contains a via method and a variable number of message building methods (such as toMail or toDatabase) that convert the notification to a message optimized for that particular channel.

Sending notifications

Notifications can be sent in two ways, either from the configuration file when an event is fired, or from your own plugins.

First, let’s show how you configure sending a notification when for example a new blogpost is added:

php
<?php 
 
return [
    'notifications' => [
        [
            'class' => \craft\elements\Entry::class,
            'event' => \craft\elements\Entry::EVENT_AFTER_SAVE,
            'notification' => \app\notifications\BlogPostAdded::class,
        ],
    ],
];

Here we’re listening from the EVENT_AFTER_SAVE event on the Entry class of Craft which will cause our notification to be triggered every time we save an entry.

In our BlogPostAdded class we can then use the via function to determine if and how we want to send the notification:

php
/**
 * Get the notification's delivery channels.
 *
 * @return array
 */
public function via()
{
    $entry = $this->event->sender;

    if ($entry->section->handle === 'blog' && !$this->event->isNew) {
        return [
            'database' => Craft::$app->getUsers()->getUserByUsernameOrEmail('[email protected]'),
        ];
    }

    return [];
}

We know the event is an ElementEvent, which contains the sender and an isNew property, using this information we can determine that we only want to send a notification when the entry is from the blog section and it’s a new Entry.

Sending a notification from a plugin

From a plugin, you can use the notificationsService to send you own notifications.

php
use percipioglobal\notifications\Notifications; 
use app\notifications\BlogPostAdded; 
 
Notifications::getInstance()->notificationsService->send(new BlogPostAdded());

Database notifications

To save a notification in the database for later retrieval, make sure your via method returns the database key with a User object as value.

php
return [
    'database' => Craft::$app->getUsers()->getUserByUsernameOrEmail('[email protected]'),
];

When using the database notification channel, your Notification class should define a toDatabase or toArray function.

This can be as simple as:

php
public function toDatabase()
{
    return ArrayHelper::toArray($this);
}

When retrieving the notifications from the database in your templates, the notification will contain the data that is passed here.

Retrieving notifications

The notifications plugin provides a template variable to retrieve notifications and mark them as read.

Let’s see how we can loop over the notifications, this automatically uses the current logged in user to find notifications for:

twig
{% for notification in craft.notifications.unread %}
    {# The notification object contains all the data from the toDatabase or toArray function on your notification class #}
{% endfor %}

You can also retrieve the notifications through the notificationsService

php
use percipioglobal\notifications\Notifications; 

// All unread notifications
Notifications::getInstance()->notificationsService->getAllUnread();

// All notifications
Notifications::getInstance()->notificationsService->getAll();

Marking notifications as read

To mark notifications as read, we can use the Twig variable or the notificationsService as well

twig
{% for notification in craft.notifications.unread %}
    {{ craft.notifications.markAsRead(notification) }}
{% endfor %}
php
use percipioglobal\notifications\Notifications; 

Notifications::getInstance()->notificationsService->markAsRead($notification);

Delete read notifications

To keep your database clean and lean, you can delete the read notifications older than a given time frame. The default time is set to -1 month. If you want a custom time frame, provide the date within the strtotime PHP restrictions.