VOOZH about

URL: https://deepwiki.com/hypervel/notifications/4-sending-notifications

⇱ Sending Notifications | hypervel/notifications | DeepWiki


Loading...
Menu

Sending Notifications

This document explains the mechanisms for dispatching notifications to notifiable entities within the hypervel/notifications package. It covers the entry points for sending notifications, the distinction between synchronous and asynchronous delivery, and the underlying orchestration performed by the ChannelManager and NotificationSender classes.

For detailed information on specific sending patterns, see:

For information about how notifications are constructed for different channels, see Message Construction.

Entry Points

The ChannelManager class provides two primary methods for sending notifications:

MethodSignatureBehaviorUse Case
send()send(mixed $notifiables, mixed $notification): voidRespects ShouldQueue interface; queues if implemented, sends immediately otherwiseDefault method for all notification sending
sendNow()sendNow(mixed $notifiables, mixed $notification, ?array $channels = null): voidAlways sends immediately, bypassing queueManual control when queue behavior must be overridden

Both methods are defined in src/ChannelManager.php54-75 and accept:

  • $notifiables - A notifiable entity, array of entities, or Collection
  • $notification - An instance of a notification class
  • $channels (sendNow only) - Optional array to override channels returned by via()

Sources: src/ChannelManager.php54-75

Notification Dispatch Architecture


Dispatch Flow:

When ChannelManager::send() is invoked, it instantiates a NotificationSender with dependencies injected from the container src/ChannelManager.php56-61:

  1. The ChannelManager itself (for channel resolution)
  2. BusDispatcherContract (for queue dispatch)
  3. EventDispatcherInterface (for lifecycle events)
  4. Current locale from context src/ChannelManager.php60

The NotificationSender::send() method checks if the notification implements ShouldQueue src/NotificationSender.php44 This decision determines the execution path.

Sources: src/ChannelManager.php54-75 src/NotificationSender.php40-50

Synchronous Delivery


The sendNow() method implements synchronous delivery src/NotificationSender.php55-76:

  1. Format Notifiables: Convert the input to a Collection or array src/NotificationSender.php57
  2. Clone Notification: Create a pristine copy to avoid state pollution src/NotificationSender.php59
  3. Iterate Notifiables: Process each notifiable entity sequentially src/NotificationSender.php61
  4. Determine Channels: Call notification->via($notifiable) to get channel list src/NotificationSender.php62
  5. Apply Locale: Execute delivery within the preferred locale context src/NotificationSender.php66
  6. Generate UUID: Create a unique notification ID src/NotificationSender.php67
  7. Send to Channels: Iterate channels and invoke sendToNotifiable() src/NotificationSender.php69-72

Channel Delivery Logic:

The sendToNotifiable() method src/NotificationSender.php93-108 performs:

  1. Assign ID: Set the notification's ID property if not already set src/NotificationSender.php95-97
  2. Gate Check: Call shouldSendNotification() to check delivery permission src/NotificationSender.php99-101
  3. Dispatch to Driver: Invoke the channel driver's send() method src/NotificationSender.php103
  4. Fire Event: Dispatch NotificationSent event with response data src/NotificationSender.php105-107

Sources: src/NotificationSender.php55-108

Asynchronous Delivery

When a notification implements ShouldQueue, the queueNotification() method is invoked src/NotificationSender.php129-185 This method extracts queue configuration from the notification and dispatches a SendQueuedNotifications job for each notifiable/channel combination.


Configuration Extraction Process:

The queue configuration is extracted in this order src/NotificationSender.php149-174:

ConfigurationPrimary SourceFallback SourceLine Reference
ConnectionviaConnections()[$channel]$notification->connection149-153
Queue NameviaQueues()[$channel]$notification->queue155-159
DelaywithDelay($notifiable, $channel)$notification->delay161-165
Middlewaremiddleware($notifiable, $channel)$notification->middleware167-174

Job Dispatch:

The SendQueuedNotifications job is configured via fluent interface src/NotificationSender.php176-182:

(new SendQueuedNotifications($notifiable, $notification, [$channel]))
 ->onConnection($connection)
 ->onQueue($queue)
 ->delay(is_array($delay) ? ($delay[$channel] ?? null) : $delay)
 ->through($middleware)

Each notifiable/channel pair receives a separate job. This granularity allows independent retry policies per channel.

Sources: src/NotificationSender.php129-185

Locale Handling

The NotificationSender applies locale context during delivery using the Localizable trait src/NotificationSender.php24 Locale resolution follows a precedence hierarchy:


The preferredLocale() method implements this logic src/NotificationSender.php81-88:

  1. Check $notification->locale property
  2. Check $this->locale (from ChannelManager context)
  3. If notifiable implements HasLocalePreference, call preferredLocale()
  4. Fall back to null (application default)

The resolved locale is applied via withLocale() src/NotificationSender.php66 which temporarily sets the locale for the duration of the callback execution.

Queued Notification Locale:

For queued notifications, the locale is explicitly set on the cloned notification src/NotificationSender.php145-147:


This ensures the worker process uses the same locale context as the dispatching request.

Sources: src/NotificationSender.php66-88 src/NotificationSender.php145-147

Gate Mechanism

Before sending to any channel, the shouldSendNotification() method determines if delivery should proceed src/NotificationSender.php113-124:


The gate mechanism provides two extension points:

  1. Notification Method: Implement shouldSend($notifiable, $channel) on the notification class src/NotificationSender.php115-119
  2. Event Listener: Listen to NotificationSending event and return false src/NotificationSender.php121-123

Both mechanisms can prevent delivery. The notification method is checked first, followed by the event dispatch.

Sources: src/NotificationSender.php113-124

Context Management

The ChannelManager stores default channel and locale in Hyperf Context rather than instance properties src/ChannelManager.php197-198 src/ChannelManager.php221 src/ChannelManager.php231 This design enables request-scoped configuration:

Context KeyAccessor MethodMutator MethodDefault Fallback
__notifications.defaultChannelgetDefaultDriver()deliverVia($channel)$this->defaultChannel ('mail')
__notifications.defaultLocalegetLocale()locale($locale)$this->locale (null)

Context-based storage allows different coroutines or requests to maintain independent notification configurations without global state mutation.

Sources: src/ChannelManager.php197-232

Special Cases

Anonymous Notifiables and Database Channel

The database channel is explicitly excluded when sending to AnonymousNotifiable instances src/NotificationSender.php70-72:


This prevents attempting to persist notifications for entities without database representation.

Notification ID Assignment

Each notification receives a UUID v4 identifier src/NotificationSender.php67 src/NotificationSender.php136 For synchronous delivery, one UUID is generated per notifiable. For queued delivery, one UUID is generated per notifiable (shared across channels for that notifiable).

The ID is assigned to the notification's id property if not already set src/NotificationSender.php95-97 src/NotificationSender.php141-143

Sources: src/NotificationSender.php67 src/NotificationSender.php70-72 src/NotificationSender.php95-97 src/NotificationSender.php136 src/NotificationSender.php141-143

Summary

The notification sending mechanism centers on two classes:

The system automatically routes notifications through the appropriate path (synchronous or queued) based on interface implementation, applies locale context with a clear precedence hierarchy, and provides multiple extension points through the gate mechanism and event system.

For specific implementation patterns, refer to the child pages documenting basic usage, anonymous notifications, and queue configuration.