From bc34b5867a333d3c6f8ac1b68dcd39da77d3e2c2 Mon Sep 17 00:00:00 2001 From: kaldari Date: Sat, 4 May 2013 18:08:58 -0700 Subject: [PATCH] Adding GetNewMessagesAlert hook and wgUserNewMsgRevisionId JS global This hook allows extensions to disable or modify the new messages alert ('orange bar of doom') while still allowing the user_newtalk table to be updated. The wgUserNewMsgRevisionId JS global allows gadgets and extensions to create their own new message alerts on the client side. I also threw in a few comment updates for good measure! See also Echo change I3f35a56b which utilizes this. Bug: 47962 Change-Id: I2105bdd2bcd5b27f6f36ec8d8fa7fa99d60a2d82 --- RELEASE-NOTES-1.22 | 6 ++++++ docs/hooks.txt | 8 ++++++++ includes/OutputPage.php | 4 ++++ includes/Skin.php | 33 +++++++++++++++++++++------------ includes/User.php | 28 ++++++++++++++++++++++++++-- includes/WikiPage.php | 3 ++- 6 files changed, 67 insertions(+), 15 deletions(-) diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22 index ff9622a376..c378270d6a 100644 --- a/RELEASE-NOTES-1.22 +++ b/RELEASE-NOTES-1.22 @@ -58,6 +58,12 @@ production. * HTMLForm will turn multiselect checkboxes into a Chosen interface when setting cssclass 'mw-chosen' * rebuildLocalisationCache learned --lang option. Let you rebuild l10n caches of the specified languages instead of all of them. +* New GetNewMessagesAlert hook allowing extensions to disable or modify the new + messages alert +* New wgUserNewMsgRevisionId JS global for logged in users. This will be null + if the user has no new talk page messages. Otherwise it will be set to the + revision ID of the oldest new talk page message. This will allow gadgets and + extensions to create their own new message alerts on the client side. * mediawiki.log: Added log.warn wrapper (uses console.warn and console.trace). * mediawiki.log: Implemented log.deprecate. This method defines a property and uses ES5 getter/setter to emit a warning when they are used. diff --git a/docs/hooks.txt b/docs/hooks.txt index 0b835c2696..a292997469 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -1193,6 +1193,14 @@ to do this unless they broke backwards compatibility with a previous version of the media handler metadata output. &$version: Array of version strings +'GetNewMessagesAlert': Disable or modify the new messages alert +&$newMessagesAlert: An empty string by default. If the user has new talk page +messages, this should be populated with an alert message to that effect +$newtalks: An empty array if the user has no new messages or an array containing +links and revisions if there are new messages (See User::getNewMessageLinks) +$user: The user object of the user who is loading the page +$out: OutputPage object (to check what type of page the user is on) + 'GetPreferences': Modify user preferences. $user: User whose preferences are being modified. &$preferences: Preferences description array, to be fed to an HTMLForm object diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 3abfff0637..0609e377c4 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -3074,6 +3074,10 @@ $templates $vars['wgUserEditCount'] = $user->getEditCount(); $userReg = wfTimestampOrNull( TS_UNIX, $user->getRegistration() ); $vars['wgUserRegistration'] = $userReg !== null ? ( $userReg * 1000 ) : null; + // Get the revision ID of the oldest new message on the user's talk + // page. This can be used for constructing new message alerts on + // the client side. + $vars['wgUserNewMsgRevisionId'] = $user->getNewMessageRevisionId(); } if ( $wgContLang->hasVariants() ) { $vars['wgUserVariant'] = $wgContLang->getPreferredVariant(); diff --git a/includes/Skin.php b/includes/Skin.php index cc957c47d4..1aa1f05c08 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -1294,17 +1294,27 @@ abstract class Skin extends ContextSource { } /** - * Gets new talk page messages for the current user. - * @return MediaWiki message or if no new talk page messages, nothing + * Gets new talk page messages for the current user and returns an + * appropriate alert message (or an empty string if there are no messages) + * @return String */ function getNewtalks() { + + $newMessagesAlert = ''; + $user = $this->getUser(); + $newtalks = $user->getNewMessageLinks(); $out = $this->getOutput(); - $newtalks = $this->getUser()->getNewMessageLinks(); - $ntl = ''; + // Allow extensions to disable or modify the new messages alert + if ( !wfRunHooks( 'GetNewMessagesAlert', array( &$newMessagesAlert, $newtalks, $user, $out ) ) ) { + return ''; + } + if ( $newMessagesAlert ) { + return $newMessagesAlert; + } if ( count( $newtalks ) == 1 && $newtalks[0]['wiki'] === wfWikiID() ) { - $uTalkTitle = $this->getUser()->getTalkPage(); + $uTalkTitle = $user->getTalkPage(); if ( !$uTalkTitle->equals( $out->getTitle() ) ) { $lastSeenRev = isset( $newtalks[0]['rev'] ) ? $newtalks[0]['rev'] : null; @@ -1343,26 +1353,25 @@ abstract class Skin extends ContextSource { ); if ( $nofAuthors >= 1 && $nofAuthors <= 10 ) { - $ntl = $this->msg( + $newMessagesAlert = $this->msg( 'youhavenewmessagesfromusers', $newMessagesLink, $newMessagesDiffLink )->numParams( $nofAuthors ); } else { // $nofAuthors === 11 signifies "11 or more" ("more than 10") - $ntl = $this->msg( + $newMessagesAlert = $this->msg( $nofAuthors > 10 ? 'youhavenewmessagesmanyusers' : 'youhavenewmessages', $newMessagesLink, $newMessagesDiffLink ); } - $ntl = $ntl->text(); + $newMessagesAlert = $newMessagesAlert->text(); # Disable Squid cache $out->setSquidMaxage( 0 ); } } elseif ( count( $newtalks ) ) { - // _>" " for BC <= 1.16 - $sep = str_replace( '_', ' ', $this->msg( 'newtalkseparator' )->escaped() ); + $sep = $this->msg( 'newtalkseparator' )->escaped(); $msgs = array(); foreach ( $newtalks as $newtalk ) { @@ -1372,11 +1381,11 @@ abstract class Skin extends ContextSource { ); } $parts = implode( $sep, $msgs ); - $ntl = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped(); + $newMessagesAlert = $this->msg( 'youhavenewmessagesmulti' )->rawParams( $parts )->escaped(); $out->setSquidMaxage( 0 ); } - return $ntl; + return $newMessagesAlert; } /** diff --git a/includes/User.php b/includes/User.php index 5a525bf46f..e8990d3dcf 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1807,8 +1807,11 @@ class User { } /** - * Return the talk page(s) this user has new messages on. - * @return Array of String page URLs + * Return the revision and link for the oldest new talk page message for + * this user. + * Note: This function was designed to accomodate multiple talk pages, but + * currently only returns a single link and revision. + * @return Array */ public function getNewMessageLinks() { $talks = array(); @@ -1828,6 +1831,27 @@ class User { return array( array( 'wiki' => wfWikiID(), 'link' => $utp->getLocalURL(), 'rev' => $rev ) ); } + /** + * Get the revision ID for the oldest new talk page message for this user + * @return Integer or null if there are no new messages + */ + public function getNewMessageRevisionId() { + $newMessageRevisionId = null; + $newMessageLinks = $this->getNewMessageLinks(); + if ( $newMessageLinks ) { + // Note: getNewMessageLinks() never returns more than a single link + // and it is always for the same wiki, but we double-check here in + // case that changes some time in the future. + if ( count( $newMessageLinks ) === 1 && $newMessageLinks[0]['wiki'] === wfWikiID() ) { + $newMessageRevision = $newMessageLinks[0]['rev']; + $newMessageRevisionId = $newMessageRevision->getId(); + } else { + throw new MWException( "Unexpected values from User::getNewMessageLinks()" ); + } + } + return $newMessageRevisionId; + } + /** * Internal uncached check for new messages * diff --git a/includes/WikiPage.php b/includes/WikiPage.php index 8c00e1b526..f2c9c298d3 100644 --- a/includes/WikiPage.php +++ b/includes/WikiPage.php @@ -2053,7 +2053,8 @@ class WikiPage implements Page, IDBAccessObject { $content = $revision->getContent(); // Parse the text - // Be careful not to double-PST: $text is usually already PST-ed once + // Be careful not to do pre-save transform twice: $text is usually + // already pre-save transformed once. if ( !$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) { wfDebug( __METHOD__ . ": No prepared edit or vary-revision is set...\n" ); $editInfo = $this->prepareContentForEdit( $content, $revision->getId(), $user ); -- 2.20.1