r84383 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r84382‎ | r84383 | r84384 >
Date:14:42, 20 March 2011
Author:aaron
Status:resolved
Tags:
Comment:
* Moved "users watching"/"user currently reviewing" functions to FRUserActivity and rewrote it
* (bug 25295) Track *who* is reviewing pages and when they started; warn users of this on review forms
* Got rid of revreview-text msg
* Fixed fr-under-review css use at unreviewedpages
Modified paths:
  • /trunk/extensions/FlaggedRevs/FRUserActivity.php (added) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedArticleView.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/FlaggedRevs.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/forms/RevisionReviewForm.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/language/FlaggedRevs.i18n.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/specialpages/PendingChanges_body.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/specialpages/ProblemChanges_body.php (modified) (history)
  • /trunk/extensions/FlaggedRevs/specialpages/UnreviewedPages_body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php
@@ -66,6 +66,7 @@
6767 # Can users make comments that will show up below flagged revisions?
6868 # NOTE: this is NOT the same as the simple log comment
6969 $wgFlaggedRevsComments = false; // @TODO: remove when ready?
 70+
7071 # Auto-review settings for edits/new pages:
7172 # FR_AUTOREVIEW_NONE
7273 # Don't auto-review any edits or new pages
@@ -242,6 +243,7 @@
243244 $wgAutoloadClasses['FlaggedRevs'] = $dir . 'FlaggedRevs.class.php';
244245 $wgAutoloadClasses['FRUserCounters'] = $dir . 'FRUserCounters.php';
245246 $wgAutoloadClasses['FRInclusionManager'] = $dir . 'FRInclusionManager.php';
 247+$wgAutoloadClasses['FRUserActivity'] = $dir . 'FRUserActivity.php';
246248 $wgAutoloadClasses['FlaggedRevsHooks'] = $dir . 'FlaggedRevs.hooks.php';
247249 $wgAutoloadClasses['FlaggedRevsLogs'] = $dir . 'FlaggedRevsLogs.php';
248250 $wgAutoloadClasses['FRExtraCacheUpdate'] = $dir . 'FRExtraCacheUpdate.php';
Index: trunk/extensions/FlaggedRevs/language/FlaggedRevs.i18n.php
@@ -192,7 +192,8 @@
193193 'revreview-submit-unreviewed' => 'Done. Unaccepted!',
194194 'revreview-successful' => '\'\'\'Revision of [[:$1|$1]] successfully flagged. ([{{fullurl:{{#Special:ReviewedVersions}}|page=$2}} view reviewed versions])\'\'\'',
195195 'revreview-successful2' => '\'\'\'Revision of [[:$1|$1]] successfully unflagged.\'\'\'',
196 - 'revreview-text' => '\'\'[[{{MediaWiki:Validationpage}}|Reviewed versions]] are checked versions of pages used to determine the stable version.\'\'',
 196+ 'revreview-poss-conflict-p' => '\'\'\'WARNING: Another user, [[User:$1|$1]], just started reviewing this page at $2.\'\'\'',
 197+ 'revreview-poss-conflict-c' => '\'\'\'WARNING: Another user, [[User:$1|$1]], just started reviewing these changes at $2.\'\'\'',
