88 return $this->pageStatus;
107 $minorEdit, $oldid =
false, $pageStatus =
'changed'
111 if (
$title->getNamespace() < 0 ) {
116 $config = RequestContext::getMain()->getConfig();
118 if ( $config->get(
'EnotifWatchlist' ) || $config->get(
'ShowUpdatedMarker' ) ) {
119 $watchers = MediaWikiServices::getInstance()->getWatchedItemStore()->updateNotificationTimestamp(
136 ->userHasRight( $editor,
'nominornewtalk' ) )
152 'editor' => $editor->
getName(),
153 'editorID' => $editor->
getId(),
154 'timestamp' => $timestamp,
155 'summary' => $summary,
156 'minorEdit' => $minorEdit,
158 'watchers' => $watchers,
159 'pageStatus' => $pageStatus
191 $pageStatus =
'changed'
193 # we use $wgPasswordSender as sender's address
198 $messageCache = MediaWikiServices::getInstance()->getMessageCache();
200 # The following code is only run, if several conditions are met:
201 # 1. EmailNotification for pages (other than user_talk pages) must be enabled
202 # 2. minor edits (changes) are only regarded if the global flag indicates so
207 $this->timestamp = $timestamp;
208 $this->summary = $summary;
209 $this->minorEdit = $minorEdit;
210 $this->oldid = $oldid;
211 $this->editor = $editor;
212 $this->composed_common =
false;
213 $this->pageStatus = $pageStatus;
215 $formattedPageStatus = [
'deleted',
'created',
'moved',
'restored',
'changed' ];
217 Hooks::runner()->onUpdateUserMailerFormattedPageStatus( $formattedPageStatus );
218 if ( !in_array( $this->pageStatus, $formattedPageStatus ) ) {
219 throw new MWException(
'Not a valid page status!' );
226 ->userHasRight( $editor,
'nominornewtalk' ) )
230 && $this->canSendUserTalkEmail( $editor,
$title, $minorEdit )
233 $this->compose( $targetUser, self::USER_TALK, $messageCache );
234 $userTalkId = $targetUser->getId();
241 foreach ( $userArray as $watchingUser ) {
242 if ( $watchingUser->getOption(
'enotifwatchlistpages' )
243 && ( !$minorEdit || $watchingUser->getOption(
'enotifminoredits' ) )
244 && $watchingUser->isEmailConfirmed()
245 && $watchingUser->getId() != $userTalkId
250 && Hooks::runner()->onSendWatchlistEmailNotification( $watchingUser,
$title, $this )
252 $this->compose( $watchingUser, self::WATCHLIST, $messageCache );
259 if ( $editor->
getName() == $name ) {
264 $this->compose( $user, self::ALL_CHANGES, $messageCache );
283 if ( !$targetUser || $targetUser->isAnon() ) {
284 wfDebug( __METHOD__ .
": user talk page edited, but user does not exist" );
285 } elseif ( $targetUser->getId() == $editor->
getId() ) {
286 wfDebug( __METHOD__ .
": user edited their own talk page, no notification sent" );
290 wfDebug( __METHOD__ .
": talk page owner is blocked and cannot login, no notification sent" );
291 } elseif ( $targetUser->getOption(
'enotifusertalkpages' )
292 && ( !$minorEdit || $targetUser->getOption(
'enotifminoredits' ) )
294 if ( !$targetUser->isEmailConfirmed() ) {
295 wfDebug( __METHOD__ .
": talk page owner doesn't have validated email" );
296 } elseif ( !Hooks::runner()->onAbortTalkPageEmailNotification( $targetUser,
$title ) ) {
297 wfDebug( __METHOD__ .
": talk page update notification is aborted for this user" );
299 wfDebug( __METHOD__ .
": sending talk page update notification" );
303 wfDebug( __METHOD__ .
": talk page owner doesn't want notifications" );
318 $this->composed_common =
true;
320 # You as the WikiAdmin and Sysops can make use of plenty of
321 # named variables when composing your notification emails while
322 # simply editing the Meta pages
325 $postTransformKeys = [];
326 $pageTitleUrl = $this->title->getCanonicalURL();
327 $pageTitle = $this->title->getPrefixedText();
329 if ( $this->oldid ) {
332 $this->title->getCanonicalURL( [
'diff' =>
'next',
'oldid' => $this->oldid ] ) )
333 ->inContentLanguage()->text();
339 $this->title->getCanonicalURL( [
'diff' =>
'0',
'oldid' => $this->oldid ] ) )
340 ->inContentLanguage()->text();
342 $keys[
'$OLDID'] = $this->oldid;
344 $keys[
'$CHANGEDORCREATED'] =
wfMessage(
'changed' )->inContentLanguage()->text();
346 # clear $OLDID placeholder in the message template
347 $keys[
'$OLDID'] =
'';
348 $keys[
'$NEWPAGE'] =
'';
350 $keys[
'$CHANGEDORCREATED'] =
wfMessage(
'created' )->inContentLanguage()->text();
353 $keys[
'$PAGETITLE'] = $this->title->getPrefixedText();
354 $keys[
'$PAGETITLE_URL'] = $this->title->getCanonicalURL();
355 $keys[
'$PAGEMINOREDIT'] = $this->minorEdit ?
356 "\n\n" .
wfMessage(
'enotif_minoredit' )->inContentLanguage()->text() :
358 $keys[
'$UNWATCHURL'] = $this->title->getCanonicalURL(
'action=unwatch' );
360 if ( $this->editor->isAnon() ) {
361 # real anon (user:xxx.xxx.xxx.xxx)
362 $keys[
'$PAGEEDITOR'] =
wfMessage(
'enotif_anon_editor', $this->editor->getName() )
363 ->inContentLanguage()->text();
364 $keys[
'$PAGEEDITOR_EMAIL'] =
wfMessage(
'noemailtitle' )->inContentLanguage()->text();
368 ? $this->editor->getRealName() : $this->editor->getName();
370 $keys[
'$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
373 $keys[
'$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
375 Skin::makeInternalOrExternalUrl(
wfMessage(
'helppage' )->inContentLanguage()->text() )
378 # Replace this after transforming the message, T37019
379 $postTransformKeys[
'$PAGESUMMARY'] = $this->summary ==
'' ?
' - ' : $this->summary;
386 $this->subject =
wfMessage(
'enotif_subject_' . $this->pageStatus )->inContentLanguage()
387 ->params( $pageTitle,
$keys[
'$PAGEEDITOR'] )->text();
392 $keys[
'$PAGEINTRO'] =
wfMessage(
'enotif_body_intro_' . $this->pageStatus )
393 ->inContentLanguage()->params( $pageTitle,
$keys[
'$PAGEEDITOR'], $pageTitleUrl )
396 $body =
wfMessage(
'enotif_body' )->inContentLanguage()->plain();
397 $body = strtr( $body,
$keys );
398 $body = $messageCache->
transform( $body,
false,
null, $this->title );
399 $this->body = wordwrap( strtr( $body, $postTransformKeys ), 72 );
401 # Reveal the page editor's address as REPLY-TO address only if
402 # the user has not opted-out and the option is enabled at the
403 # global configuration level.
405 wfMessage(
'emailsender' )->inContentLanguage()->text() );
407 && ( $this->editor->getEmail() !=
'' )
408 && $this->editor->getOption(
'enotifrevealaddr' )
410 $editorAddress = MailAddress::newFromUser( $this->editor );
412 $this->from = $editorAddress;
414 $this->from = $adminAddress;
415 $this->replyto = $editorAddress;
418 $this->from = $adminAddress;
435 if ( !$this->composed_common ) {
436 $this->composeCommonMailtext( $messageCache );
440 $this->mailTargets[] = MailAddress::newFromUser( $user );
442 $this->sendPersonalised( $user,
$source );
452 $this->sendImpersonal( $this->mailTargets );
472 $to = MailAddress::newFromUser( $watchingUser );
474 # $PAGEEDITDATE is the time and date of the page change
475 # expressed in terms of individual local time of the notification
476 # recipient, i.e. watching user
477 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
479 [
'$WATCHINGUSERNAME',
483 ? $watchingUser->getRealName() : $watchingUser->getName(),
484 $contLang->userDate( $this->timestamp, $watchingUser ),
485 $contLang->userTime( $this->timestamp, $watchingUser ) ],
489 if (
$source === self::WATCHLIST ) {
490 $headers[
'List-Help'] =
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Watchlist';
493 return UserMailer::send( $to, $this->from, $this->subject, $body, [
494 'replyTo' => $this->replyto,
495 'headers' => $headers,
506 if ( empty( $addresses ) ) {
510 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
512 [
'$WATCHINGUSERNAME',
515 [
wfMessage(
'enotif_impersonal_salutation' )->inContentLanguage()->text(),
516 $contLang->date( $this->timestamp,
false,
false ),
517 $contLang->time( $this->timestamp,
false,
false ) ],
520 return UserMailer::send( $addresses, $this->from, $this->subject, $body, [
521 '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.
static singleton( $domain=false)
Stores a single person's name and email address.
Cache of messages that are defined by MediaWiki namespace pages or by hooks.
transform( $message, $interface=false, $language=null, $title=null)
static getSafeTitleFor( $name, $subpage=false)
Get a localised Title object for a page name with a possibly unvalidated subpage.
Represents a title within MediaWiki.
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.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
getId()
Get the user's ID.