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 );
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();
366 $keys[
'$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
369 $keys[
'$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
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,