197198 'revreview-toggle-show' => '(+)',
198199 'revreview-toggle-hide' => '(-)',
199200 'revreview-toggle-title' => 'show/hide details',
Index: trunk/extensions/FlaggedRevs/forms/RevisionReviewForm.php
@@ -644,7 +644,7 @@
645645 User $user, FlaggedArticle $article, Revision $rev,
646646 $refId = 0, $topNotice = '', $templateIDs, $imageSHA1Keys
647647 ) {
648 - global $wgOut, $wgParser, $wgEnableParserCache;
 648+ global $wgOut, $wgLang, $wgParser, $wgEnableParserCache;
649649 $id = $rev->getId();
650650 if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
651651 return false; # The revision must be valid and public
@@ -705,9 +705,18 @@
706706 $form .= Xml::closeElement( 'legend' ) . "\n";
707707 # Show explanatory text
708708 $form .= $topNotice;
709 - if ( !FlaggedRevs::lowProfileUI() ) {
710 - $form .= wfMsgExt( 'revreview-text', array( 'parse' ) );
 709+ # Show possible conflict warning msg
 710+ if ( $refId ) {
 711+ list( $u, $ts ) = FRUserActivity::getUserReviewingDiff( $refId, $rev->getId() );
 712+ } else {
 713+ list( $u, $ts ) = FRUserActivity::getUserReviewingPage( $rev->getPage() );
711714 }
 715+ if ( $u !== null && $u != $user->getName() ) {
 716+ $msg = $refId ? 'revreview-poss-conflict-c' : 'revreview-poss-conflict-p';
 717+ $form .= '<p><span class="fr-under-review">' .
 718+ wfMsgExt( $msg, 'parseinline', $u, $wgLang->timeanddate( $ts, true ) ) .
 719+ '</span></p>';
 720+ }
712721
713722 if ( $disabled ) {
714723 $form .= Xml::openElement( 'div', array( 'class' => 'fr-rating-controls-disabled',
Index: trunk/extensions/FlaggedRevs/specialpages/PendingChanges_body.php
@@ -209,7 +209,7 @@
210210 }
211211
212212 public function formatRow( $row ) {
213 - global $wgLang, $wgUser, $wgMemc;
 213+ global $wgLang, $wgUser;
214214 $css = $quality = $underReview = '';
215215
216216 $title = Title::newFromRow( $row );
@@ -229,7 +229,7 @@
230230 }
231231 # Is anybody watching?
232232 if ( !$this->including() && $wgUser->isAllowed( 'unreviewedpages' ) ) {
233 - $uw = UnreviewedPages::usersWatching( $title );
 233+ $uw = FRUserActivity::numUsersWatchingPage( $title );
234234 $watching = $uw
235235 ? wfMsgExt( 'pendingchanges-watched', 'parsemag', $wgLang->formatNum( $uw ) )
236236 : wfMsgHtml( 'pendingchanges-unwatched' );
@@ -259,9 +259,9 @@
260260 } else {
261261 $age = ""; // wtf?
262262 }
263 - $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
264263 # Show if a user is looking at this page
265 - if ( $wgMemc->get( $key ) ) {
 264+ list( $u, $ts ) = FRUserActivity::getUserReviewingDiff( $row->stable, $row->page_latest );
 265+ if ( $u !== null ) {
266266 $underReview = ' <span class="fr-under-review">' .
267267 wfMsgHtml( 'pendingchanges-viewing' ) . '</span>';
268268 }
Index: trunk/extensions/FlaggedRevs/specialpages/UnreviewedPages_body.php
@@ -92,7 +92,7 @@
9393 }
9494
9595 public function formatRow( $row ) {
96 - global $wgLang, $wgUser, $wgMemc;
 96+ global $wgLang, $wgUser;
9797
9898 $stxt = $underReview = $watching = '';
9999 $title = Title::newFromRow( $row );
@@ -122,7 +122,7 @@
123123 $age = ' ' . wfMsg( 'unreviewedpages-recent' ); // hot off the press :)
124124 }
125125 if ( $wgUser->isAllowed( 'unwatchedpages' ) ) {
126 - $uw = self::usersWatching( $title );
 126+ $uw = FRUserActivity::numUsersWatchingPage( $title );
127127 $watching = $uw
128128 ? wfMsgExt( 'unreviewedpages-watched', 'parsemag', $wgLang->formatNum( $uw ) )
129129 : wfMsgHtml( 'unreviewedpages-unwatched' );
@@ -132,53 +132,18 @@
133133 }
134134 $css = self::getLineClass( $hours, $uw );
135135 $css = $css ? " class='$css'" : "";
136 - $pageId = isset( $row->page_id ) ? $row->page_id : $row->qc_value;
137 - $key = wfMemcKey( 'unreviewedPages', 'underReview', $pageId );
138 - $val = $wgMemc->get( $key );
 136+
139137 # Show if a user is looking at this page
140 - if ( $val ) {
141 - $underReview = " <b class='fr-under-review'>" .
142 - wfMsgHtml( 'unreviewedpages-viewing' ) . '</b>';
 138+ list( $u, $ts ) = FRUserActivity::getUserReviewingPage( $row->page_id );
 139+ if ( $u !== null ) {
 140+ $underReview = " <span class='fr-under-review'>" .
 141+ wfMsgHtml( 'unreviewedpages-viewing' ) . '</span>';
143142 }
144143
145144 return( "<li{$css}>{$link} {$stxt} ({$hist})" .
146145 "{$age}{$watching}{$underReview}</li>" );
147146 }
148 -
149 - /**
150 - * Get number of users watching a page.
151 - * @param Title $title
152 - * @return int
153 - */
154 - public static function usersWatching( Title $title ) {
155 - global $wgMiserMode, $wgCookieExpiration;
156 - $dbr = wfGetDB( DB_SLAVE );
157 - $count = - 1;
158 - if ( $wgMiserMode ) {
159 - # Get a rough idea of size
160 - $count = $dbr->estimateRowCount( 'watchlist', '*',
161 - array( 'wl_namespace' => $title->getNamespace(),
162 - 'wl_title' => $title->getDBkey() ),
163 - __METHOD__ );
164 - }
165 - # If it is small, just COUNT() it, otherwise, stick with estimate...
166 - if ( $count == - 1 || $count <= 100 ) {
167 - # Get number of active editors watchling this
168 - $cutoff = $dbr->timestamp( wfTimestamp( TS_UNIX ) - 2 * $wgCookieExpiration );
169 - $res = $dbr->select( array( 'watchlist', 'user' ), '1',
170 - array( 'wl_namespace' => $title->getNamespace(),
171 - 'wl_title' => $title->getDBkey(),
172 - 'wl_user = user_id',
173 - // logged in or out
174 - 'user_touched > ' . $dbr->addQuotes( $cutoff ) ),
175 - __METHOD__,
176 - array( 'USE INDEX' => array( 'watchlist' => 'namespace_title' ) )
177 - );
178 - $count = $dbr->numRows( $res );
179 - }
180 - return (int)$count;
181 - }
182 -
 147+
183148 protected static function getLineClass( $hours, $uw ) {
184149 if ( $uw == 0 )
185150 return 'fr-unreviewed-unwatched';
@@ -189,7 +154,7 @@
190155 else
191156 return "";
192157 }
193 -
 158+
194159 /**
195160 * There may be many pages, most of which are reviewed
196161 */
@@ -303,8 +268,8 @@
304269
305270 function getQueryCacheInfo() {
306271 $conds = $this->mConds;
307 - $fields = array( 'page_namespace', 'page_title', 'page_len', 'qc_value',
308 - 'MIN(rev_timestamp) AS creation' );
 272+ $fields = array( 'page_namespace', 'page_title', 'page_len', 'page_id',
 273+ 'qc_value', 'MIN(rev_timestamp) AS creation' );
309274 # Re-join on flaggedpages to double-check since things
310275 # could have changed since the cache date. Also, use
311276 # the proper cache for this level.
Index: trunk/extensions/FlaggedRevs/specialpages/ProblemChanges_body.php
@@ -173,7 +173,7 @@
174174 }
175175
176176 public function formatRow( $row ) {
177 - global $wgLang, $wgUser, $wgMemc;
 177+ global $wgLang, $wgUser;
178178 $css = $quality = $tags = $underReview = '';
179179
180180 $title = Title::newFromRow( $row );
@@ -196,7 +196,7 @@
197197 }
198198 # Is anybody watching?
199199 if ( !$this->including() && $wgUser->isAllowed( 'unreviewedpages' ) ) {
200 - $uw = UnreviewedPages::usersWatching( $title );
 200+ $uw = FRUserActivity::numUsersWatchingPage( $title );
201201 $watching = $uw
202202 ? wfMsgExt( 'pendingchanges-watched', 'parsemag', $wgLang->formatNum( $uw ) )
203203 : wfMsgHtml( 'pendingchanges-unwatched' );
@@ -228,9 +228,9 @@
229229 } else {
230230 $age = ""; // wtf?
231231 }
232 - $key = wfMemcKey( 'stableDiffs', 'underReview', $row->stable, $row->page_latest );
233232 # Show if a user is looking at this page
234 - if ( $wgMemc->get( $key ) ) {
 233+ list( $u, $ts ) = FRUserActivity::getUserReviewingDiff( $row->stable, $row->page_latest );
 234+ if ( $u !== null ) {
235235 $underReview = ' <span class="fr-under-review">' .
236236 wfMsgHtml( 'pendingchanges-viewing' ) . '</span>';
237237 }
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php
@@ -133,14 +133,16 @@
134134
135135 // Mark when an unreviewed page is being reviewed
136136 protected static function maybeMarkUnderReview( FlaggedArticle $fa, WebRequest $request ) {
137 - global $wgMemc;
 137+ global $wgUser;
 138+ if ( !$request->getInt( 'reviewing' ) && !$request->getInt( 'rcid' ) ) {
 139+ return true; // not implied by URL
 140+ }
138141 # Set a key to note when someone is reviewing this.
139142 # NOTE: diff-to-stable views already handled elsewhere.
140 - if ( $request->getInt( 'reviewing' ) || $request->getInt( 'rcid' ) ) {
141 - if ( $fa->isReviewable() && $fa->getTitle()->userCan( 'review' ) ) {
142 - $key = wfMemcKey( 'unreviewedPages', 'underReview', $fa->getId() );
143 - $wgMemc->set( $key, '1', 20 * 60 );
144 - }
 143+ if ( $fa->isReviewable() && !$fa->getStable() // not reviewed yet
 144+ && $fa->getTitle()->userCan( 'review' ) )
 145+ {
 146+ FRUserActivity::setUserReviewingPage( $wgUser, $fa->getID() );
145147 }
146148 return true;
147149 }
@@ -2027,4 +2029,4 @@
20282030 }
20292031 return true;
20302032 }
2031 -}
 2033+}
\ No newline at end of file
Index: trunk/extensions/FlaggedRevs/FRUserActivity.php
@@ -0,0 +1,132 @@
 2+<?php
 3+/*
 4+* Class of utility functions for getting/tracking user activity
 5+*/
 6+class FRUserActivity {
 7+ /**
 8+ * Get number of active users watching a page
 9+ * @param Title $title
 10+ * @return int
 11+ */
 12+ public static function numUsersWatchingPage( Title $title ) {
 13+ global $wgMemc, $wgCookieExpiration;
 14+ # Check the cache...
 15+ $key = wfMemcKey( 'flaggedrevs', 'usersWatching', $title->getArticleID() );
 16+ $val = $wgMemc->get( $key );
 17+ if ( is_int( $val ) ) {
 18+ return $val; // cache hit
 19+ }
 20+ # Get number of active editors watching this page...
 21+ $dbr = wfGetDB( DB_SLAVE );
 22+ $cutoff = $dbr->timestamp( wfTimestamp( TS_UNIX ) - 2 * $wgCookieExpiration );
 23+ $count = (int)$dbr->selectField(
 24+ array( 'watchlist', 'user' ),
 25+ 'COUNT(*)',
 26+ array(
 27+ 'wl_namespace' => $title->getNamespace(),
 28+ 'wl_title' => $title->getDBkey(),
 29+ 'wl_user = user_id',
 30+ 'user_touched > ' . $dbr->addQuotes( $cutoff ) // logged in or out
 31+ ),
 32+ __METHOD__,
 33+ array( 'USE INDEX' => array( 'watchlist' => 'namespace_title' ) )
 34+ );
 35+ if ( $count > 10 ) {
 36+ # Save new value to cache (more aggresive for larger counts)
 37+ $wgMemc->set( $key, $count, ( $count > 200 ) ? 30*60 : 5*60 );
 38+ }
 39+
 40+ return $count;
 41+ }
 42+
 43+ /*
 44+ * Get who is currently reviewing a page
 45+ * @param int $pageId
 46+ * @return array (username or null, MW timestamp or null)
 47+ */
 48+ public static function getUserReviewingPage( $pageId ) {
 49+ global $wgMemc;
 50+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingPage', $pageId );
 51+ $val = $wgMemc->get( $key );
 52+ if ( is_array( $val ) && count( $val ) == 2 ) {
 53+ return $val;
 54+ }
 55+ return array( null, null );
 56+ }
 57+
 58+ /*
 59+ * Set the flag for who is reviewing a page if not already set by someone
 60+ * @param User $user
 61+ * @param int $pageId
 62+ * @return bool flag set
 63+ */
 64+ public static function setUserReviewingPage( $user, $pageId ) {
 65+ global $wgMemc;
 66+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingPage', $pageId );
 67+ $val = array( $user->getName(), wfTimestampNow() );
 68+ if ( !$wgMemc->get( $key ) ) { // no flag set
 69+ # Set the flag (use locks if available)
 70+ $wgMemc->lock( $key, 4000 ); // 4 sec timeout
 71+ $wgMemc->set( $key, $val, 20*60 ); // 20 min
 72+ $wgMemc->unlock( $key );
 73+ return true;
 74+ }
 75+ return false;
 76+ }
 77+
 78+ /*
 79+ * Clear the flag for who is reviewing a page
 80+ * @param int $pageId
 81+ */
 82+ public static function clearUserReviewingPage( $pageId ) {
 83+ global $wgMemc;
 84+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingPage', $pageId );
 85+ $wgMemc->delete( $key );
 86+ }
 87+
 88+ /*
 89+ * Get who is currently reviewing a diff
 90+ * @param int $oldId
 91+ * @param int $newId
 92+ * @return array (username or null, MW timestamp or null)
 93+ */
 94+ public static function getUserReviewingDiff( $oldId, $newId ) {
 95+ global $wgMemc;
 96+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingDiff', $oldId, $newId );
 97+ $val = $wgMemc->get( $key );
 98+ if ( is_array( $val ) && count( $val ) == 2 ) {
 99+ return $val;
 100+ }
 101+ return array( null, null );
 102+ }
 103+
 104+ /*
 105+ * Set the flag for who is reviewing a diff if not already set by someone
 106+ * @param User $user
 107+ * @param int $pageId
 108+ * @return bool flag set
 109+ */
 110+ public static function setUserReviewingDiff( $user, $oldId, $newId ) {
 111+ global $wgMemc;
 112+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingDiff', $oldId, $newId );
 113+ $val = array( $user->getName(), wfTimestampNow() );
 114+ if ( !$wgMemc->get( $key ) ) { // no flag set
 115+ # Set the flag (use locks if available)
 116+ $wgMemc->lock( $key, 4000 ); // 4 sec timeout
 117+ $wgMemc->set( $key, $val, 6*20 ); // 6 min
 118+ $wgMemc->unlock( $key );
 119+ return true;
 120+ }
 121+ return false;
 122+ }
 123+
 124+ /*
 125+ * Clear the flag for who is reviewing a diff
 126+ * @param int $pageId
 127+ */
 128+ public static function clearUserReviewingDiff( $oldId, $newId ) {
 129+ global $wgMemc;
 130+ $key = wfMemcKey( 'flaggedrevs', 'userReviewingDiff', $oldId, $newId );
 131+ $wgMemc->delete( $key );
 132+ }
 133+}
Property changes on: trunk/extensions/FlaggedRevs/FRUserActivity.php
___________________________________________________________________
Added: svn:eol-style
1134 + native
Index: trunk/extensions/FlaggedRevs/FlaggedArticleView.php
@@ -1387,7 +1387,8 @@
13881388 # If the user can review then prompt them to review them...
13891389 if ( $wgUser->isAllowed( 'review' ) ) {
13901390 # Set a key to note that someone is viewing this
1391 - $this->markDiffUnderReview( $oldRev, $newRev );
 1391+ FRUserActivity::setUserReviewingDiff(
 1392+ $wgUser, $oldRev->getId(), $newRev->getId() );
13921393 // Reviewer just edited...
13931394 if ( $wgRequest->getInt( 'shownotice' )
13941395 && $newRev->isCurrent()
@@ -1580,13 +1581,6 @@
15811582 return $diffLinks;
15821583 }
15831584
1584 - // Mark that someone is viewing a portion or all of the diff-to-stable
1585 - protected function markDiffUnderReview( Revision $oldRev, Revision $newRev ) {
1586 - global $wgMemc;
1587 - $key = wfMemcKey( 'stableDiffs', 'underReview', $oldRev->getID(), $newRev->getID() );
1588 - $wgMemc->set( $key, '1', 6 * 60 );
1589 - }
1590 -
15911585 /**
15921586 * Set $this->isDiffFromStable and $this->isMultiPageDiff fields
15931587 * Note: $oldRev could be false

Follow-up revisions

RevisionCommit summaryAuthorDate
r84435Timeout/locking fixes for r84383 (these don't do anything yet though anyway)aaron00:10, 21 March 2011
r90033*Added API to set "currently reviewing" flag for pages and diffs...aaron03:41, 14 June 2011

Status & tagging log