Index: trunk/extensions/FlaggedRevs/language/UnreviewedPages.i18n.php |
— | — | @@ -18,6 +18,9 @@ |
19 | 19 | 'unreviewed-list' => 'This page lists content pages that have not been reviewed.', |
20 | 20 | 'unreviewed-none' => 'There are currently no pages meeting these criteria', |
21 | 21 | 'unreviewed-viewing' => '(under review)', |
| 22 | + 'unreviewed-hours' => '($1 {{PLURAL:$1|hour|hours}})', |
| 23 | + 'unreviewed-days' => '($1 {{PLURAL:$1|day|days}})', |
| 24 | + 'unreviewed-recent' => '(less than 1 hour)', |
22 | 25 | ); |
23 | 26 | |
24 | 27 | /** Message documentation (Message documentation) |
Index: trunk/extensions/FlaggedRevs/specialpages/UnreviewedPages_body.php |
— | — | @@ -87,7 +87,7 @@ |
88 | 88 | public function formatRow( $row ) { |
89 | 89 | global $wgLang, $wgUser, $wgMemc; |
90 | 90 | |
91 | | - $title = Title::makeTitle( $row->page_namespace, $row->page_title ); |
| 91 | + $title = Title::newFromRow( $row ); |
92 | 92 | $link = $this->skin->makeKnownLinkObj( $title, null, 'redirect=no&reviewform=1' ); |
93 | 93 | $hist = $this->skin->makeKnownLinkObj( $title, wfMsgHtml('hist'), 'action=history' ); |
94 | 94 | $css = $stxt = $review = $underReview = ''; |
— | — | @@ -97,6 +97,22 @@ |
98 | 98 | : wfMsgExt('historysize', array('parsemag'), $wgLang->formatNum( $size ) ); |
99 | 99 | $stxt = " <small>$stxt</small>"; |
100 | 100 | } |
| 101 | + # Get how long the first unreviewed edit has been waiting... |
| 102 | + static $currentTime; |
| 103 | + $currentTime = wfTimestamp( TS_UNIX ); // now |
| 104 | + $firstPendingTime = wfTimestamp( TS_UNIX, $row->creation ); |
| 105 | + $hours = ($currentTime - $firstPendingTime)/3600; |
| 106 | + // After three days, just use days |
| 107 | + if( $hours > (3*24) ) { |
| 108 | + $days = round($hours/24,0); |
| 109 | + $age = wfMsgExt('unreviewed-days',array('parsemag'),$days); |
| 110 | + // If one or more hours, use hours |
| 111 | + } elseif( $hours >= 1 ) { |
| 112 | + $hours = round($hours,0); |
| 113 | + $age = wfMsgExt('unreviewed-hours',array('parsemag'),$hours); |
| 114 | + } else { |
| 115 | + $age = wfMsg('unreviewed-recent'); // hot off the press :) |
| 116 | + } |
101 | 117 | if( $wgUser->isAllowed('unwatchedpages') ) { |
102 | 118 | $uw = self::usersWatching( $title ); |
103 | 119 | $watching = $uw ? |
— | — | @@ -115,7 +131,7 @@ |
116 | 132 | $underReview = " <b class='fr-under-review'>".wfMsgHtml('unreviewed-viewing').'</b>'; |
117 | 133 | } |
118 | 134 | |
119 | | - return( "<li{$css}>{$link} {$stxt} ({$hist}) {$review}{$watching}{$underReview}</li>" ); |
| 135 | + return( "<li{$css}>{$link} {$stxt} ({$hist}) {$review}{$age}{$watching}{$underReview}</li>" ); |
120 | 136 | } |
121 | 137 | |
122 | 138 | /** |
— | — | @@ -208,7 +224,8 @@ |
209 | 225 | return $this->getQueryCacheInfo(); |
210 | 226 | } |
211 | 227 | $conds = $this->mConds; |
212 | | - $fields = array('page_namespace','page_title','page_len','page_id'); |
| 228 | + $fields = array('page_namespace','page_title','page_len','page_id', |
| 229 | + 'MIN(rev_timestamp) AS creation'); |
213 | 230 | # Filter by level |
214 | 231 | if( $this->level == 1 ) { |
215 | 232 | $conds[] = "fp_page_id IS NULL OR fp_quality = 0"; |
— | — | @@ -223,29 +240,36 @@ |
224 | 241 | } |
225 | 242 | # Filter by category |
226 | 243 | if( $this->category ) { |
227 | | - $tables = array( 'categorylinks', 'page', 'flaggedpages' ); |
| 244 | + $tables = array( 'categorylinks', 'page', 'flaggedpages', 'revision' ); |
228 | 245 | $fields[] = 'cl_sortkey'; |
229 | 246 | $conds['cl_to'] = $this->category; |
230 | 247 | $conds[] = 'cl_from = page_id'; |
231 | 248 | $this->mIndexField = 'cl_sortkey'; |
232 | 249 | $useIndex = array( 'categorylinks' => 'cl_sortkey' ); |
| 250 | + $groupBy = 'cl_sortkey,cl_from'; |
233 | 251 | } else { |
234 | | - $tables = array( 'page', 'flaggedpages' ); |
| 252 | + $tables = array( 'page', 'flaggedpages', 'revision' ); |
235 | 253 | $this->mIndexField = 'page_title'; |
236 | 254 | $useIndex = array( 'page' => 'name_title' ); |
| 255 | + $groupBy = 'page_title'; |
237 | 256 | } |
| 257 | + $useIndex['revision'] = 'page_timestamp'; // sigh... |
238 | 258 | return array( |
239 | 259 | 'tables' => $tables, |
240 | 260 | 'fields' => $fields, |
241 | 261 | 'conds' => $conds, |
242 | | - 'options' => array( 'USE INDEX' => $useIndex ), |
243 | | - 'join_conds' => array( 'flaggedpages' => array('LEFT JOIN','fp_page_id=page_id') ) |
| 262 | + 'options' => array( 'USE INDEX' => $useIndex, 'GROUP BY' => $groupBy ), |
| 263 | + 'join_conds' => array( |
| 264 | + 'revision' => array('LEFT JOIN','rev_page=page_id'), // Get creation date |
| 265 | + 'flaggedpages' => array('LEFT JOIN','fp_page_id=page_id') |
| 266 | + ) |
244 | 267 | ); |
245 | 268 | } |
246 | 269 | |
247 | 270 | function getQueryCacheInfo() { |
248 | 271 | $conds = $this->mConds; |
249 | | - $fields = array('page_namespace','page_title','page_len','qc_value'); |
| 272 | + $fields = array('page_namespace','page_title','page_len','qc_value', |
| 273 | + 'MIN(rev_timestamp) AS creation'); |
250 | 274 | # Re-join on flaggedpages to double-check since things |
251 | 275 | # could have changed since the cache date. Also, use |
252 | 276 | # the proper cache for this level. |
— | — | @@ -256,7 +280,6 @@ |
257 | 281 | $conds['qc_type'] = 'fr_unreviewedpages'; |
258 | 282 | $conds[] = 'fp_page_id IS NULL'; |
259 | 283 | } |
260 | | - $conds[] = 'qc_value = page_id'; |
261 | 284 | # Reviewable pages only |
262 | 285 | $conds['qc_namespace'] = $this->namespace; |
263 | 286 | # No redirects |
— | — | @@ -266,18 +289,26 @@ |
267 | 290 | $this->mIndexField = 'qc_value'; // page_id |
268 | 291 | # Filter by category |
269 | 292 | if( $this->category ) { |
270 | | - $tables = array( 'page', 'categorylinks', 'querycache', 'flaggedpages' ); |
| 293 | + $tables = array( 'page', 'categorylinks', 'querycache', 'flaggedpages', 'revision' ); |
271 | 294 | $conds['cl_to'] = $this->category; |
272 | 295 | $conds[] = 'cl_from = qc_value'; // page_id |
273 | 296 | } else { |
274 | | - $tables = array( 'page', 'querycache', 'flaggedpages' ); |
| 297 | + $tables = array( 'page', 'querycache', 'flaggedpages', 'revision' ); |
275 | 298 | } |
| 299 | + $useIndex = array('querycache' => 'qc_type','page' => 'PRIMARY', |
| 300 | + 'revision' => 'page_timestamp'); // sigh... |
276 | 301 | return array( |
277 | 302 | 'tables' => $tables, |
278 | 303 | 'fields' => $fields, |
279 | 304 | 'conds' => $conds, |
280 | | - 'options' => array( 'USE INDEX' => array('querycache' => 'qc_type','page' => 'PRIMARY') ), |
281 | | - 'join_conds' => array( 'flaggedpages' => array('LEFT JOIN','fp_page_id = qc_value') ) |
| 305 | + 'options' => array( 'USE INDEX' => $useIndex, 'GROUP BY' => 'qc_value' ), |
| 306 | + 'join_conds' => array( |
| 307 | + 'querycache' => array('LEFT JOIN','qc_value=page_id'), |
| 308 | + 'revision' => array('LEFT JOIN','rev_page=page_id'), // Get creation date |
| 309 | + 'flaggedpages' => array('LEFT JOIN','fp_page_id=page_id'), |
| 310 | + 'categorylinks' => array('LEFT JOIN', |
| 311 | + array('cl_from=page_id','cl_to'=>$this->category) ) |
| 312 | + ) |
282 | 313 | ); |
283 | 314 | } |
284 | 315 | |