114 $config = RequestContext::getMain()->getConfig();
116 if ( $config->get(
'EnotifWatchlist' ) || $config->get(
'ShowUpdatedMarker' ) ) {
117 $watchers = MediaWikiServices::getInstance()->getWatchedItemStore()->updateNotificationTimestamp(
134 ->userHasRight(
$editor,
'nominornewtalk' ) )
156 'watchers' => $watchers,
189 # we use $wgPasswordSender as sender's address
194 $messageCache = MediaWikiServices::getInstance()->getMessageCache();
196 # The following code is only run, if several conditions are met:
197 # 1. EmailNotification for pages (other than user_talk pages) must be enabled
198 # 2. minor edits (changes) are only regarded if the global flag indicates so
208 $this->composed_common =
false;
211 $formattedPageStatus = [
'deleted',
'created',
'moved',
'restored',
'changed' ];
213 Hooks::run(
'UpdateUserMailerFormattedPageStatus', [ &$formattedPageStatus ] );
214 if ( !in_array( $this->pageStatus, $formattedPageStatus ) ) {
215 throw new MWException(
'Not a valid page status!' );
222 ->userHasRight(
$editor,
'nominornewtalk' ) )
229 $this->
compose( $targetUser, self::USER_TALK, $messageCache );
230 $userTalkId = $targetUser->getId();
237 foreach ( $userArray as $watchingUser ) {
238 if ( $watchingUser->getOption(
'enotifwatchlistpages' )
239 && ( !
$minorEdit || $watchingUser->getOption(
'enotifminoredits' ) )
240 && $watchingUser->isEmailConfirmed()
241 && $watchingUser->getId() != $userTalkId
246 && Hooks::run(
'SendWatchlistEmailNotification', [ $watchingUser,
$title, $this ] )
248 $this->
compose( $watchingUser, self::WATCHLIST, $messageCache );
259 $user = User::newFromName( $name );
260 $this->
compose( $user, self::ALL_CHANGES, $messageCache );
279 if ( !$targetUser || $targetUser->isAnon() ) {
280 wfDebug( __METHOD__ .
": user talk page edited, but user does not exist\n" );
282 wfDebug( __METHOD__ .
": user edited their own talk page, no notification sent\n" );
286 wfDebug( __METHOD__ .
": talk page owner is blocked and cannot login, no notification sent\n" );
287 } elseif ( $targetUser->getOption(
'enotifusertalkpages' )
288 && ( !
$minorEdit || $targetUser->getOption(
'enotifminoredits' ) )
290 if ( !$targetUser->isEmailConfirmed() ) {
291 wfDebug( __METHOD__ .
": talk page owner doesn't have validated email\n" );
292 } elseif ( !Hooks::run(
'AbortTalkPageEmailNotification', [ $targetUser,
$title ] ) ) {
293 wfDebug( __METHOD__ .
": talk page update notification is aborted for this user\n" );
295 wfDebug( __METHOD__ .
": sending talk page update notification\n" );
299 wfDebug( __METHOD__ .
": talk page owner doesn't want notifications\n" );
314 $this->composed_common =
true;
316 # You as the WikiAdmin and Sysops can make use of plenty of
317 # named variables when composing your notification emails while
318 # simply editing the Meta pages
321 $postTransformKeys = [];
322 $pageTitleUrl = $this->title->getCanonicalURL();
323 $pageTitle = $this->title->getPrefixedText();
325 if ( $this->oldid ) {
328 $this->title->getCanonicalURL( [
'diff' =>
'next',
'oldid' => $this->oldid ] ) )
329 ->inContentLanguage()->text();
335 $this->title->getCanonicalURL( [
'diff' =>
'0',
'oldid' => $this->oldid ] ) )
336 ->inContentLanguage()->text();
340 $keys[
'$CHANGEDORCREATED'] =
wfMessage(
'changed' )->inContentLanguage()->text();
342 # clear $OLDID placeholder in the message template
343 $keys[
'$OLDID'] =
'';
344 $keys[
'$NEWPAGE'] =
'';
346 $keys[
'$CHANGEDORCREATED'] =
wfMessage(
'created' )->inContentLanguage()->text();
349 $keys[
'$PAGETITLE'] = $this->title->getPrefixedText();
350 $keys[
'$PAGETITLE_URL'] = $this->title->getCanonicalURL();
351 $keys[
'$PAGEMINOREDIT'] = $this->minorEdit ?
352 "\n\n" .
wfMessage(
'enotif_minoredit' )->inContentLanguage()->text() :
354 $keys[
'$UNWATCHURL'] = $this->title->getCanonicalURL(
'action=unwatch' );
356 if ( $this->editor->isAnon() ) {
357 # real anon (user:xxx.xxx.xxx.xxx)
358 $keys[
'$PAGEEDITOR'] =
wfMessage(
'enotif_anon_editor', $this->editor->getName() )
359 ->inContentLanguage()->text();
360 $keys[
'$PAGEEDITOR_EMAIL'] =
wfMessage(
'noemailtitle' )->inContentLanguage()->text();
364 ? $this->editor->getRealName() : $this->editor->getName();
365 $emailPage = SpecialPage::getSafeTitleFor(
'Emailuser', $this->editor->getName() );
366 $keys[
'$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
369 $keys[
'$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
371 Skin::makeInternalOrExternalUrl(
wfMessage(
'helppage' )->inContentLanguage()->text() )
374 # Replace this after transforming the message, T37019
375 $postTransformKeys[
'$PAGESUMMARY'] = $this->summary ==
'' ?
' - ' :
$this->summary;
382 $this->subject =
wfMessage(
'enotif_subject_' . $this->pageStatus )->inContentLanguage()
383 ->params( $pageTitle,
$keys[
'$PAGEEDITOR'] )->text();
388 $keys[
'$PAGEINTRO'] =
wfMessage(
'enotif_body_intro_' . $this->pageStatus )
389 ->inContentLanguage()->params( $pageTitle,
$keys[
'$PAGEEDITOR'], $pageTitleUrl )
395 $this->body = wordwrap( strtr(
$body, $postTransformKeys ), 72 );
397 # Reveal the page editor's address as REPLY-TO address only if
398 # the user has not opted-out and the option is enabled at the
399 # global configuration level.
401 wfMessage(
'emailsender' )->inContentLanguage()->text() );
403 && ( $this->editor->getEmail() !=
'' )
404 && $this->editor->getOption(
'enotifrevealaddr' )
408 $this->from = $editorAddress;
410 $this->from = $adminAddress;
411 $this->replyto = $editorAddress;
414 $this->from = $adminAddress;
431 if ( !$this->composed_common ) {
470 # $PAGEEDITDATE is the time and date of the page change
471 # expressed in terms of individual local time of the notification
472 # recipient, i.e. watching user
473 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
475 [
'$WATCHINGUSERNAME',
479 ? $watchingUser->getRealName() : $watchingUser->getName(),
480 $contLang->userDate( $this->timestamp, $watchingUser ),
481 $contLang->userTime( $this->timestamp, $watchingUser ) ],
485 if (
$source === self::WATCHLIST ) {
486 $headers[
'List-Help'] =
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Watchlist';
490 'replyTo' => $this->replyto,
491 'headers' => $headers,
502 if ( empty( $addresses ) ) {
506 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
508 [
'$WATCHINGUSERNAME',
511 [
wfMessage(
'enotif_impersonal_salutation' )->inContentLanguage()->text(),
512 $contLang->date( $this->timestamp,
false,
false ),
513 $contLang->time( $this->timestamp,
false,
false ) ],
517 'replyTo' => $this->replyto,
bool $wgEnotifRevealEditorAddress
Allow sending of e-mail notifications with the editor's address in "Reply-To".
$wgEnotifWatchlist
Allow users to enable email notification ("enotif") on watchlist changes.
bool $wgEnotifFromEditor
Allow sending of e-mail notifications with the editor's address as sender.
$wgEnotifUserTalk
Allow users to enable email notification ("enotif") when someone edits their user talk page.
$wgNoReplyAddress
Reply-To address for e-mail notifications.
$wgEnotifImpersonal
Send a generic mail instead of a personalised mail for each user.
$wgUsersNotifiedOnAllChanges
Array of usernames who will be sent a notification email for every change which occurs on a wiki.
$wgBlockDisablesLogin
If true, blocked users will not be allowed to login.
$wgEnotifMinorEdits
Potentially send notification mails on minor edits to pages.
$wgPasswordSender
Sender email address for e-mail notifications.
$wgEnotifUseRealName
Use real name instead of username in e-mail "from" field.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
This module processes the email notifications when the current page is changed.
sendImpersonal( $addresses)
Same as sendPersonalised but does impersonal mail suitable for bulk mailing.
canSendUserTalkEmail( $editor, $title, $minorEdit)
const ALL_CHANGES
Notification because user is notified for all changes.
sendMails()
Send any queued mails.
notifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit, $oldid=false, $pageStatus='changed')
Send emails corresponding to the user $editor editing the page $title.
sendPersonalised( $watchingUser, $source)
Does the per-user customizations to a notification e-mail (name, timestamp in proper timezone,...
const WATCHLIST
Notification is due to a watchlisted page being edited.
actuallyNotifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit, $oldid, $watchers, $pageStatus='changed')
Immediate version of notifyOnPageChange().
const USER_TALK
Notification is due to user's user talk being edited.
composeCommonMailtext(MessageCache $messageCache)
Generate the generic "this page has been changed" e-mail text.
compose( $user, $source, MessageCache $messageCache)
Compose a mail to a given user and either queue it for sending, or send it now, depending on settings...
getPageStatus()
Extensions that have hooks for UpdateUserMailerFormattedPageStatus (to provide additional pageStatus ...
Job for email notification mails.
Stores a single person's name and email address.
static newFromUser(User $user)
Create a new MailAddress object for the given user.
Cache of messages that are defined by MediaWiki namespace pages or by hooks.
transform( $message, $interface=false, $language=null, $title=null)
Represents a title within MediaWiki.
getNamespace()
Get the namespace index, i.e.
getText()
Get the text form (spaces not underscores) of the main part.
static send( $to, $from, $subject, $body, $options=[])
This function will perform a direct (authenticated) login to a SMTP Server to use for mail relaying i...
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
getName()
Get the user name, or the IP of an anonymous user.
getId()
Get the user's ID.