MediaWiki master
NotificationService.php
Go to the documentation of this file.
1<?php
2
4
7use Psr\Log\LoggerInterface;
8use RuntimeException;
10use Wikimedia\ObjectFactory\ObjectFactory;
11
18
24 'class' => RecentChangeNotificationHandler::class,
25 'services' => [
26 'UserFactory',
27 'TitleFactory',
28 ],
29 'types' => [ 'mediawiki.recent_change' ]
30 ];
31
33 private array $handlersByType = [];
34
35 private LoggerInterface $logger;
36 private ObjectFactory $objectFactory;
37 private MiddlewareChain $middlewareChain;
38 private array $specs;
39
40 public function __construct(
41 LoggerInterface $logger,
42 ObjectFactory $objectFactory,
43 MiddlewareChain $middlewareChain,
44 array $specs
45 ) {
46 $this->logger = $logger;
47 $this->objectFactory = $objectFactory;
48 $this->middlewareChain = $middlewareChain;
49 $this->specs = $specs;
50 }
51
53 private function getHandlers(): array {
54 if ( $this->handlersByType === [] ) {
55 foreach ( $this->specs as $spec ) {
56 $obj = $this->objectFactory->createObject( $spec, [ 'assertClass' => NotificationHandler::class ] );
57 foreach ( $spec['types'] as $type ) {
58 if ( str_contains( $type, '*' ) && $type !== '*' ) {
59 // In the future we may allow more complex wildcards than setting the whole type to '*'
60 throw new RuntimeException( "Partial wildcards are not supported, tried to use \"$type\"" );
61 }
62 if ( isset( $this->handlersByType[$type] ) ) {
63 // In the future we may add something to allow overrides
64 throw new RuntimeException( "Handler for notification type \"$type\" already present" );
65 }
66 $this->handlersByType[$type] = $obj;
67 }
68 }
69 }
70 return $this->handlersByType;
71 }
72
77 public function notify( Notification $notification, RecipientSet $recipients ): void {
78 $handlers = $this->getHandlers();
79
80 // IDEA - this can queue all notifications and send on POST_SEND
81 // The middleware can handle things like filter out duplicates?
82
83 $batch = $this->middlewareChain->process(
84 new NotificationsBatch( new NotificationEnvelope( $notification, $recipients ) )
85 );
86
87 // TODO $handler could take the entire batch instead of single notification
88 // TODO do we want to pick handlers one by one? IMHO it should fan out and let different
89 // handlers to handle notifications the way the want, for example IRC handler send irc
90 foreach ( $batch as $envelope ) {
91 $scheduledNotification = $envelope->getNotification();
92 $scheduledRecipients = $envelope->getRecipientSet();
93 $handler = $handlers[$scheduledNotification->getType()] ?? $handlers['*'] ?? null;
94 if ( $handler === null ) {
95 $this->logger->warning( "No handler defined for notification type {type}", [
96 'type' => $scheduledNotification->getType(),
97 ] );
98 return;
99 }
100 $handler->notify( $scheduledNotification, $scheduledRecipients );
101 }
102 }
103
107 public function notifySimple(
108 MessageSpecifier $message,
109 UserIdentity $recipient
110 ): void {
111 $notification = new Types\SimpleNotification( $message );
112 $this->notify( $notification, new RecipientSet( [ $recipient ] ) );
113 }
114}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:71
An object representing notification with list of recipients.
Notify users about things occurring.
const RECENT_CHANGE_HANDLER_SPEC
MediaWiki's notification handler for watchlist, talk page, and admin notification.
__construct(LoggerInterface $logger, ObjectFactory $objectFactory, MiddlewareChain $middlewareChain, array $specs)
notify(Notification $notification, RecipientSet $recipients)
Notify users about an event occurring.
notifySimple(MessageSpecifier $message, UserIdentity $recipient)
Notify a user with a message.
An object representing notification with list of recipients.
Accept notification events and notify users about them.
Interface for objects representing user identity.