leucosticte has uploaded a new change for review. https://gerrit.wikimedia.org/r/101443
Change subject: Add preferences checkbox to email text of watched deleted pages ...................................................................... Add preferences checkbox to email text of watched deleted pages Bug: 38642 New configuration setting: $wgEnotifDeletionsWatchlist = false; If true, makes the preferences checkbox available: "Email me the text of any page on my watchlist that is deleted" New preference: enotifdelwatchlistpages If set to 1, causes the text of the most recent revision of watched pages to be emailed to the user upon page deletion, if watchlist.wl_del_notificationtimestamp is null. New field: watchlist.wl_del_notificationtimestamp This stores the date/time when the page text was sent to the user. Cleared when the user visits the page, very much like watchlist.wl_notificationtimestamp. Change-Id: Ie49440ad940a7488ea2e855ab322ade7e33f1fe4 --- M includes/DefaultSettings.php M includes/Preferences.php M includes/User.php M includes/UserMailer.php M includes/WatchedItem.php M includes/installer/PostgresUpdater.php M includes/installer/SqliteUpdater.php M includes/specials/SpecialEditWatchlist.php M languages/messages/MessagesEn.php A maintenance/archives/patch-wl_del_notificationtimestamp.sql M maintenance/postgres/tables.sql A maintenance/sqlite/archives/patch-wl_del_notificationtimestamp.sql M maintenance/tables.sql 13 files changed, 176 insertions(+), 34 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/43/101443/1 diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 40f943f..ebf0fcc 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1423,6 +1423,12 @@ $wgEnotifWatchlist = false; /** + * Allow users to enable inclusion of revision text in email notification ("enotif") on + * watchlist changes. + */ +$wgEnotifDeletionsWatchlist = false; + +/** * Allow users to enable email notification ("enotif") when someone edits their * user talk page. */ diff --git a/includes/Preferences.php b/includes/Preferences.php index e4c7a81..51ff39b 100644 --- a/includes/Preferences.php +++ b/includes/Preferences.php @@ -188,8 +188,8 @@ global $wgAuth, $wgContLang, $wgParser, $wgCookieExpiration, $wgLanguageCode, $wgDisableTitleConversion, $wgDisableLangConversion, $wgMaxSigChars, $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication, - $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress, - $wgSecureLogin; + $wgEnotifWatchlist, $wgEnotifDeletionsWatchlist, $wgEnotifUserTalk, + $wgEnotifRevealEditorAddress, $wgSecureLogin; // retrieving user name for GENDER and misc. $userName = $user->getName(); @@ -536,6 +536,14 @@ 'disabled' => $disableEmailPrefs, ); } + if ( $wgEnotifWatchlist && $wgEnotifDeletionsWatchlist ) { + $defaultPreferences['enotifdelwatchlistpages'] = array( + 'type' => 'toggle', + 'section' => 'personal/email', + 'label-message' => 'tog-enotifdelwatchlistpages', + 'disabled' => $disableEmailPrefs, + ); + } if ( $wgEnotifUserTalk ) { $defaultPreferences['enotifusertalkpages'] = array( 'type' => 'toggle', diff --git a/includes/User.php b/includes/User.php index a2e7023..d1cece4 100644 --- a/includes/User.php +++ b/includes/User.php @@ -3110,7 +3110,10 @@ if ( $id != 0 ) { $dbw = wfGetDB( DB_MASTER ); $dbw->update( 'watchlist', - array( /* SET */ 'wl_notificationtimestamp' => null ), + array( /* SET */ + 'wl_notificationtimestamp' => null, + 'wl_del_notificationtimestamp' => null + ), array( /* WHERE */ 'wl_user' => $id ), __METHOD__ ); diff --git a/includes/UserMailer.php b/includes/UserMailer.php index 39c3e18..491fefb 100644 --- a/includes/UserMailer.php +++ b/includes/UserMailer.php @@ -461,7 +461,8 @@ */ class EmailNotification { protected $subject, $body, $replyto, $from; - protected $timestamp, $summary, $minorEdit, $oldid, $composed_common, $pageStatus; + protected $timestamp, $summary, $minorEdit, $oldid, $composed_common, $pageStatus, $pageText = ''; + protected $noNotifications; protected $mailTargets = array(); /** @@ -489,7 +490,7 @@ * @param $pageStatus (default: 'changed') */ public function notifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit, $oldid = false, $pageStatus = 'changed' ) { - global $wgEnotifUseJobQ, $wgEnotifWatchlist, $wgShowUpdatedMarker, $wgEnotifMinorEdits, + global $wgEnotifUseJobQ, $wgEnotifWatchlist, $wgEnotifDeletionsWatchlist, $wgShowUpdatedMarker, $wgEnotifMinorEdits, $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk; if ( $title->getNamespace() < 0 ) { @@ -498,8 +499,27 @@ // Build a list of users to notify $watchers = array(); + $delWatchers = array(); if ( $wgEnotifWatchlist || $wgShowUpdatedMarker ) { $dbw = wfGetDB( DB_MASTER ); + + if ( $wgEnotifDeletionsWatchlist && $pageStatus == 'deleted' ) { + $res = $dbw->select( array( 'watchlist' ), + array( 'wl_user' ), + array( + 'wl_user != ' . intval( $editor->getID() ), + 'wl_namespace' => $title->getNamespace(), + 'wl_title' => $title->getDBkey(), + 'wl_del_notificationtimestamp IS NULL', + ), __METHOD__ + ); + foreach ( $res as $row ) { + $delUser = User::newFromId ( intval( $row->wl_user ) ); + if ( $delUser->getOption( 'enotifdelwatchlistpages' ) ) { + $delWatchers[] = intval( $row->wl_user ); + } + } + } $res = $dbw->select( array( 'watchlist' ), array( 'wl_user' ), array( @@ -512,24 +532,52 @@ foreach ( $res as $row ) { $watchers[] = intval( $row->wl_user ); } + $watchers = ( array_unique ( array_merge ( $watchers, $delWatchers ) ) ); + if ( $watchers ) { // Update wl_notificationtimestamp for all watching users except the editor + #var_dump ( $watchers ); + #die(); $fname = __METHOD__; - $dbw->onTransactionIdle( - function() use ( $dbw, $timestamp, $watchers, $title, $fname ) { - $dbw->begin( $fname ); - $dbw->update( 'watchlist', - array( /* SET */ - 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp ) - ), array( /* WHERE */ - 'wl_user' => $watchers, - 'wl_namespace' => $title->getNamespace(), - 'wl_title' => $title->getDBkey(), - ), $fname - ); - $dbw->commit( $fname ); - } - ); + if ( $pageStatus == 'deleted' ) { + $dbw->onTransactionIdle( + function() use ( $dbw, $timestamp, $watchers, $title, $fname ) { + $dbw->begin( $fname ); + $dbw->update( 'watchlist', + array( /* SET */ + 'wl_notificationtimestamp' => + $dbw->timestamp( $timestamp ), + 'wl_del_notificationtimestamp' => + $dbw->timestamp( $timestamp ) + ), + array( /* WHERE */ + 'wl_user' => $watchers, + 'wl_namespace' => $title->getNamespace(), + 'wl_title' => $title->getDBkey(), + ), $fname + ); + $dbw->commit( $fname ); + } + ); + } else { + $dbw->onTransactionIdle( + function() use ( $dbw, $timestamp, $watchers, $title, $fname ) { + $dbw->begin( $fname ); + $dbw->update( 'watchlist', + array( /* SET */ + 'wl_notificationtimestamp' => + $dbw->timestamp( $timestamp ) + ), + array( /* WHERE */ + 'wl_user' => $watchers, + 'wl_namespace' => $title->getNamespace(), + 'wl_title' => $title->getDBkey(), + ), $fname + ); + $dbw->commit( $fname ); + } + ); + } } } @@ -588,7 +636,7 @@ public function actuallyNotifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit, $oldid, $watchers, $pageStatus = 'changed' ) { # we use $wgPasswordSender as sender's address - global $wgEnotifWatchlist; + global $wgEnotifWatchlist, $wgEnotifDeletionsWatchlist; global $wgEnotifMinorEdits, $wgEnotifUserTalk; wfProfileIn( __METHOD__ ); @@ -626,15 +674,46 @@ $userTalkId = $targetUser->getId(); } - if ( $wgEnotifWatchlist ) { + if ( $wgEnotifWatchlist || ( $wgEnotifDeletionsWatchlist && $pageStatus == 'deleted' ) ) { // Send updates to watchers other than the current editor + $contentText = null; + if ( $wgEnotifDeletionsWatchlist && $pageStatus == 'deleted' ) { + // Get the text of the most recent revision + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->selectRow ( 'archive', 'ar_text_id', array ( + 'ar_namespace' => $title->getNamespace(), + 'ar_title' => $title->getDBkey() ), __METHOD__, + array ( 'ORDER BY' => 'ar_rev_id DESC' ) ); + if ( $res ) { + $res = $dbr->selectRow ( 'text', 'old_text', array ( + 'old_id' => $res->ar_text_id ) ); + } + if ( $res ) { + $contentText = $res->old_text; + } + } $userArray = UserArray::newFromIDs( $watchers ); foreach ( $userArray as $watchingUser ) { - if ( $watchingUser->getOption( 'enotifwatchlistpages' ) + if ( ( $watchingUser->getOption( 'enotifwatchlistpages' ) + || ( $contentText && $watchingUser->getOption( 'enotifdelwatchlistpages' ) ) ) && ( !$minorEdit || $watchingUser->getOption( 'enotifminoredits' ) ) && $watchingUser->isEmailConfirmed() && $watchingUser->getID() != $userTalkId ) { + $this->pageText = ''; + if ( $contentText ) { + if ( $watchingUser->getOption( 'enotifdelwatchlistpages' ) ) { + $this->pageText = str_replace ( '$CONTENTTEXT', $contentText, + wfMessage( 'enotif_body_deletion_watchlist' ) + ->inContentLanguage()->text() ); + } + } + if ( $wgEnotifDeletionsWatchlist && $pageStatus != 'deleted' + && $watchingUser->getOption( 'enotifdelwatchlistpages' ) ) { + $this->noNotifications = wfMessage( + 'enotif_body_no_notifications_unless_deleted' ) + ->inContentLanguage()->text(); + } $this->compose( $watchingUser ); } } @@ -839,6 +918,10 @@ */ function sendPersonalised( $watchingUser ) { global $wgContLang, $wgEnotifUseRealName; + if ( !isset ( $this->noNotifications ) ) { + $this->noNotifications = wfMessage( 'enotif_body_no_notifications' ) + ->inContentLanguage()->text(); + } // From the PHP manual: // Note: The to parameter cannot be an address in the form of "Something <some...@example.com>". // The mail command will not parse this properly while talking with the MTA. @@ -850,10 +933,14 @@ $body = str_replace( array( '$WATCHINGUSERNAME', '$PAGEEDITDATE', - '$PAGEEDITTIME' ), + '$PAGEEDITTIME', + '$NONOTIFICATIONS', + '$PAGETEXT' ), array( $wgEnotifUseRealName ? $watchingUser->getRealName() : $watchingUser->getName(), $wgContLang->userDate( $this->timestamp, $watchingUser ), - $wgContLang->userTime( $this->timestamp, $watchingUser ) ), + $wgContLang->userTime( $this->timestamp, $watchingUser ), + $this->noNotifications, + $this->pageText ), $this->body ); return UserMailer::send( $to, $this->from, $this->subject, $body, $this->replyto ); @@ -867,7 +954,10 @@ */ function sendImpersonal( $addresses ) { global $wgContLang; - + if ( !isset ( $this->noNotifications ) ) { + $this->noNotifications = wfMessage( 'enotif_body_no_notifications' ) + ->inContentLanguage()->text(); + } if ( empty( $addresses ) ) { return null; } @@ -875,10 +965,14 @@ $body = str_replace( array( '$WATCHINGUSERNAME', '$PAGEEDITDATE', - '$PAGEEDITTIME' ), + '$PAGEEDITTIME', + '$NONOTIFICATIONS', + '$PAGETEXT' ), array( wfMessage( 'enotif_impersonal_salutation' )->inContentLanguage()->text(), $wgContLang->date( $this->timestamp, false, false ), - $wgContLang->time( $this->timestamp, false, false ) ), + $wgContLang->time( $this->timestamp, false, false ), + $this->noNotifications, + $this->pageText ), $this->body ); return UserMailer::send( $addresses, $this->from, $this->subject, $body, $this->replyto ); diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php index d2fb468..3c59028 100644 --- a/includes/WatchedItem.php +++ b/includes/WatchedItem.php @@ -258,7 +258,8 @@ 'wl_user' => $this->getUserId(), 'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ), 'wl_title' => $this->getTitleDBkey(), - 'wl_notificationtimestamp' => null + 'wl_notificationtimestamp' => null, + 'wl_del_notificationtimestamp' => null ), __METHOD__, 'IGNORE' ); // Every single watched page needs now to be listed in watchlist; @@ -268,7 +269,8 @@ 'wl_user' => $this->getUserId(), 'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ), 'wl_title' => $this->getTitleDBkey(), - 'wl_notificationtimestamp' => null + 'wl_notificationtimestamp' => null, + 'wl_del_notificationtimestamp' => null ), __METHOD__, 'IGNORE' ); $this->watched = true; diff --git a/includes/installer/PostgresUpdater.php b/includes/installer/PostgresUpdater.php index 3ecb79b..728461a 100644 --- a/includes/installer/PostgresUpdater.php +++ b/includes/installer/PostgresUpdater.php @@ -169,6 +169,7 @@ "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('archive_ar_id_seq')" ), array( 'addPgField', 'externallinks', 'el_id', "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('externallinks_el_id_seq')" ), + array( 'addPgField', 'watchlist', 'wl_del_notificationtimestamp', "TIMESTAMPTZ" ), # type changes array( 'changeField', 'archive', 'ar_deleted', 'smallint', '' ), diff --git a/includes/installer/SqliteUpdater.php b/includes/installer/SqliteUpdater.php index e0ed1ec..b37f58a 100644 --- a/includes/installer/SqliteUpdater.php +++ b/includes/installer/SqliteUpdater.php @@ -123,6 +123,8 @@ // 1.23 array( 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ), + array( 'addField', 'watchlist', 'wl_del_notificationtimestamp', + 'patch-wl_del_notificationtimestamp.sql' ), ); } diff --git a/includes/specials/SpecialEditWatchlist.php b/includes/specials/SpecialEditWatchlist.php index daa56b3..1898cc4 100644 --- a/includes/specials/SpecialEditWatchlist.php +++ b/includes/specials/SpecialEditWatchlist.php @@ -406,12 +406,14 @@ 'wl_namespace' => MWNamespace::getSubject( $title->getNamespace() ), 'wl_title' => $title->getDBkey(), 'wl_notificationtimestamp' => null, + 'wl_del_notificationtimestamp' => null, ); $rows[] = array( 'wl_user' => $this->getUser()->getId(), 'wl_namespace' => MWNamespace::getTalk( $title->getNamespace() ), 'wl_title' => $title->getDBkey(), 'wl_notificationtimestamp' => null, + 'wl_del_notificationtimestamp' => null, ); } } diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index f3e1fb4..3f89f10 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -677,6 +677,7 @@ 'tog-minordefault' => 'Mark all edits minor by default', 'tog-previewontop' => 'Show preview before edit box', 'tog-previewonfirst' => 'Show preview on first edit', +'tog-enotifdelwatchlistpages' => 'Email me the text of any page on my watchlist that is deleted', 'tog-enotifwatchlistpages' => 'Email me when a page or file on my watchlist is changed', 'tog-enotifusertalkpages' => 'Email me when my user talk page is changed', 'tog-enotifminoredits' => 'Email me also for minor edits of pages and files', @@ -2991,7 +2992,7 @@ mail: $PAGEEDITOR_EMAIL wiki: $PAGEEDITOR_WIKI -There will be no other notifications in case of further activity unless you visit this page while logged in. You could also reset the notification flags for all your watched pages on your watchlist. +$NONOTIFICATIONS Your friendly {{SITENAME}} notification system @@ -3006,7 +3007,15 @@ $UNWATCHURL Feedback and further assistance: -{{canonicalurl:{{MediaWiki:Helppage}}}}', +{{canonicalurl:{{MediaWiki:Helppage}}}}$PAGETEXT', +'enotif_body_no_notifications' => 'There will be no other notifications in case of further activity unless you visit this page while logged in. You could also reset the notification flags for all your watched pages on your watchlist.', +'enotif_body_no_notifications_unless_deleted' => 'There will be no other notifications in case of further activity unless the page is deleted or you visit this page while logged in. You could also reset the notification flags for all your watched pages on your watchlist.', +'enotif_body_deletion_watchlist' => ' + +-- +The text of the most recent revision made to the page before it was deleted is as follows: + +$CONTENTTEXT', 'created' => 'created', # only translate this message to other languages if you have to change it 'changed' => 'changed', # only translate this message to other languages if you have to change it diff --git a/maintenance/archives/patch-wl_del_notificationtimestamp.sql b/maintenance/archives/patch-wl_del_notificationtimestamp.sql new file mode 100644 index 0000000..8e28dda --- /dev/null +++ b/maintenance/archives/patch-wl_del_notificationtimestamp.sql @@ -0,0 +1,11 @@ +-- Patch for email notification on page deletions + +-- A new column 'wl_del_notificationtimestamp' is added to the table 'watchlist'. +-- When a page watched by a user X is deleted by someone else, an email is sent to the watching user X +-- if and only if the field 'wl_del_notificationtimestamp' is '0'. The time/date of sending the mail is then stored in that field. +-- Further pages deletions do not trigger new notification mails as long as user X has not re-visited that page. +-- The field is reset to '0' when user X re-visits the page or when he or she resets all notification timestamps +-- ("notification flags") at once by clicking the new button on his/her watchlist page. +-- Nathan Larson (Leucosticte) 13 December 2013 + +ALTER TABLE /*$wgDBprefix*/watchlist ADD (wl_del_notificationtimestamp varbinary(14)); diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql index d0d1e92..4a7f07e 100644 --- a/maintenance/postgres/tables.sql +++ b/maintenance/postgres/tables.sql @@ -434,7 +434,8 @@ wl_user INTEGER NOT NULL REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, wl_namespace SMALLINT NOT NULL DEFAULT 0, wl_title TEXT NOT NULL, - wl_notificationtimestamp TIMESTAMPTZ + wl_notificationtimestamp TIMESTAMPTZ, + wl_del_notificationtimestamp TIMESTAMPTZ ); CREATE UNIQUE INDEX wl_user_namespace_title ON watchlist (wl_namespace, wl_title, wl_user); CREATE INDEX wl_user ON watchlist (wl_user); diff --git a/maintenance/sqlite/archives/patch-wl_del_notificationtimestamp.sql b/maintenance/sqlite/archives/patch-wl_del_notificationtimestamp.sql new file mode 100644 index 0000000..59590c1 --- /dev/null +++ b/maintenance/sqlite/archives/patch-wl_del_notificationtimestamp.sql @@ -0,0 +1 @@ +ALTER TABLE /*_*/watchlist ADD COLUMN wl_del_notificationtimestamp integer unsigned NOT NULL default 0; diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 18139b2..07a13af 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -1118,7 +1118,9 @@ -- Timestamp used to send notification e-mails and show "updated since last visit" markers on -- history and recent changes / watchlist. Set to NULL when the user visits the latest revision -- of the page, which means that they should be sent an e-mail on the next change. - wl_notificationtimestamp varbinary(14) + wl_notificationtimestamp varbinary(14), + -- Timestamp used to send revision text in page deletion notification e-mails. + wl_del_notificationtimestamp varbinary(14) ) /*$wgDBTableOptions*/; -- To view, visit https://gerrit.wikimedia.org/r/101443 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie49440ad940a7488ea2e855ab322ade7e33f1fe4 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: leucosticte <nathanlarson3...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits