Overview

Architecture

WPZylos Notification follows a multi-channel dispatcher pattern, where a single notification can be delivered through multiple independent channels simultaneously.

┌─────────────────┐
|   Notification   |  ─── defines via(), toMail(), toDatabase(), toAdminNotice()
+--──────┬────────┘
         |
         ▼
┌─────────────────────┐
|  NotificationManager |  ─── routes to channels, handles errors
+--──────┬────────────┘
         |
    ┌────┼─────────────┐
    ▼    ▼             ▼
┌──────┐ ┌──────────┐ ┌────────────┐
| Mail | | Database | | AdminNotice|
+--────┘ +--────────┘ +--──────────┘

Design Patterns

Strategy Pattern (Channels)

Each notification channel implements the NotificationChannel interface, making them interchangeable:

interface NotificationChannel
{
    public function send(object $notifiable, Notification $notification): void;
}

The NotificationManager delegates to the appropriate channel based on the notification's via() method.

Fluent Builder Pattern (Messages)

MailMessage and AdminNoticeMessage use fluent method chaining for composing message content:

$message = (new MailMessage())
    ->subject('Order Shipped')
    ->greeting('Hello!')
    ->line('Your order has shipped.')
    ->action('Track', 'https://example.com/track');

Trait-Based Composition (Notifiable)

The Notifiable trait adds notification capabilities to any class without inheritance:

class User
{
    use Notifiable;
    // User now has notify(), notifications(), unreadNotifications(), etc.
}

Service Provider Pattern

The NotificationServiceProvider registers all services in the container and wires up the built-in channels.

How It Works

  1. Define — Create a notification extending Notification with via() and channel-specific methods
  2. Send — Call $notifiable->notify($notification) or use NotificationManager::send()
  3. Route — The manager iterates channels from via(), resolving each registered channel
  4. Deliver — Each channel calls its corresponding to*() method and delivers the message
  5. Recover — If a channel fails, the error is caught and reported via do_action('wpzylos_notification_failed') without stopping other channels

Package Dependencies

  • wpzylos-core (required) — ServiceProvider base, ApplicationInterface, ContextInterface
  • wpzylos-database (optional) — Connection class for DatabaseChannel and DatabaseNotificationInstaller
  • wpzylos-mail (optional) — MailManager for advanced email sending via MailChannel