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
19
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
52 private function getHandlers(): array {
53 if ( $this->handlersByType === [] ) {
54 foreach ( $this->specs as $spec ) {
55 $obj = $this->objectFactory->createObject( $spec, [ 'assertClass' => NotificationHandler::class ] );
56 foreach ( $spec['types'] as $type ) {
57 if ( str_contains( $type, '*' ) && $type !== '*' ) {
58 // In the future we may allow more complex wildcards than setting the whole type to '*'
59 throw new RuntimeException( "Partial wildcards are not supported, tried to use \"$type\"" );
60 }
61 if ( isset( $this->handlersByType[$type] ) ) {
62 // In the future we may add something to allow overrides
63 throw new RuntimeException( "Handler for notification type \"$type\" already present" );
64 }
65 $this->handlersByType[$type] = $obj;
66 }
67 }
68 }
69 return $this->handlersByType;
70 }
71
76 public function notify( Notification $notification, RecipientSet $recipients ): void {
77 $handlers = $this->getHandlers();
78
79 // IDEA - this can queue all notifications and send on POST_SEND
80 // The middleware can handle things like filter out duplicates?
81
82 $batch = $this->middlewareChain->process(
83 new NotificationsBatch( new NotificationEnvelope( $notification, $recipients ) )
84 );
85
86 // TODO $handler could take the entire batch instead of single notification
87 // TODO do we want to pick handlers one by one? IMHO it should fan out and let different
88 // handlers to handle notifications the way the want, for example IRC handler send irc
89 foreach ( $batch as $envelope ) {
90 $scheduledNotification = $envelope->getNotification();
91 $scheduledRecipients = $envelope->getRecipientSet();
92 $handler = $handlers[$scheduledNotification->getType()] ?? $handlers['*'] ?? null;
93 if ( $handler === null ) {
94 $this->logger->warning( "No handler defined for notification type {type}", [
95 'type' => $scheduledNotification->getType(),
96 ] );
97 return;
98 }
99 $handler->notify( $scheduledNotification, $scheduledRecipients );
100 }
101 }
102
106 public function notifySimple(
107 MessageSpecifier $message,
108 UserIdentity $recipient
109 ): void {
110 $notification = new Types\SimpleNotification( $message );
111 $this->notify( $notification, new RecipientSet( [ $recipient ] ) );
112 }
113}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:82
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.
Interface for objects representing user identity.