Index: trunk/extensions/FlaggedRevs/FlaggedArticle.php |
— | — | @@ -1,541 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Class representing a MediaWiki article and history |
5 | | - * |
6 | | - * FlaggedArticle::getTitleInstance() is preferred over constructor calls |
7 | | - */ |
8 | | -class FlaggedArticle extends Article { |
9 | | - /* Process cache variables */ |
10 | | - protected $stable = 0; |
11 | | - protected $stableRev = null; |
12 | | - protected $revsArePending = null; |
13 | | - protected $pendingRevCount = null; |
14 | | - protected $pageConfig = null; |
15 | | - protected $syncedInTracking = null; |
16 | | - |
17 | | - protected $imagePage = null; // for file pages |
18 | | - |
19 | | - /** |
20 | | - * Get a FlaggedArticle for a given title |
21 | | - * @param Title |
22 | | - * @return FlaggedArticle |
23 | | - */ |
24 | | - public static function getTitleInstance( Title $title ) { |
25 | | - // Check if there is already an instance on this title |
26 | | - if ( !isset( $title->flaggedRevsArticle ) ) { |
27 | | - $title->flaggedRevsArticle = new self( $title ); |
28 | | - } |
29 | | - return $title->flaggedRevsArticle; |
30 | | - } |
31 | | - |
32 | | - /** |
33 | | - * Get a FlaggedArticle for a given article |
34 | | - * @param Article |
35 | | - * @return FlaggedArticle |
36 | | - */ |
37 | | - public static function getArticleInstance( Article $article ) { |
38 | | - return self::getTitleInstance( $article->mTitle ); |
39 | | - } |
40 | | - |
41 | | - /** |
42 | | - * Clear object process cache values |
43 | | - * @return void |
44 | | - */ |
45 | | - public function clear() { |
46 | | - $this->stable = 0; |
47 | | - $this->stableRev = null; |
48 | | - $this->revsArePending = null; |
49 | | - $this->pendingRevCount = null; |
50 | | - $this->pageConfig = null; |
51 | | - $this->syncedInTracking = null; |
52 | | - $this->imagePage = null; |
53 | | - parent::clear(); // call super! |
54 | | - } |
55 | | - |
56 | | - /** |
57 | | - * Get the current file version of this file page |
58 | | - * @TODO: kind of hacky |
59 | | - * @return mixed (File/false) |
60 | | - */ |
61 | | - public function getFile() { |
62 | | - if ( $this->mTitle->getNamespace() != NS_FILE ) { |
63 | | - return false; // not a file page |
64 | | - } |
65 | | - if ( is_null( $this->imagePage ) ) { |
66 | | - $this->imagePage = new ImagePage( $this->mTitle ); |
67 | | - } |
68 | | - return $this->imagePage->getFile(); |
69 | | - } |
70 | | - |
71 | | - /** |
72 | | - * Get the displayed file version of this file page |
73 | | - * @TODO: kind of hacky |
74 | | - * @return mixed (File/false) |
75 | | - */ |
76 | | - public function getDisplayedFile() { |
77 | | - if ( $this->mTitle->getNamespace() != NS_FILE ) { |
78 | | - return false; // not a file page |
79 | | - } |
80 | | - if ( is_null( $this->imagePage ) ) { |
81 | | - $this->imagePage = new ImagePage( $this->mTitle ); |
82 | | - } |
83 | | - return $this->imagePage->getDisplayedFile(); |
84 | | - } |
85 | | - |
86 | | - /** |
87 | | - * Is the stable version shown by default for this page? |
88 | | - * @return bool |
89 | | - */ |
90 | | - public function isStableShownByDefault() { |
91 | | - if ( !$this->isReviewable() ) { |
92 | | - return false; // no stable versions can exist |
93 | | - } |
94 | | - $config = $this->getStabilitySettings(); // page configuration |
95 | | - return (bool)$config['override']; |
96 | | - } |
97 | | - |
98 | | - /** |
99 | | - * Do edits have to be reviewed before being shown by default (going live)? |
100 | | - * @return bool |
101 | | - */ |
102 | | - public function editsRequireReview() { |
103 | | - return ( |
104 | | - $this->isReviewable() && // reviewable page |
105 | | - $this->isStableShownByDefault() && // and stable versions override |
106 | | - $this->getStableRev() // and there is a stable version |
107 | | - ); |
108 | | - } |
109 | | - |
110 | | - /** |
111 | | - * Are edits to this page currently pending? |
112 | | - * @return bool |
113 | | - */ |
114 | | - public function revsArePending() { |
115 | | - if ( !$this->mDataLoaded ) { |
116 | | - $this->loadPageData(); |
117 | | - } |
118 | | - return $this->revsArePending; |
119 | | - } |
120 | | - |
121 | | - /** |
122 | | - * Get number of revs since the stable revision |
123 | | - * Note: slower than revsArePending() |
124 | | - * @param int $flags FR_MASTER (be sure to use loadFromDB( FR_MASTER ) if set) |
125 | | - * @return int |
126 | | - */ |
127 | | - public function getPendingRevCount( $flags = 0 ) { |
128 | | - global $wgMemc, $wgParserCacheExpireTime; |
129 | | - if ( !$this->mDataLoaded ) { |
130 | | - $this->loadPageData(); |
131 | | - } |
132 | | - # Pending count deferred even after page data load |
133 | | - if ( $this->pendingRevCount !== null ) { |
134 | | - return $this->pendingRevCount; // use process cache |
135 | | - } |
136 | | - $srev = $this->getStableRev(); |
137 | | - if ( !$srev ) { |
138 | | - return 0; // none |
139 | | - } |
140 | | - $count = null; |
141 | | - $sRevId = $srev->getRevId(); |
142 | | - # Try the cache... |
143 | | - $key = wfMemcKey( 'flaggedrevs', 'countPending', $this->getId() ); |
144 | | - if ( !( $flags & FR_MASTER ) ) { |
145 | | - $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this ); |
146 | | - # Items is cached and newer that page_touched... |
147 | | - if ( $tuple !== false ) { |
148 | | - # Confirm that cache value was made against the same stable rev Id. |
149 | | - # This avoids lengthy cache pollution if $sRevId is outdated. |
150 | | - list( $cRevId, $cPending ) = explode( '-', $tuple, 2 ); |
151 | | - if ( $cRevId == $sRevId ) { |
152 | | - $count = (int)$cPending; |
153 | | - } |
154 | | - } |
155 | | - } |
156 | | - # Otherwise, fetch result from DB as needed... |
157 | | - if ( is_null( $count ) ) { |
158 | | - $db = ( $flags & FR_MASTER ) ? |
159 | | - wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE ); |
160 | | - $srevTS = $db->timestamp( $srev->getRevTimestamp() ); |
161 | | - $count = $db->selectField( 'revision', 'COUNT(*)', |
162 | | - array( 'rev_page' => $this->getId(), |
163 | | - 'rev_timestamp > ' . $db->addQuotes( $srevTS ) ), // bug 15515 |
164 | | - __METHOD__ ); |
165 | | - # Save result to cache... |
166 | | - $data = FlaggedRevs::makeMemcObj( "{$sRevId}-{$count}" ); |
167 | | - $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
168 | | - } |
169 | | - $this->pendingRevCount = $count; |
170 | | - return $this->pendingRevCount; |
171 | | - } |
172 | | - |
173 | | - /** |
174 | | - * Checks if the stable version is synced with the current revision |
175 | | - * Note: slower than getPendingRevCount() |
176 | | - * @return bool |
177 | | - */ |
178 | | - public function stableVersionIsSynced() { |
179 | | - global $wgMemc, $wgParserCacheExpireTime; |
180 | | - $srev = $this->getStableRev(); |
181 | | - if ( !$srev ) { |
182 | | - return true; |
183 | | - } |
184 | | - # Stable text revision must be the same as the current |
185 | | - if ( $this->revsArePending() ) { |
186 | | - return false; |
187 | | - # Stable file revision must be the same as the current |
188 | | - } elseif ( $this->mTitle->getNamespace() == NS_FILE ) { |
189 | | - $file = $this->getFile(); // current upload version |
190 | | - if ( $file && $file->getTimestamp() > $srev->getFileTimestamp() ) { |
191 | | - return false; |
192 | | - } |
193 | | - } |
194 | | - # If using the current version of includes, there is nothing else to check. |
195 | | - if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) { |
196 | | - return true; // short-circuit |
197 | | - } |
198 | | - # Try the cache... |
199 | | - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->getId() ); |
200 | | - $value = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this ); |
201 | | - if ( $value === "true" ) { |
202 | | - return true; |
203 | | - } elseif ( $value === "false" ) { |
204 | | - return false; |
205 | | - } |
206 | | - # Since the stable and current revisions have the same text and only outputs, |
207 | | - # the only other things to check for are template and file differences in the output. |
208 | | - # (a) Check if the current output has a newer template/file used |
209 | | - # (b) Check if the stable version has a file/template that was deleted |
210 | | - $synced = ( !$srev->findPendingTemplateChanges() |
211 | | - && !$srev->findPendingFileChanges( 'noForeign' ) ); |
212 | | - # Save to cache. This will be updated whenever the page is touched. |
213 | | - $data = FlaggedRevs::makeMemcObj( $synced ? "true" : "false" ); |
214 | | - $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
215 | | - |
216 | | - return $synced; |
217 | | - } |
218 | | - |
219 | | - /** |
220 | | - * Are template/file changes and ONLY template/file changes pending? |
221 | | - * @return bool |
222 | | - */ |
223 | | - public function onlyTemplatesOrFilesPending() { |
224 | | - return ( !$this->revsArePending() && !$this->stableVersionIsSynced() ); |
225 | | - } |
226 | | - |
227 | | - /** |
228 | | - * Is this page less open than the site defaults? |
229 | | - * @return bool |
230 | | - */ |
231 | | - public function isPageLocked() { |
232 | | - return ( !FlaggedRevs::isStableShownByDefault() && $this->isStableShownByDefault() ); |
233 | | - } |
234 | | - |
235 | | - /** |
236 | | - * Is this page more open than the site defaults? |
237 | | - * @return bool |
238 | | - */ |
239 | | - public function isPageUnlocked() { |
240 | | - return ( FlaggedRevs::isStableShownByDefault() && !$this->isStableShownByDefault() ); |
241 | | - } |
242 | | - |
243 | | - /** |
244 | | - * Tags are only shown for unreviewed content and this page is not locked/unlocked? |
245 | | - * @return bool |
246 | | - */ |
247 | | - public function lowProfileUI() { |
248 | | - return FlaggedRevs::lowProfileUI() && |
249 | | - FlaggedRevs::isStableShownByDefault() == $this->isStableShownByDefault(); |
250 | | - } |
251 | | - |
252 | | - /** |
253 | | - * Is this article reviewable? |
254 | | - * @return bool |
255 | | - */ |
256 | | - public function isReviewable() { |
257 | | - if ( !FlaggedRevs::inReviewNamespace( $this->mTitle ) ) { |
258 | | - return false; |
259 | | - } |
260 | | - # Check if flagging is disabled for this page via config |
261 | | - if ( FlaggedRevs::useOnlyIfProtected() ) { |
262 | | - $config = $this->getStabilitySettings(); // page configuration |
263 | | - return (bool)$config['override']; // stable is default or flagging disabled |
264 | | - } |
265 | | - return true; |
266 | | - } |
267 | | - |
268 | | - /** |
269 | | - * Is this page in patrollable? |
270 | | - * @return bool |
271 | | - */ |
272 | | - public function isPatrollable() { |
273 | | - if ( !FlaggedRevs::inPatrolNamespace( $this->mTitle ) ) { |
274 | | - return false; |
275 | | - } |
276 | | - return !$this->isReviewable(); // pages that are reviewable are not patrollable |
277 | | - } |
278 | | - |
279 | | - /** |
280 | | - * Get the stable revision ID |
281 | | - * @return int |
282 | | - */ |
283 | | - public function getStable() { |
284 | | - if ( !$this->mDataLoaded ) { |
285 | | - $this->loadPageData(); |
286 | | - } |
287 | | - return (int)$this->stable; |
288 | | - } |
289 | | - |
290 | | - /** |
291 | | - * Get the stable revision |
292 | | - * @return mixed (FlaggedRevision/null) |
293 | | - */ |
294 | | - public function getStableRev() { |
295 | | - if ( !$this->mDataLoaded ) { |
296 | | - $this->loadPageData(); |
297 | | - } |
298 | | - # Stable rev deferred even after page data load |
299 | | - if ( $this->stableRev === null ) { |
300 | | - $srev = FlaggedRevision::newFromTitle( $this->mTitle, $this->stable ); |
301 | | - $this->stableRev = $srev ? $srev : false; // cache negative hits too |
302 | | - } |
303 | | - return $this->stableRev ? $this->stableRev : null; // false => null |
304 | | - } |
305 | | - |
306 | | - /** |
307 | | - * Get visiblity restrictions on page |
308 | | - * @return Array (select,override) |
309 | | - */ |
310 | | - public function getStabilitySettings() { |
311 | | - if ( !$this->mDataLoaded ) { |
312 | | - $this->loadPageData(); |
313 | | - } |
314 | | - return $this->pageConfig; |
315 | | - } |
316 | | - |
317 | | - /* |
318 | | - * Get the fp_reviewed value for this page |
319 | | - * @return bool |
320 | | - */ |
321 | | - public function syncedInTracking() { |
322 | | - if ( !$this->mDataLoaded ) { |
323 | | - $this->loadPageData(); |
324 | | - } |
325 | | - return $this->syncedInTracking; |
326 | | - } |
327 | | - |
328 | | - /** |
329 | | - * Fetch a page record with the given conditions |
330 | | - * @param $dbr Database object |
331 | | - * @param $conditions Array |
332 | | - * @return mixed Database result resource, or false on failure |
333 | | - */ |
334 | | - protected function pageData( $dbr, $conditions ) { |
335 | | - $row = $dbr->selectRow( |
336 | | - array( 'page', 'flaggedpages', 'flaggedpage_config' ), |
337 | | - array_merge( |
338 | | - Article::selectFields(), |
339 | | - FlaggedPageConfig::selectFields(), |
340 | | - array( 'fp_pending_since', 'fp_stable', 'fp_reviewed' ) ), |
341 | | - $conditions, |
342 | | - __METHOD__, |
343 | | - array(), |
344 | | - array( |
345 | | - 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ), |
346 | | - 'flaggedpage_config' => array( 'LEFT JOIN', 'fpc_page_id = page_id' ) ) |
347 | | - ); |
348 | | - return $row; |
349 | | - } |
350 | | - |
351 | | - /** |
352 | | - * Set the page field data loaded from some source |
353 | | - * @param $data Database row object or "fromdb" |
354 | | - * @return void |
355 | | - */ |
356 | | - public function loadPageData( $data = 'fromdb' ) { |
357 | | - $this->mDataLoaded = true; // sanity |
358 | | - # Fetch data from DB as needed... |
359 | | - if ( $data === 'fromdb' ) { |
360 | | - $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle ); |
361 | | - } |
362 | | - # Load in primary page data... |
363 | | - parent::loadPageData( $data /* Row obj */ ); |
364 | | - # Load in FlaggedRevs page data... |
365 | | - $this->stable = 0; // 0 => "found nothing" |
366 | | - $this->stableRev = null; // defer this one... |
367 | | - $this->revsArePending = false; // false => "found nothing" or "none pending" |
368 | | - $this->pendingRevCount = null; // defer this one... |
369 | | - $this->pageConfig = FlaggedPageConfig::getDefaultVisibilitySettings(); // default |
370 | | - $this->syncedInTracking = true; // false => "unreviewed" or "synced" |
371 | | - # Load in Row data if the page exists... |
372 | | - if ( $data ) { |
373 | | - if ( $data->fpc_override !== null ) { // page config row found |
374 | | - $this->pageConfig = FlaggedPageConfig::getVisibilitySettingsFromRow( $data ); |
375 | | - } |
376 | | - if ( $data->fp_stable !== null ) { // stable rev found |
377 | | - $this->stable = (int)$data->fp_stable; |
378 | | - $this->revsArePending = ( $data->fp_pending_since !== null ); // revs await review |
379 | | - $this->syncedInTracking = (bool)$data->fp_reviewed; |
380 | | - } |
381 | | - } |
382 | | - } |
383 | | - |
384 | | - /** |
385 | | - * Set the page field data loaded from the DB |
386 | | - * @param int $flags FR_MASTER |
387 | | - * @param $data Database row object or "fromdb" |
388 | | - */ |
389 | | - public function loadFromDB( $flags = 0 ) { |
390 | | - $db = ( $flags & FR_MASTER ) ? |
391 | | - wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE ); |
392 | | - $this->loadPageData( $this->pageDataFromTitle( $db, $this->mTitle ) ); |
393 | | - } |
394 | | - |
395 | | - /** |
396 | | - * Updates the flagging tracking tables for this page |
397 | | - * @param FlaggedRevision $srev The new stable version |
398 | | - * @param mixed $latest The latest rev ID (optional) |
399 | | - * @return bool Updates were done |
400 | | - */ |
401 | | - public function updateStableVersion( FlaggedRevision $srev, $latest = null ) { |
402 | | - $rev = $srev->getRevision(); |
403 | | - if ( !$this->exists() || !$rev ) { |
404 | | - return false; // no bogus entries |
405 | | - } |
406 | | - # Get the latest revision ID if not set |
407 | | - if ( !$latest ) { |
408 | | - $latest = $this->mTitle->getLatestRevID( Title::GAID_FOR_UPDATE ); |
409 | | - } |
410 | | - $dbw = wfGetDB( DB_MASTER ); |
411 | | - # Get the highest quality revision (not necessarily this one)... |
412 | | - if ( $srev->getQuality() === FlaggedRevs::highestReviewTier() ) { |
413 | | - $maxQuality = $srev->getQuality(); // save a query |
414 | | - } else { |
415 | | - $maxQuality = $dbw->selectField( array( 'flaggedrevs', 'revision' ), |
416 | | - 'fr_quality', |
417 | | - array( 'fr_page_id' => $this->getId(), |
418 | | - 'rev_id = fr_rev_id', |
419 | | - 'rev_page = fr_page_id', |
420 | | - 'rev_deleted & ' . Revision::DELETED_TEXT => 0 |
421 | | - ), |
422 | | - __METHOD__, |
423 | | - array( 'ORDER BY' => 'fr_quality DESC', 'LIMIT' => 1 ) |
424 | | - ); |
425 | | - $maxQuality = max( $maxQuality, $srev->getQuality() ); // sanity |
426 | | - } |
427 | | - # Get the timestamp of the first edit after the stable version (if any)... |
428 | | - $nextTimestamp = null; |
429 | | - if ( $rev->getId() != $latest ) { |
430 | | - $timestamp = $dbw->timestamp( $rev->getTimestamp() ); |
431 | | - $nextEditTS = $dbw->selectField( 'revision', |
432 | | - 'rev_timestamp', |
433 | | - array( |
434 | | - 'rev_page' => $this->getId(), |
435 | | - "rev_timestamp > " . $dbw->addQuotes( $timestamp ) ), |
436 | | - __METHOD__, |
437 | | - array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ) |
438 | | - ); |
439 | | - if ( $nextEditTS ) { // sanity check |
440 | | - $nextTimestamp = $nextEditTS; |
441 | | - } |
442 | | - } |
443 | | - # Get the new page sync status... |
444 | | - $synced = !( |
445 | | - $nextTimestamp !== null || // edits pending |
446 | | - $srev->findPendingTemplateChanges() || // template changes pending |
447 | | - $srev->findPendingFileChanges( 'noForeign' ) // file changes pending |
448 | | - ); |
449 | | - # Alter table metadata |
450 | | - $dbw->replace( 'flaggedpages', |
451 | | - array( 'fp_page_id' ), |
452 | | - array( |
453 | | - 'fp_page_id' => $this->getId(), |
454 | | - 'fp_stable' => $rev->getId(), |
455 | | - 'fp_reviewed' => $synced ? 1 : 0, |
456 | | - 'fp_quality' => ( $maxQuality === false ) ? null : $maxQuality, |
457 | | - 'fp_pending_since' => $dbw->timestampOrNull( $nextTimestamp ) |
458 | | - ), |
459 | | - __METHOD__ |
460 | | - ); |
461 | | - # Update pending edit tracking table |
462 | | - self::updatePendingList( $this->getId(), $latest ); |
463 | | - return true; |
464 | | - } |
465 | | - |
466 | | - /** |
467 | | - * Updates the flagging tracking tables for this page |
468 | | - * @return void |
469 | | - */ |
470 | | - public function clearStableVersion() { |
471 | | - if ( !$this->exists() ) { |
472 | | - return; // nothing to do |
473 | | - } |
474 | | - $dbw = wfGetDB( DB_MASTER ); |
475 | | - $dbw->delete( 'flaggedpages', |
476 | | - array( 'fp_page_id' => $this->getId() ), __METHOD__ ); |
477 | | - $dbw->delete( 'flaggedpage_pending', |
478 | | - array( 'fpp_page_id' => $this->getId() ), __METHOD__ ); |
479 | | - } |
480 | | - |
481 | | - /** |
482 | | - * Updates the flaggedpage_pending table |
483 | | - * @param int $pageId Page ID |
484 | | - * @abstract int $latest Latest revision |
485 | | - * @return void |
486 | | - */ |
487 | | - protected static function updatePendingList( $pageId, $latest ) { |
488 | | - $data = array(); |
489 | | - $level = FlaggedRevs::highestReviewTier(); |
490 | | - # Update pending times for each level, going from highest to lowest |
491 | | - $dbw = wfGetDB( DB_MASTER ); |
492 | | - $higherLevelId = 0; |
493 | | - $higherLevelTS = ''; |
494 | | - while ( $level >= 0 ) { |
495 | | - # Get the latest revision of this level... |
496 | | - $row = $dbw->selectRow( array( 'flaggedrevs', 'revision' ), |
497 | | - array( 'fr_rev_id', 'rev_timestamp' ), |
498 | | - array( 'fr_page_id' => $pageId, |
499 | | - 'fr_quality' => $level, |
500 | | - 'rev_id = fr_rev_id', |
501 | | - 'rev_page = fr_page_id', |
502 | | - 'rev_deleted & ' . Revision::DELETED_TEXT => 0, |
503 | | - 'rev_id > ' . intval( $higherLevelId ) |
504 | | - ), |
505 | | - __METHOD__, |
506 | | - array( 'ORDER BY' => 'fr_rev_id DESC', 'LIMIT' => 1 ) |
507 | | - ); |
508 | | - # If there is a revision of this level, track it... |
509 | | - # Revisions reviewed to one level count as reviewed |
510 | | - # at the lower levels (i.e. quality -> checked). |
511 | | - if ( $row ) { |
512 | | - $id = $row->fr_rev_id; |
513 | | - $ts = $row->rev_timestamp; |
514 | | - } else { |
515 | | - $id = $higherLevelId; // use previous (quality -> checked) |
516 | | - $ts = $higherLevelTS; // use previous (quality -> checked) |
517 | | - } |
518 | | - # Get edits that actually are pending... |
519 | | - if ( $id && $latest > $id ) { |
520 | | - # Get the timestamp of the edit after this version (if any) |
521 | | - $nextTimestamp = $dbw->selectField( 'revision', |
522 | | - 'rev_timestamp', |
523 | | - array( 'rev_page' => $pageId, "rev_timestamp > " . $dbw->addQuotes( $ts ) ), |
524 | | - __METHOD__, |
525 | | - array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ) |
526 | | - ); |
527 | | - $data[] = array( |
528 | | - 'fpp_page_id' => $pageId, |
529 | | - 'fpp_quality' => $level, |
530 | | - 'fpp_rev_id' => $id, |
531 | | - 'fpp_pending_since' => $nextTimestamp |
532 | | - ); |
533 | | - $higherLevelId = $id; |
534 | | - $higherLevelTS = $ts; |
535 | | - } |
536 | | - $level--; |
537 | | - } |
538 | | - # Clear any old junk, and insert new rows |
539 | | - $dbw->delete( 'flaggedpage_pending', array( 'fpp_page_id' => $pageId ), __METHOD__ ); |
540 | | - $dbw->insert( 'flaggedpage_pending', $data, __METHOD__ ); |
541 | | - } |
542 | | -} |
Index: trunk/extensions/FlaggedRevs/FRUserCounters.php |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | * @param int $uid |
10 | 10 | * @param int $flags FR_MASTER, FR_FOR_UPDATE |
11 | 11 | * @param string $dBName, optional wiki name |
12 | | - * @returns array |
| 12 | + * @return array |
13 | 13 | */ |
14 | 14 | public static function getUserParams( $uid, $flags = 0, $dBName = false ) { |
15 | 15 | $p = array(); |
— | — | @@ -44,7 +44,7 @@ |
45 | 45 | * @param int $uid |
46 | 46 | * @param int $flags FR_MASTER, FR_FOR_UPDATE |
47 | 47 | * @param string $dBName, optional wiki name |
48 | | - * @returns mixed (false or Row) |
| 48 | + * @return mixed (false or Row) |
49 | 49 | */ |
50 | 50 | protected static function fetchParamsRow( $uid, $flags = 0, $dBName = false ) { |
51 | 51 | $options = array(); |
— | — | @@ -67,7 +67,7 @@ |
68 | 68 | * @param int $uid |
69 | 69 | * @param array $params |
70 | 70 | * @param string $dBName, optional wiki name |
71 | | - * @returns bool success |
| 71 | + * @return bool success |
72 | 72 | */ |
73 | 73 | public static function saveUserParams( $uid, array $params, $dBName = false ) { |
74 | 74 | $dbw = wfGetDB( DB_MASTER, array(), $dBName ); |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | * Flatten params for a user for DB storage |
86 | 86 | * Note: param values must be integers |
87 | 87 | * @param array $params |
88 | | - * @returns string |
| 88 | + * @return string |
89 | 89 | */ |
90 | 90 | protected static function flattenParams( array $params ) { |
91 | 91 | $flatRows = array(); |
— | — | @@ -105,7 +105,7 @@ |
106 | 106 | /** |
107 | 107 | * Expand params for a user from DB storage |
108 | 108 | * @param string $flatPars |
109 | | - * @returns array |
| 109 | + * @return array |
110 | 110 | */ |
111 | 111 | protected static function expandParams( $flatPars ) { |
112 | 112 | $p = array(); // init |
— | — | @@ -131,7 +131,7 @@ |
132 | 132 | * @param &array $p user params |
133 | 133 | * @param Article $article the article just edited |
134 | 134 | * @param string $summary edit summary |
135 | | - * @returns bool anything changed |
| 135 | + * @return bool anything changed |
136 | 136 | */ |
137 | 137 | public static function updateUserParams( array &$p, Article $article, $summary ) { |
138 | 138 | global $wgFlaggedRevsAutoconfirm, $wgFlaggedRevsAutopromote; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.php |
— | — | @@ -258,7 +258,7 @@ |
259 | 259 | $wgAutoloadClasses['FRSquidUpdate'] = $dir . 'FRExtraCacheUpdate.php'; |
260 | 260 | $wgAutoloadClasses['FRDependencyUpdate'] = $dir . 'FRDependencyUpdate.php'; |
261 | 261 | $wgAutoloadClasses['FRInclusionManager'] = $dir . 'FRInclusionManager.php'; |
262 | | -$wgAutoloadClasses['FlaggedArticle'] = $dir . 'FlaggedArticle.php'; |
| 262 | +$wgAutoloadClasses['FlaggedPage'] = $dir . 'FlaggedPage.php'; |
263 | 263 | $wgAutoloadClasses['FlaggedRevision'] = $dir . 'FlaggedRevision.php'; |
264 | 264 | |
265 | 265 | # Business object classes |
— | — | @@ -269,7 +269,7 @@ |
270 | 270 | $wgAutoloadClasses['PageStabilityProtectForm'] = $dir . 'business/PageStabilityForm.php'; |
271 | 271 | |
272 | 272 | # Presentation classes... |
273 | | -$wgAutoloadClasses['FlaggedArticleView'] = $dir . 'presentation/FlaggedArticleView.php'; |
| 273 | +$wgAutoloadClasses['FlaggedPageView'] = $dir . 'presentation/FlaggedPageView.php'; |
274 | 274 | $wgAutoloadClasses['FlaggedRevsLogView'] = $dir . 'presentation/FlaggedRevsLogView.php'; |
275 | 275 | $wgAutoloadClasses['FlaggedRevsXML'] = $dir . 'presentation/FlaggedRevsXML.php'; |
276 | 276 | $wgAutoloadClasses['RevisionReviewFormGUI'] = $dir . 'presentation/RevisionReviewFormGUI.php'; |
— | — | @@ -626,7 +626,7 @@ |
627 | 627 | |
628 | 628 | # AJAX functions |
629 | 629 | $wgAjaxExportList[] = 'RevisionReview::AjaxReview'; |
630 | | -$wgAjaxExportList[] = 'FlaggedArticleView::AjaxBuildDiffHeaderItems'; |
| 630 | +$wgAjaxExportList[] = 'FlaggedPageView::AjaxBuildDiffHeaderItems'; |
631 | 631 | |
632 | 632 | # Cache update |
633 | 633 | $wgSpecialPageCacheUpdates[] = 'efFlaggedRevsUnreviewedPagesUpdate'; |
— | — | @@ -640,4 +640,4 @@ |
641 | 641 | } |
642 | 642 | |
643 | 643 | # B/C ... |
644 | | -$wgLogActions['rights/erevoke'] = 'rights-editor-revoke'; |
\ No newline at end of file |
| 644 | +$wgLogActions['rights/erevoke'] = 'rights-editor-revoke'; |
Index: trunk/extensions/FlaggedRevs/FlaggedRevsLog.php |
— | — | @@ -3,7 +3,7 @@ |
4 | 4 | class FlaggedRevsLog { |
5 | 5 | /** |
6 | 6 | * $action is a valid review log action |
7 | | - * @returns bool |
| 7 | + * @return bool |
8 | 8 | */ |
9 | 9 | public static function isReviewAction( $action ) { |
10 | 10 | return preg_match( '/^(approve2?(-i|-a|-ia)?|unapprove2?)$/', $action ); |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | |
13 | 13 | /** |
14 | 14 | * $action is a valid stability log action |
15 | | - * @returns bool |
| 15 | + * @return bool |
16 | 16 | */ |
17 | 17 | public static function isStabilityAction( $action ) { |
18 | 18 | return preg_match( '/^(config|modify|reset)$/', $action ); |
— | — | @@ -19,7 +19,7 @@ |
20 | 20 | |
21 | 21 | /** |
22 | 22 | * $action is a valid review log deprecate action |
23 | | - * @returns bool |
| 23 | + * @return bool |
24 | 24 | */ |
25 | 25 | public static function isReviewDeapproval( $action ) { |
26 | 26 | return ( $action == 'unapprove' || $action == 'unapprove2' ); |
— | — | @@ -116,7 +116,7 @@ |
117 | 117 | /** |
118 | 118 | * Get log params (associate array) from a stability config |
119 | 119 | * @param array $config |
120 | | - * @returns array (associative) |
| 120 | + * @return array (associative) |
121 | 121 | */ |
122 | 122 | public static function stabilityLogParams( array $config ) { |
123 | 123 | $params = $config; |
— | — | @@ -129,9 +129,9 @@ |
130 | 130 | /** |
131 | 131 | * Collapse an associate array into a string |
132 | 132 | * @param array $pars |
133 | | - * @returns string |
| 133 | + * @return string |
134 | 134 | */ |
135 | | - public static function collapseParams( Array $pars ) { |
| 135 | + public static function collapseParams( array $pars ) { |
136 | 136 | $res = array(); |
137 | 137 | foreach ( $pars as $param => $value ) { |
138 | 138 | // Sanity check... |
— | — | @@ -148,9 +148,9 @@ |
149 | 149 | /** |
150 | 150 | * Expand a list of log params into an associative array |
151 | 151 | * @params array $pars |
152 | | - * @returns array (associative) |
| 152 | + * @return array (associative) |
153 | 153 | */ |
154 | | - public static function expandParams( Array $pars ) { |
| 154 | + public static function expandParams( array $pars ) { |
155 | 155 | $res = array(); |
156 | 156 | foreach ( $pars as $paramAndValue ) { |
157 | 157 | list( $param, $value ) = explode( '=', $paramAndValue, 2 ); |
Index: trunk/extensions/FlaggedRevs/maintenance/purgeReviewablePages.inc |
— | — | @@ -33,7 +33,7 @@ |
34 | 34 | # Go through and append each purgeable page... |
35 | 35 | foreach ( $res as $row ) { |
36 | 36 | $title = Title::newFromRow( $row ); |
37 | | - $fa = FlaggedArticle::getTitleInstance( $title ); |
| 37 | + $fa = FlaggedPage::getTitleInstance( $title ); |
38 | 38 | if ( $fa->isReviewable() ) { |
39 | 39 | # Need to purge this page - add to list |
40 | 40 | fwrite( $fileHandle, $title->getPrefixedDBKey() . "\n" ); |
Index: trunk/extensions/FlaggedRevs/maintenance/updateTracking.inc |
— | — | @@ -123,7 +123,7 @@ |
124 | 124 | $db->begin(); |
125 | 125 | foreach ( $res as $row ) { |
126 | 126 | $title = Title::newFromRow( $row ); |
127 | | - $article = new FlaggedArticle( $title ); |
| 127 | + $article = new FlaggedPage( $title ); |
128 | 128 | $oldFrev = FlaggedRevision::newFromStable( $title, FR_MASTER ); |
129 | 129 | $frev = FlaggedRevision::determineStable( $title, FR_MASTER ); |
130 | 130 | # Update fp_stable, fp_quality, and fp_reviewed |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.class.php |
— | — | @@ -132,7 +132,7 @@ |
133 | 133 | |
134 | 134 | /** |
135 | 135 | * Is there only one tag and it has only one level? |
136 | | - * @returns bool |
| 136 | + * @return bool |
137 | 137 | */ |
138 | 138 | public static function binaryFlagging() { |
139 | 139 | self::load(); |
— | — | @@ -141,7 +141,7 @@ |
142 | 142 | |
143 | 143 | /** |
144 | 144 | * If there only one tag and it has only one level, return it |
145 | | - * @returns string |
| 145 | + * @return string |
146 | 146 | */ |
147 | 147 | public static function binaryTagName() { |
148 | 148 | self::load(); |
— | — | @@ -154,7 +154,7 @@ |
155 | 155 | |
156 | 156 | /** |
157 | 157 | * Are quality versions enabled? |
158 | | - * @returns bool |
| 158 | + * @return bool |
159 | 159 | */ |
160 | 160 | public static function qualityVersions() { |
161 | 161 | self::load(); |
— | — | @@ -163,7 +163,7 @@ |
164 | 164 | |
165 | 165 | /** |
166 | 166 | * Are pristine versions enabled? |
167 | | - * @returns bool |
| 167 | + * @return bool |
168 | 168 | */ |
169 | 169 | public static function pristineVersions() { |
170 | 170 | self::load(); |
— | — | @@ -172,7 +172,7 @@ |
173 | 173 | |
174 | 174 | /** |
175 | 175 | * Get the highest review tier that is enabled |
176 | | - * @returns int One of FR_PRISTINE,FR_QUALITY,FR_CHECKED |
| 176 | + * @return int One of FR_PRISTINE,FR_QUALITY,FR_CHECKED |
177 | 177 | */ |
178 | 178 | public static function highestReviewTier() { |
179 | 179 | self::load(); |
— | — | @@ -186,7 +186,7 @@ |
187 | 187 | |
188 | 188 | /** |
189 | 189 | * Allow auto-review edits directly to the stable version by reviewers? |
190 | | - * @returns bool |
| 190 | + * @return bool |
191 | 191 | */ |
192 | 192 | public static function autoReviewEdits() { |
193 | 193 | self::load(); |
— | — | @@ -195,7 +195,7 @@ |
196 | 196 | |
197 | 197 | /** |
198 | 198 | * Auto-review new pages with the minimal level? |
199 | | - * @returns bool |
| 199 | + * @return bool |
200 | 200 | */ |
201 | 201 | public static function autoReviewNewPages() { |
202 | 202 | self::load(); |
— | — | @@ -204,7 +204,7 @@ |
205 | 205 | |
206 | 206 | /** |
207 | 207 | * Auto-review of new pages or edits to pages enabled? |
208 | | - * @returns bool |
| 208 | + * @return bool |
209 | 209 | */ |
210 | 210 | public static function autoReviewEnabled() { |
211 | 211 | return self::autoReviewEdits() || self::autoReviewNewPages(); |
— | — | @@ -213,7 +213,7 @@ |
214 | 214 | /** |
215 | 215 | * Get the maximum level that $tag can be autoreviewed to |
216 | 216 | * @param string $tag |
217 | | - * @returns int |
| 217 | + * @return int |
218 | 218 | */ |
219 | 219 | public static function maxAutoReviewLevel( $tag ) { |
220 | 220 | global $wgFlaggedRevsTagsAuto; |
— | — | @@ -231,7 +231,7 @@ |
232 | 232 | /** |
233 | 233 | * Is a "stable version" used as the default display |
234 | 234 | * version for all pages in reviewable namespaces? |
235 | | - * @returns bool |
| 235 | + * @return bool |
236 | 236 | */ |
237 | 237 | public static function isStableShownByDefault() { |
238 | 238 | global $wgFlaggedRevsOverride; |
— | — | @@ -244,7 +244,7 @@ |
245 | 245 | /** |
246 | 246 | * Are pages reviewable only if they have been manually |
247 | 247 | * configured by an admin to use a "stable version" as the default? |
248 | | - * @returns bool |
| 248 | + * @return bool |
249 | 249 | */ |
250 | 250 | public static function useOnlyIfProtected() { |
251 | 251 | global $wgFlaggedRevsProtection; |
— | — | @@ -253,7 +253,7 @@ |
254 | 254 | |
255 | 255 | /** |
256 | 256 | * Return the include handling configuration |
257 | | - * @returns int |
| 257 | + * @return int |
258 | 258 | */ |
259 | 259 | public static function inclusionSetting() { |
260 | 260 | global $wgFlaggedRevsHandleIncludes; |
— | — | @@ -262,7 +262,7 @@ |
263 | 263 | |
264 | 264 | /** |
265 | 265 | * Should tags only be shown for unreviewed content for this user? |
266 | | - * @returns bool |
| 266 | + * @return bool |
267 | 267 | */ |
268 | 268 | public static function lowProfileUI() { |
269 | 269 | global $wgFlaggedRevsLowProfile; |
— | — | @@ -271,7 +271,7 @@ |
272 | 272 | |
273 | 273 | /** |
274 | 274 | * Are there site defined protection levels for review |
275 | | - * @returns bool |
| 275 | + * @return bool |
276 | 276 | */ |
277 | 277 | public static function useProtectionLevels() { |
278 | 278 | global $wgFlaggedRevsProtection; |
— | — | @@ -280,7 +280,7 @@ |
281 | 281 | |
282 | 282 | /** |
283 | 283 | * Get the autoreview restriction levels available |
284 | | - * @returns array |
| 284 | + * @return array |
285 | 285 | */ |
286 | 286 | public static function getRestrictionLevels() { |
287 | 287 | self::load(); |
— | — | @@ -289,7 +289,7 @@ |
290 | 290 | |
291 | 291 | /** |
292 | 292 | * Get the array of tag dimensions and level messages |
293 | | - * @returns array |
| 293 | + * @return array |
294 | 294 | */ |
295 | 295 | public static function getDimensions() { |
296 | 296 | self::load(); |
— | — | @@ -299,7 +299,7 @@ |
300 | 300 | /** |
301 | 301 | * Get the associative array of tag dimensions |
302 | 302 | * (tags => array(levels => msgkey)) |
303 | | - * @returns array |
| 303 | + * @return array |
304 | 304 | */ |
305 | 305 | public static function getTags() { |
306 | 306 | self::load(); |
— | — | @@ -309,7 +309,7 @@ |
310 | 310 | /** |
311 | 311 | * Get the associative array of tag restrictions |
312 | 312 | * (tags => array(rights => levels)) |
313 | | - * @returns array |
| 313 | + * @return array |
314 | 314 | */ |
315 | 315 | public static function getTagRestrictions() { |
316 | 316 | self::load(); |
— | — | @@ -319,7 +319,7 @@ |
320 | 320 | /** |
321 | 321 | * Get the UI name for a tag |
322 | 322 | * @param string $tag |
323 | | - * @returns string |
| 323 | + * @return string |
324 | 324 | */ |
325 | 325 | public static function getTagMsg( $tag ) { |
326 | 326 | return wfMsgExt( "revreview-$tag", array( 'escapenoentities' ) ); |
— | — | @@ -328,7 +328,7 @@ |
329 | 329 | /** |
330 | 330 | * Get the levels for a tag. Gives map of level to message name. |
331 | 331 | * @param string $tag |
332 | | - * @returns associative array (integer -> string) |
| 332 | + * @return associative array (integer -> string) |
333 | 333 | */ |
334 | 334 | public static function getTagLevels( $tag ) { |
335 | 335 | self::load(); |
— | — | @@ -340,7 +340,7 @@ |
341 | 341 | * Get the the UI name for a value of a tag |
342 | 342 | * @param string $tag |
343 | 343 | * @param int $value |
344 | | - * @returns string |
| 344 | + * @return string |
345 | 345 | */ |
346 | 346 | public static function getTagValueMsg( $tag, $value ) { |
347 | 347 | self::load(); |
— | — | @@ -356,7 +356,7 @@ |
357 | 357 | |
358 | 358 | /** |
359 | 359 | * Are there no actual dimensions? |
360 | | - * @returns bool |
| 360 | + * @return bool |
361 | 361 | */ |
362 | 362 | public static function dimensionsEmpty() { |
363 | 363 | self::load(); |
— | — | @@ -411,7 +411,7 @@ |
412 | 412 | /** |
413 | 413 | * Check if all of the required site flags have a valid value |
414 | 414 | * @param array $flags |
415 | | - * @returns bool |
| 415 | + * @return bool |
416 | 416 | */ |
417 | 417 | public static function flagsAreValid( array $flags ) { |
418 | 418 | foreach ( self::getDimensions() as $qal => $levels ) { |
— | — | @@ -427,7 +427,7 @@ |
428 | 428 | * @param User $user |
429 | 429 | * @param string $tag |
430 | 430 | * @param int $value |
431 | | - * @returns bool |
| 431 | + * @return bool |
432 | 432 | */ |
433 | 433 | public static function userCanSetTag( $user, $tag, $value ) { |
434 | 434 | # Sanity check tag and value |
— | — | @@ -459,7 +459,7 @@ |
460 | 460 | * @param User $user |
461 | 461 | * @param array $flags, suggested flags |
462 | 462 | * @param array $oldflags, pre-existing flags |
463 | | - * @returns bool |
| 463 | + * @return bool |
464 | 464 | */ |
465 | 465 | public static function userCanSetFlags( $user, array $flags, $oldflags = array() ) { |
466 | 466 | if ( !$user->isAllowed( 'review' ) ) { |
— | — | @@ -485,7 +485,7 @@ |
486 | 486 | * Check if a user can set the autoreview restiction level to $right |
487 | 487 | * @param User $user |
488 | 488 | * @param string $right the level |
489 | | - * @returns bool |
| 489 | + * @return bool |
490 | 490 | */ |
491 | 491 | public static function userCanSetAutoreviewLevel( $user, $right ) { |
492 | 492 | if ( $right == '' ) { |
— | — | @@ -513,7 +513,7 @@ |
514 | 514 | * @param Title $title |
515 | 515 | * @param string $text wikitext |
516 | 516 | * @param int $id Source revision Id |
517 | | - * @return Array( string wikitext, array of template versions ) |
| 517 | + * @return array( string wikitext, array of template versions ) |
518 | 518 | */ |
519 | 519 | public static function expandText( Title $title, $text, $id ) { |
520 | 520 | global $wgParser; |
— | — | @@ -577,7 +577,7 @@ |
578 | 578 | /** |
579 | 579 | * Get standard parser options |
580 | 580 | * @param User $user (optional) |
581 | | - * @returns ParserOptions |
| 581 | + * @return ParserOptions |
582 | 582 | */ |
583 | 583 | public static function makeParserOptions( $user = null ) { |
584 | 584 | global $wgUser; |
— | — | @@ -722,8 +722,8 @@ |
723 | 723 | /** |
724 | 724 | * Update the page tables with a new stable version. |
725 | 725 | * @param Title $title |
726 | | - * @param mixed $sv, the new stable version (optional) |
727 | | - * @param mixed $oldSv, the old stable version (optional) |
| 726 | + * @param FlaggedRevision|null $sv, the new stable version (optional) |
| 727 | + * @param FlaggedRevision|null $oldSv, the old stable version (optional) |
728 | 728 | * @return bool stable version text/file changed and FR_INCLUDES_STABLE |
729 | 729 | */ |
730 | 730 | public static function stableVersionUpdates( Title $title, $sv = null, $oldSv = null ) { |
— | — | @@ -734,7 +734,7 @@ |
735 | 735 | if ( $sv === null ) { // optional |
736 | 736 | $sv = FlaggedRevision::determineStable( $title, FR_MASTER ); |
737 | 737 | } |
738 | | - $article = new FlaggedArticle( $title ); |
| 738 | + $article = new FlaggedPage( $title ); |
739 | 739 | if ( !$sv ) { |
740 | 740 | # Empty flaggedrevs data for this page if there is no stable version |
741 | 741 | $article->clearStableVersion(); |
— | — | @@ -804,7 +804,7 @@ |
805 | 805 | * @param Title $title |
806 | 806 | * @param int $rev_id |
807 | 807 | * @param $flags, FR_MASTER |
808 | | - * @return Array |
| 808 | + * @return array |
809 | 809 | */ |
810 | 810 | public static function getRevisionTags( Title $title, $rev_id, $flags = 0 ) { |
811 | 811 | $db = ( $flags & FR_MASTER ) ? |
— | — | @@ -822,7 +822,7 @@ |
823 | 823 | * @param int $page_id |
824 | 824 | * @param int $rev_id |
825 | 825 | * @param $flags, FR_MASTER |
826 | | - * @returns mixed (int or false) |
| 826 | + * @return mixed (int or false) |
827 | 827 | * Get quality of a revision |
828 | 828 | */ |
829 | 829 | public static function getRevQuality( $page_id, $rev_id, $flags = 0 ) { |
— | — | @@ -840,7 +840,7 @@ |
841 | 841 | * @param Title $title |
842 | 842 | * @param int $rev_id |
843 | 843 | * @param $flags, FR_MASTER |
844 | | - * @returns bool |
| 844 | + * @return bool |
845 | 845 | * Useful for quickly pinging to see if a revision is flagged |
846 | 846 | */ |
847 | 847 | public static function revIsFlagged( Title $title, $rev_id, $flags = 0 ) { |
— | — | @@ -851,7 +851,7 @@ |
852 | 852 | /** |
853 | 853 | * Get the "prime" flagged revision of a page |
854 | 854 | * @param Article $article |
855 | | - * @returns mixed (integer/false) |
| 855 | + * @return mixed (integer/false) |
856 | 856 | * Will not return a revision if deleted |
857 | 857 | */ |
858 | 858 | public static function getPrimeFlaggedRevId( Article $article ) { |
— | — | @@ -876,7 +876,7 @@ |
877 | 877 | /** |
878 | 878 | * Mark a revision as patrolled if needed |
879 | 879 | * @param Revision $rev |
880 | | - * @returns bool DB write query used |
| 880 | + * @return bool DB write query used |
881 | 881 | */ |
882 | 882 | public static function markRevisionPatrolled( Revision $rev ) { |
883 | 883 | $rcid = $rev->isUnpatrolled(); |
— | — | @@ -908,7 +908,7 @@ |
909 | 909 | } |
910 | 910 | |
911 | 911 | /** |
912 | | - * @param mixed $data makeMemcObj() tuple (false/Object) |
| 912 | + * @param object|false $data makeMemcObj() tuple |
913 | 913 | * @param Article $article |
914 | 914 | * @return mixed |
915 | 915 | * Return memc value if not expired |
— | — | @@ -980,7 +980,7 @@ |
981 | 981 | /** |
982 | 982 | * Get minimum level tags for a tier |
983 | 983 | * @param int $tier FR_PRISTINE/FR_QUALITY/FR_CHECKED |
984 | | - * @return Array |
| 984 | + * @return array |
985 | 985 | */ |
986 | 986 | public static function quickTags( $tier ) { |
987 | 987 | self::load(); |
— | — | @@ -1022,7 +1022,7 @@ |
1023 | 1023 | |
1024 | 1024 | /** |
1025 | 1025 | * Get the list of reviewable namespaces |
1026 | | - * @return Array |
| 1026 | + * @return array |
1027 | 1027 | */ |
1028 | 1028 | public static function getReviewNamespaces() { |
1029 | 1029 | self::load(); // validates namespaces |
— | — | @@ -1031,7 +1031,7 @@ |
1032 | 1032 | |
1033 | 1033 | /** |
1034 | 1034 | * Get the list of patrollable namespaces |
1035 | | - * @return Array |
| 1035 | + * @return array |
1036 | 1036 | */ |
1037 | 1037 | public static function getPatrolNamespaces() { |
1038 | 1038 | self::load(); // validates namespaces |
— | — | @@ -1071,7 +1071,7 @@ |
1072 | 1072 | |
1073 | 1073 | /** |
1074 | 1074 | * Clear FlaggedRevs tracking tables for this page |
1075 | | - * @param mixed $pageId (int or array) |
| 1075 | + * @param int|array $pageId (int or array) |
1076 | 1076 | */ |
1077 | 1077 | public static function clearTrackingRows( $pageId ) { |
1078 | 1078 | $dbw = wfGetDB( DB_MASTER ); |
— | — | @@ -1082,7 +1082,7 @@ |
1083 | 1083 | |
1084 | 1084 | /** |
1085 | 1085 | * Clear tracking table of stable-only links for this page |
1086 | | - * @param mixed $pageId (int or array) |
| 1086 | + * @param int|array $pageId (int or array) |
1087 | 1087 | */ |
1088 | 1088 | public static function clearStableOnlyDeps( $pageId ) { |
1089 | 1089 | $dbw = wfGetDB( DB_MASTER ); |
Index: trunk/extensions/FlaggedRevs/business/RevisionReviewForm.php |
— | — | @@ -138,7 +138,7 @@ |
139 | 139 | * @return mixed (true on success, error string on failure) |
140 | 140 | */ |
141 | 141 | protected function doBuildOnReady() { |
142 | | - $this->article = FlaggedArticle::getTitleInstance( $this->page ); |
| 142 | + $this->article = FlaggedPage::getTitleInstance( $this->page ); |
143 | 143 | return true; |
144 | 144 | } |
145 | 145 | |
— | — | @@ -320,7 +320,7 @@ |
321 | 321 | * Adds or updates the flagged revision table for this page/id set |
322 | 322 | * @param Revision $rev The revision to be accepted |
323 | 323 | * @param FlaggedRevision $oldFrev Currently accepted version of $rev or null |
324 | | - * @returns true on success, array of errors on failure |
| 324 | + * @return true on success, array of errors on failure |
325 | 325 | */ |
326 | 326 | private function approveRevision( Revision $rev, FlaggedRevision $oldFrev = null ) { |
327 | 327 | wfProfileIn( __METHOD__ ); |
— | — | @@ -486,13 +486,13 @@ |
487 | 487 | |
488 | 488 | /** |
489 | 489 | * Get template and image parameters from parser output to use on forms. |
490 | | - * @param FlaggedArticle $article |
| 490 | + * @param FlaggedPage $article |
491 | 491 | * @param array $templateIDs (from ParserOutput/OutputPage->mTemplateIds) |
492 | 492 | * @param array $imageSHA1Keys (from ParserOutput/OutputPage->mImageTimeKeys) |
493 | | - * @returns array( templateParams, imageParams, fileVersion ) |
| 493 | + * @return array( templateParams, imageParams, fileVersion ) |
494 | 494 | */ |
495 | 495 | public static function getIncludeParams( |
496 | | - FlaggedArticle $article, array $templateIDs, array $imageSHA1Keys |
| 496 | + FlaggedPage $article, array $templateIDs, array $imageSHA1Keys |
497 | 497 | ) { |
498 | 498 | $templateParams = $imageParams = $fileVersion = ''; |
499 | 499 | # NS -> title -> rev ID mapping |
— | — | @@ -520,7 +520,7 @@ |
521 | 521 | * Get template and image versions from form value for parser output. |
522 | 522 | * @param string $templateParams |
523 | 523 | * @param string $imageParams |
524 | | - * @returns array( templateIds, fileSHA1Keys ) |
| 524 | + * @return array( templateIds, fileSHA1Keys ) |
525 | 525 | * templateIds like ParserOutput->mTemplateIds |
526 | 526 | * fileSHA1Keys like ParserOutput->mImageTimeKeys |
527 | 527 | */ |
— | — | @@ -575,7 +575,7 @@ |
576 | 576 | * Get template and image versions from parsing a revision. |
577 | 577 | * @param Article $article |
578 | 578 | * @param Revision $rev |
579 | | - * @returns array( templateIds, fileSHA1Keys ) |
| 579 | + * @return array( templateIds, fileSHA1Keys ) |
580 | 580 | * templateIds like ParserOutput->mTemplateIds |
581 | 581 | * fileSHA1Keys like ParserOutput->mImageTimeKeys |
582 | 582 | */ |
Index: trunk/extensions/FlaggedRevs/business/PageStabilityForm.php |
— | — | @@ -224,7 +224,7 @@ |
225 | 225 | $changed = FlaggedPageConfig::setStabilitySettings( $this->page, $this->getNewConfig() ); |
226 | 226 | # Log if this actually changed anything... |
227 | 227 | if ( $changed ) { |
228 | | - $article = new FlaggedArticle( $this->page ); |
| 228 | + $article = new FlaggedPage( $this->page ); |
229 | 229 | if ( FlaggedRevs::useOnlyIfProtected() ) { |
230 | 230 | # Config may have changed to allow stable versions, so refresh |
231 | 231 | # the tracking table to account for any hidden reviewed versions... |
— | — | @@ -268,7 +268,7 @@ |
269 | 269 | * (b) Add a null edit like the log entry |
270 | 270 | * @return Revision |
271 | 271 | */ |
272 | | - protected function updateLogsAndHistory( FlaggedArticle $article ) { |
| 272 | + protected function updateLogsAndHistory( FlaggedPage $article ) { |
273 | 273 | global $wgContLang; |
274 | 274 | $newConfig = $this->getNewConfig(); |
275 | 275 | $oldConfig = $this->getOldConfig(); |
— | — | @@ -312,7 +312,7 @@ |
313 | 313 | |
314 | 314 | /* |
315 | 315 | * Get current stability config array |
316 | | - * @return Array |
| 316 | + * @return array |
317 | 317 | */ |
318 | 318 | public function getOldConfig() { |
319 | 319 | if ( $this->getState() == self::FORM_UNREADY ) { |
— | — | @@ -326,7 +326,7 @@ |
327 | 327 | |
328 | 328 | /* |
329 | 329 | * Get proposed stability config array |
330 | | - * @return Array |
| 330 | + * @return array |
331 | 331 | */ |
332 | 332 | public function getNewConfig() { |
333 | 333 | return array( |
Index: trunk/extensions/FlaggedRevs/FlaggedRevision.php |
— | — | @@ -327,7 +327,7 @@ |
328 | 328 | |
329 | 329 | /** |
330 | 330 | * Get select fields for FlaggedRevision DB row (flaggedrevs/revision tables) |
331 | | - * @return Array |
| 331 | + * @return array |
332 | 332 | */ |
333 | 333 | public static function selectFields() { |
334 | 334 | return array_merge( |
— | — | @@ -418,7 +418,7 @@ |
419 | 419 | } |
420 | 420 | |
421 | 421 | /** |
422 | | - * @return Array tag metadata |
| 422 | + * @return array tag metadata |
423 | 423 | */ |
424 | 424 | public function getTags() { |
425 | 425 | return $this->mTags; |
— | — | @@ -459,7 +459,7 @@ |
460 | 460 | /** |
461 | 461 | * Get original template versions at time of review |
462 | 462 | * @param int $flags FR_MASTER |
463 | | - * @return Array template versions (ns -> dbKey -> rev Id) |
| 463 | + * @return array template versions (ns -> dbKey -> rev Id) |
464 | 464 | * Note: 0 used for template rev Id if it didn't exist |
465 | 465 | */ |
466 | 466 | public function getTemplateVersions( $flags = 0 ) { |
— | — | @@ -485,7 +485,7 @@ |
486 | 486 | /** |
487 | 487 | * Get original template versions at time of review |
488 | 488 | * @param int $flags FR_MASTER |
489 | | - * @return Array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) ) |
| 489 | + * @return array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) ) |
490 | 490 | * Note: false used for file timestamp/sha1 if it didn't exist |
491 | 491 | */ |
492 | 492 | public function getFileVersions( $flags = 0 ) { |
— | — | @@ -516,7 +516,7 @@ |
517 | 517 | /** |
518 | 518 | * Get the current stable version of the templates used at time of review |
519 | 519 | * @param int $flags FR_MASTER |
520 | | - * @return Array template versions (ns -> dbKey -> rev Id) |
| 520 | + * @return array template versions (ns -> dbKey -> rev Id) |
521 | 521 | * Note: 0 used for template rev Id if it doesn't exist |
522 | 522 | */ |
523 | 523 | public function getStableTemplateVersions( $flags = 0 ) { |
— | — | @@ -550,7 +550,7 @@ |
551 | 551 | /** |
552 | 552 | * Get the current stable version of the files used at time of review |
553 | 553 | * @param int $flags FR_MASTER |
554 | | - * @return Array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) ) |
| 554 | + * @return array file versions (dbKey => array('time' => MW timestamp,'sha1' => sha1) ) |
555 | 555 | * Note: false used for file timestamp/sha1 if it didn't exist |
556 | 556 | */ |
557 | 557 | public function getStableFileVersions( $flags = 0 ) { |
— | — | @@ -598,7 +598,7 @@ |
599 | 599 | * (b) Current template exists and the "version used" was non-existing (created) |
600 | 600 | * (c) Current template doesn't exist and the "version used" existed (deleted) |
601 | 601 | * |
602 | | - * @return Array of (template title, rev ID in reviewed version) tuples |
| 602 | + * @return array of (template title, rev ID in reviewed version) tuples |
603 | 603 | */ |
604 | 604 | public function findPendingTemplateChanges() { |
605 | 605 | if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) { |
— | — | @@ -668,7 +668,7 @@ |
669 | 669 | * (c) Current file doesn't exist and the "version used" existed (deleted) |
670 | 670 | * |
671 | 671 | * @param string $noForeign Using 'noForeign' skips foreign file updates (bug 15748) |
672 | | - * @return Array of (file title, MW file timestamp in reviewed version) tuples |
| 672 | + * @return array of (file title, MW file timestamp in reviewed version) tuples |
673 | 673 | */ |
674 | 674 | public function findPendingFileChanges( $noForeign = false ) { |
675 | 675 | if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) { |
— | — | @@ -749,7 +749,7 @@ |
750 | 750 | /** |
751 | 751 | * Get flags for a revision |
752 | 752 | * @param string $tags |
753 | | - * @return Array |
| 753 | + * @return array |
754 | 754 | */ |
755 | 755 | public static function expandRevisionTags( $tags ) { |
756 | 756 | $flags = array(); |
Index: trunk/extensions/FlaggedRevs/FRDependencyUpdate.php |
— | — | @@ -76,7 +76,7 @@ |
77 | 77 | /* |
78 | 78 | * Get existing cache dependancies |
79 | 79 | * @param int $flags FR_MASTER |
80 | | - * @return Array (ns => dbKey => 1) |
| 80 | + * @return array (ns => dbKey => 1) |
81 | 81 | */ |
82 | 82 | protected function getExistingDeps( $flags = 0 ) { |
83 | 83 | $db = ( $flags & FR_MASTER ) ? |
— | — | @@ -98,7 +98,7 @@ |
99 | 99 | |
100 | 100 | /* |
101 | 101 | * Get INSERT rows for cache dependancies in $new but not in $existing |
102 | | - * @return Array |
| 102 | + * @return array |
103 | 103 | */ |
104 | 104 | protected function getDepInsertions( array $existing, array $new ) { |
105 | 105 | $arr = array(); |
— | — | @@ -157,7 +157,7 @@ |
158 | 158 | |
159 | 159 | /** |
160 | 160 | * Get an array of existing links, as a 2-D array |
161 | | - * @return Array (ns => dbKey => 1) |
| 161 | + * @return array (ns => dbKey => 1) |
162 | 162 | */ |
163 | 163 | protected function getCurrentVersionLinks() { |
164 | 164 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -178,7 +178,7 @@ |
179 | 179 | |
180 | 180 | /** |
181 | 181 | * Get an array of existing templates, as a 2-D array |
182 | | - * @return Array (ns => dbKey => 1) |
| 182 | + * @return array (ns => dbKey => 1) |
183 | 183 | */ |
184 | 184 | protected function getCurrentVersionTemplates() { |
185 | 185 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -199,7 +199,7 @@ |
200 | 200 | |
201 | 201 | /** |
202 | 202 | * Get an array of existing images, image names in the keys |
203 | | - * @return Array (dbKey => 1) |
| 203 | + * @return array (dbKey => 1) |
204 | 204 | */ |
205 | 205 | protected function getCurrentVersionImages() { |
206 | 206 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -217,7 +217,7 @@ |
218 | 218 | |
219 | 219 | /** |
220 | 220 | * Get an array of existing categories, with the name in the key and sort key in the value. |
221 | | - * @return Array (category => sortkey) |
| 221 | + * @return array (category => sortkey) |
222 | 222 | */ |
223 | 223 | protected function getCurrentVersionCategories() { |
224 | 224 | $dbr = wfGetDB( DB_SLAVE ); |
Index: trunk/extensions/FlaggedRevs/FlaggedRevs.hooks.php |
— | — | @@ -46,7 +46,7 @@ |
47 | 47 | return true; // don't double-load |
48 | 48 | } |
49 | 49 | $loadedModules = true; |
50 | | - $fa = FlaggedArticleView::globalArticleInstance(); |
| 50 | + $fa = FlaggedPageView::globalArticleInstance(); |
51 | 51 | # Try to only add to relevant pages |
52 | 52 | if ( !$fa || !$fa->isReviewable() ) { |
53 | 53 | return true; |
— | — | @@ -66,7 +66,7 @@ |
67 | 67 | $rTags = FlaggedRevs::getJSTagParams(); |
68 | 68 | $globalVars['wgFlaggedRevsParams'] = $rTags; |
69 | 69 | # Get page-specific meta-data |
70 | | - $fa = FlaggedArticleView::globalArticleInstance(); |
| 70 | + $fa = FlaggedPageView::globalArticleInstance(); |
71 | 71 | # Try to only add to relevant pages |
72 | 72 | if ( $fa && $fa->isReviewable() ) { |
73 | 73 | $frev = $fa->getStableRev(); |
— | — | @@ -108,7 +108,7 @@ |
109 | 109 | */ |
110 | 110 | public static function onBeforePageDisplay( &$out, &$skin ) { |
111 | 111 | if ( $out->isArticleRelated() ) { |
112 | | - $view = FlaggedArticleView::singleton(); |
| 112 | + $view = FlaggedPageView::singleton(); |
113 | 113 | $view->displayTag(); // show notice bar/icon in subtitle |
114 | 114 | $view->setRobotPolicy(); // set indexing policy |
115 | 115 | self::injectStyleAndJS(); // full CSS/JS |
— | — | @@ -123,13 +123,13 @@ |
124 | 124 | public static function onMediaWikiPerformAction( |
125 | 125 | $output, $article, Title $title, $user, $request |
126 | 126 | ) { |
127 | | - $fa = FlaggedArticle::getTitleInstance( $title ); |
| 127 | + $fa = FlaggedPage::getTitleInstance( $title ); |
128 | 128 | self::maybeMarkUnderReview( $fa, $request ); |
129 | 129 | return true; |
130 | 130 | } |
131 | 131 | |
132 | 132 | // Mark when an unreviewed page is being reviewed |
133 | | - protected static function maybeMarkUnderReview( FlaggedArticle $fa, WebRequest $request ) { |
| 133 | + protected static function maybeMarkUnderReview( FlaggedPage $fa, WebRequest $request ) { |
134 | 134 | global $wgUser; |
135 | 135 | if ( !$request->getInt( 'reviewing' ) && !$request->getInt( 'rcid' ) ) { |
136 | 136 | return true; // not implied by URL |
— | — | @@ -203,7 +203,7 @@ |
204 | 204 | public static function onTitleMoveComplete( |
205 | 205 | Title $otitle, Title $ntitle, $user, $pageId |
206 | 206 | ) { |
207 | | - $fa = FlaggedArticle::getTitleInstance( $ntitle ); |
| 207 | + $fa = FlaggedPage::getTitleInstance( $ntitle ); |
208 | 208 | $fa->loadFromDB( FR_MASTER ); |
209 | 209 | // Re-validate NS/config (new title may not be reviewable) |
210 | 210 | if ( $fa->isReviewable() ) { |
— | — | @@ -431,7 +431,7 @@ |
432 | 432 | if ( !FlaggedRevs::inReviewNamespace( $title ) || !$title->exists() ) { |
433 | 433 | return true; // extra short-circuit |
434 | 434 | } |
435 | | - $flaggedArticle = FlaggedArticle::getTitleInstance( $title ); |
| 435 | + $flaggedArticle = FlaggedPage::getTitleInstance( $title ); |
436 | 436 | # If the draft shows by default anyway, nothing to do... |
437 | 437 | if ( !$flaggedArticle->isStableShownByDefault() ) { |
438 | 438 | return true; |
— | — | @@ -444,7 +444,7 @@ |
445 | 445 | } |
446 | 446 | # Don't let users patrol pages not in $wgFlaggedRevsPatrolNamespaces |
447 | 447 | } else if ( $action === 'patrol' || $action === 'autopatrol' ) { |
448 | | - $flaggedArticle = FlaggedArticle::getTitleInstance( $title ); |
| 448 | + $flaggedArticle = FlaggedPage::getTitleInstance( $title ); |
449 | 449 | # For a page to be patrollable it must not be reviewable. |
450 | 450 | # Note: normally, edits to non-reviewable, non-patrollable, pages are |
451 | 451 | # silently marked patrolled automatically. With $wgUseNPPatrol on, the |
— | — | @@ -456,7 +456,7 @@ |
457 | 457 | # Enforce autoreview/review restrictions |
458 | 458 | } else if ( $action === 'autoreview' || $action === 'review' ) { |
459 | 459 | # Get autoreview restriction settings... |
460 | | - $fa = FlaggedArticle::getTitleInstance( $title ); |
| 460 | + $fa = FlaggedPage::getTitleInstance( $title ); |
461 | 461 | $config = $fa->getStabilitySettings(); |
462 | 462 | # Convert Sysop -> protect |
463 | 463 | $right = ( $config['autoreview'] === 'sysop' ) ? |
— | — | @@ -485,7 +485,7 @@ |
486 | 486 | ) { |
487 | 487 | global $wgRequest; |
488 | 488 | # Edit must be non-null, to a reviewable page, with $user set |
489 | | - $fa = FlaggedArticle::getArticleInstance( $article ); |
| 489 | + $fa = FlaggedPage::getArticleInstance( $article ); |
490 | 490 | $fa->loadFromDB( FR_MASTER ); |
491 | 491 | if ( !$rev || !$user || !$fa->isReviewable() ) { |
492 | 492 | return true; |
— | — | @@ -661,7 +661,7 @@ |
662 | 662 | if ( !$user || $rev !== null ) { |
663 | 663 | return true; |
664 | 664 | } |
665 | | - $fa = FlaggedArticle::getArticleInstance( $article ); |
| 665 | + $fa = FlaggedPage::getArticleInstance( $article ); |
666 | 666 | $fa->loadFromDB( FR_MASTER ); |
667 | 667 | if ( !$fa->isReviewable() ) { |
668 | 668 | return true; // page is not reviewable |
— | — | @@ -726,7 +726,7 @@ |
727 | 727 | if ( empty( $rc->mAttribs['rc_this_oldid'] ) ) { |
728 | 728 | return true; |
729 | 729 | } |
730 | | - $fa = FlaggedArticle::getTitleInstance( $rc->getTitle() ); |
| 730 | + $fa = FlaggedPage::getTitleInstance( $rc->getTitle() ); |
731 | 731 | $fa->loadFromDB( FR_MASTER ); |
732 | 732 | // Is the page reviewable? |
733 | 733 | if ( $fa->isReviewable() ) { |
— | — | @@ -821,7 +821,7 @@ |
822 | 822 | * @param int $spacingReq days apart (of edit points) |
823 | 823 | * @param int $pointsReq number of edit points |
824 | 824 | * @param User $user |
825 | | - * @returns mixed (true if passed, int seconds on failure) |
| 825 | + * @return mixed (true if passed, int seconds on failure) |
826 | 826 | */ |
827 | 827 | protected static function editSpacingCheck( $spacingReq, $pointsReq, $user ) { |
828 | 828 | $benchmarks = 0; // actual edit points |
— | — | @@ -1197,7 +1197,7 @@ |
1198 | 1198 | } |
1199 | 1199 | |
1200 | 1200 | public static function onImagePageFindFile( $imagePage, &$normalFile, &$displayFile ) { |
1201 | | - $view = FlaggedArticleView::singleton(); |
| 1201 | + $view = FlaggedPageView::singleton(); |
1202 | 1202 | $view->imagePageFindFile( $normalFile, $displayFile ); |
1203 | 1203 | return true; |
1204 | 1204 | } |
— | — | @@ -1210,8 +1210,8 @@ |
1211 | 1211 | return true; |
1212 | 1212 | } |
1213 | 1213 | // Note: $wgArticle sometimes not set here |
1214 | | - if ( FlaggedArticleView::globalArticleInstance() != null ) { |
1215 | | - $view = FlaggedArticleView::singleton(); |
| 1214 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 1215 | + $view = FlaggedPageView::singleton(); |
1216 | 1216 | $view->setActionTabs( $skin, $contentActions ); |
1217 | 1217 | $view->setViewTabs( $skin, $contentActions, 'flat' ); |
1218 | 1218 | } |
— | — | @@ -1221,8 +1221,8 @@ |
1222 | 1222 | // Vector et al: $links is all the tabs (2 levels) |
1223 | 1223 | public static function onSkinTemplateNavigation( Skin $skin, array &$links ) { |
1224 | 1224 | // Note: $wgArticle sometimes not set here |
1225 | | - if ( FlaggedArticleView::globalArticleInstance() != null ) { |
1226 | | - $view = FlaggedArticleView::singleton(); |
| 1225 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 1226 | + $view = FlaggedPageView::singleton(); |
1227 | 1227 | $view->setActionTabs( $skin, $links['actions'] ); |
1228 | 1228 | $view->setViewTabs( $skin, $links['views'], 'nav' ); |
1229 | 1229 | } |
— | — | @@ -1230,7 +1230,7 @@ |
1231 | 1231 | } |
1232 | 1232 | |
1233 | 1233 | public static function onArticleViewHeader( &$article, &$outputDone, &$useParserCache ) { |
1234 | | - $view = FlaggedArticleView::singleton(); |
| 1234 | + $view = FlaggedPageView::singleton(); |
1235 | 1235 | $view->addStableLink( $outputDone, $useParserCache ); |
1236 | 1236 | $view->setPageContent( $outputDone, $useParserCache ); |
1237 | 1237 | return true; |
— | — | @@ -1240,7 +1240,7 @@ |
1241 | 1241 | Title $title, WebRequest $request, &$ignoreRedirect, &$target, Article &$article |
1242 | 1242 | ) { |
1243 | 1243 | global $wgMemc, $wgParserCacheExpireTime; |
1244 | | - $fa = FlaggedArticle::getTitleInstance( $title ); // on $wgTitle |
| 1244 | + $fa = FlaggedPage::getTitleInstance( $title ); // on $wgTitle |
1245 | 1245 | if ( !$fa->isReviewable() ) { |
1246 | 1246 | return true; // nothing to do |
1247 | 1247 | } |
— | — | @@ -1250,7 +1250,7 @@ |
1251 | 1251 | return true; |
1252 | 1252 | } |
1253 | 1253 | $srev = $fa->getStableRev(); |
1254 | | - $view = FlaggedArticleView::singleton(); |
| 1254 | + $view = FlaggedPageView::singleton(); |
1255 | 1255 | # Check if we are viewing an unsynced stable version... |
1256 | 1256 | if ( $srev && $view->showingStable() && $srev->getRevId() != $article->getLatest() ) { |
1257 | 1257 | # Check the stable redirect properties from the cache... |
— | — | @@ -1282,31 +1282,31 @@ |
1283 | 1283 | } |
1284 | 1284 | |
1285 | 1285 | public static function addToEditView( &$editPage ) { |
1286 | | - $view = FlaggedArticleView::singleton(); |
| 1286 | + $view = FlaggedPageView::singleton(); |
1287 | 1287 | $view->addToEditView( $editPage ); |
1288 | 1288 | return true; |
1289 | 1289 | } |
1290 | 1290 | |
1291 | 1291 | public static function onBeforeEditButtons( &$editPage, &$buttons ) { |
1292 | | - $view = FlaggedArticleView::singleton(); |
| 1292 | + $view = FlaggedPageView::singleton(); |
1293 | 1293 | $view->changeSaveButton( $editPage, $buttons ); |
1294 | 1294 | return true; |
1295 | 1295 | } |
1296 | 1296 | |
1297 | 1297 | public static function onNoSuchSection( &$editPage, &$s ) { |
1298 | | - $view = FlaggedArticleView::singleton(); |
| 1298 | + $view = FlaggedPageView::singleton(); |
1299 | 1299 | $view->addToNoSuchSection( $editPage, $s ); |
1300 | 1300 | return true; |
1301 | 1301 | } |
1302 | 1302 | |
1303 | 1303 | public static function addToHistView( &$article ) { |
1304 | | - $view = FlaggedArticleView::singleton(); |
| 1304 | + $view = FlaggedPageView::singleton(); |
1305 | 1305 | $view->addToHistView(); |
1306 | 1306 | return true; |
1307 | 1307 | } |
1308 | 1308 | |
1309 | 1309 | public static function onCategoryPageView( &$category ) { |
1310 | | - $view = FlaggedArticleView::singleton(); |
| 1310 | + $view = FlaggedPageView::singleton(); |
1311 | 1311 | $view->addToCategoryView(); |
1312 | 1312 | return true; |
1313 | 1313 | } |
— | — | @@ -1314,9 +1314,9 @@ |
1315 | 1315 | public static function onSkinAfterContent( &$data ) { |
1316 | 1316 | global $wgOut; |
1317 | 1317 | if ( $wgOut->isArticleRelated() |
1318 | | - && FlaggedArticleView::globalArticleInstance() != null ) |
| 1318 | + && FlaggedPageView::globalArticleInstance() != null ) |
1319 | 1319 | { |
1320 | | - $view = FlaggedArticleView::singleton(); |
| 1320 | + $view = FlaggedPageView::singleton(); |
1321 | 1321 | $view->addReviewNotes( $data ); |
1322 | 1322 | $view->addReviewForm( $data ); |
1323 | 1323 | $view->addVisibilityLink( $data ); |
— | — | @@ -1325,7 +1325,7 @@ |
1326 | 1326 | } |
1327 | 1327 | |
1328 | 1328 | public static function addToHistQuery( HistoryPager $pager, array &$queryInfo ) { |
1329 | | - $flaggedArticle = FlaggedArticle::getArticleInstance( $pager->getArticle() ); |
| 1329 | + $flaggedArticle = FlaggedPage::getArticleInstance( $pager->getArticle() ); |
1330 | 1330 | # Non-content pages cannot be validated. Stable version must exist. |
1331 | 1331 | if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
1332 | 1332 | # Highlight flaggedrevs |
— | — | @@ -1351,7 +1351,7 @@ |
1352 | 1352 | if ( !$file->isLocal() ) { |
1353 | 1353 | return true; // local files only |
1354 | 1354 | } |
1355 | | - $flaggedArticle = FlaggedArticle::getTitleInstance( $file->getTitle() ); |
| 1355 | + $flaggedArticle = FlaggedPage::getTitleInstance( $file->getTitle() ); |
1356 | 1356 | # Non-content pages cannot be validated. Stable version must exist. |
1357 | 1357 | if ( $flaggedArticle->isReviewable() && $flaggedArticle->getStableRev() ) { |
1358 | 1358 | $tables[] = 'flaggedrevs'; |
— | — | @@ -1415,7 +1415,7 @@ |
1416 | 1416 | } |
1417 | 1417 | |
1418 | 1418 | public static function addToHistLine( HistoryPager $history, $row, &$s, &$liClasses ) { |
1419 | | - $fa = FlaggedArticle::getArticleInstance( $history->getArticle() ); |
| 1419 | + $fa = FlaggedPage::getArticleInstance( $history->getArticle() ); |
1420 | 1420 | if ( !$fa->isReviewable() ) { |
1421 | 1421 | return true; // nothing to do here |
1422 | 1422 | } |
— | — | @@ -1462,7 +1462,7 @@ |
1463 | 1463 | * Make stable version link and return the css |
1464 | 1464 | * @param Title $title |
1465 | 1465 | * @param Row $row, from history page |
1466 | | - * @returns array (string,string) |
| 1466 | + * @return array (string,string) |
1467 | 1467 | */ |
1468 | 1468 | protected static function markHistoryRow( Title $title, $row ) { |
1469 | 1469 | if ( !isset( $row->fr_quality ) ) { |
— | — | @@ -1570,8 +1570,8 @@ |
1571 | 1571 | |
1572 | 1572 | public static function injectPostEditURLParams( $article, &$sectionAnchor, &$extraQuery ) { |
1573 | 1573 | // Note: $wgArticle sometimes not set here |
1574 | | - if ( FlaggedArticleView::globalArticleInstance() != null ) { |
1575 | | - $view = FlaggedArticleView::singleton(); |
| 1574 | + if ( FlaggedPageView::globalArticleInstance() != null ) { |
| 1575 | + $view = FlaggedPageView::singleton(); |
1576 | 1576 | $view->injectPostEditURLParams( $sectionAnchor, $extraQuery ); |
1577 | 1577 | } |
1578 | 1578 | return true; |
— | — | @@ -1591,33 +1591,33 @@ |
1592 | 1592 | |
1593 | 1593 | public static function onDiffViewHeader( $diff, $oldRev, $newRev ) { |
1594 | 1594 | self::injectStyleAndJS(); |
1595 | | - $view = FlaggedArticleView::singleton(); |
| 1595 | + $view = FlaggedPageView::singleton(); |
1596 | 1596 | $view->setViewFlags( $diff, $oldRev, $newRev ); |
1597 | 1597 | $view->addToDiffView( $diff, $oldRev, $newRev ); |
1598 | 1598 | return true; |
1599 | 1599 | } |
1600 | 1600 | |
1601 | 1601 | /* |
1602 | | - * If an article is reviewable, get custom article contents from the FlaggedArticleView |
| 1602 | + * If an article is reviewable, get custom article contents from the FlaggedPageView |
1603 | 1603 | */ |
1604 | 1604 | public static function onArticleContentOnDiff( $diffEngine, $out ) { |
1605 | | - $fa = FlaggedArticle::getTitleInstance( $out->getTitle() ); |
| 1605 | + $fa = FlaggedPage::getTitleInstance( $out->getTitle() ); |
1606 | 1606 | if ( !$fa->isReviewable() ) { |
1607 | 1607 | return true; // nothing to do |
1608 | 1608 | } |
1609 | | - $view = FlaggedArticleView::singleton(); |
| 1609 | + $view = FlaggedPageView::singleton(); |
1610 | 1610 | $view->addCustomContentHtml( $out, $diffEngine->getNewid() ); |
1611 | 1611 | return false; |
1612 | 1612 | } |
1613 | 1613 | |
1614 | 1614 | public static function addRevisionIDField( $editPage, $out ) { |
1615 | | - $view = FlaggedArticleView::singleton(); |
| 1615 | + $view = FlaggedPageView::singleton(); |
1616 | 1616 | $view->addRevisionIDField( $editPage, $out ); |
1617 | 1617 | return true; |
1618 | 1618 | } |
1619 | 1619 | |
1620 | 1620 | public static function addReviewCheck( $editPage, &$checkboxes, &$tabindex ) { |
1621 | | - $view = FlaggedArticleView::singleton(); |
| 1621 | + $view = FlaggedPageView::singleton(); |
1622 | 1622 | $view->addReviewCheck( $editPage, $checkboxes, $tabindex ); |
1623 | 1623 | return true; |
1624 | 1624 | } |
Index: trunk/extensions/FlaggedRevs/FlaggedPageConfig.php |
— | — | @@ -7,7 +7,7 @@ |
8 | 8 | * Get visibility settings/restrictions for a page |
9 | 9 | * @param Title $title, page title |
10 | 10 | * @param int $flags, FR_MASTER |
11 | | - * @returns array (associative) (select,override,autoreview,expiry) |
| 11 | + * @return array (associative) (select,override,autoreview,expiry) |
12 | 12 | */ |
13 | 13 | public static function getStabilitySettings( Title $title, $flags = 0 ) { |
14 | 14 | $db = ( $flags & FR_MASTER ) ? |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | } |
23 | 23 | |
24 | 24 | /** |
25 | | - * @return Array basic select fields for FlaggedPageConfig DB row |
| 25 | + * @return array basic select fields for FlaggedPageConfig DB row |
26 | 26 | */ |
27 | 27 | public static function selectFields() { |
28 | 28 | return array( 'fpc_override', 'fpc_level', 'fpc_expiry' ); |
— | — | @@ -82,7 +82,7 @@ |
83 | 83 | /** |
84 | 84 | * Set the stability configuration settings for a page |
85 | 85 | * @param Title $title |
86 | | - * @param Array $config |
| 86 | + * @param array $config |
87 | 87 | * @return bool Row changed |
88 | 88 | */ |
89 | 89 | public static function setStabilitySettings( Title $title, array $config ) { |
— | — | @@ -131,7 +131,7 @@ |
132 | 132 | /** |
133 | 133 | * Does this config equal the default settings? |
134 | 134 | * @param array $config |
135 | | - * @returns bool |
| 135 | + * @return bool |
136 | 136 | */ |
137 | 137 | public static function configIsReset( array $config ) { |
138 | 138 | if ( FlaggedRevs::useOnlyIfProtected() ) { |
— | — | @@ -145,7 +145,7 @@ |
146 | 146 | /** |
147 | 147 | * Find what protection level a config is in |
148 | 148 | * @param array $config |
149 | | - * @returns string |
| 149 | + * @return string |
150 | 150 | */ |
151 | 151 | public static function getProtectionLevel( array $config ) { |
152 | 152 | if ( !FlaggedRevs::useProtectionLevels() ) { |
Index: trunk/extensions/FlaggedRevs/api/actions/ApiReview.php |
— | — | @@ -66,7 +66,7 @@ |
67 | 67 | $form->setDim( $tag, (int)$params['flag_' . $tag] ); |
68 | 68 | } |
69 | 69 | if ( $form->getAction() === 'approve' ) { |
70 | | - $article = new FlaggedArticle( $title ); |
| 70 | + $article = new FlaggedPage( $title ); |
71 | 71 | // Now get the template and image parameters needed |
72 | 72 | list( $templateIds, $fileTimeKeys ) = |
73 | 73 | RevisionReviewForm::currentIncludeVersions( $article, $rev ); |
Index: trunk/extensions/FlaggedRevs/FRUserActivity.php |
— | — | @@ -42,7 +42,7 @@ |
43 | 43 | /* |
44 | 44 | * Get who is currently reviewing a page |
45 | 45 | * @param int $pageId |
46 | | - * @return Array (username or null, MW timestamp or null) |
| 46 | + * @return array (username or null, MW timestamp or null) |
47 | 47 | */ |
48 | 48 | public static function getUserReviewingPage( $pageId ) { |
49 | 49 | global $wgMemc; |
— | — | @@ -109,7 +109,7 @@ |
110 | 110 | * Get who is currently reviewing a diff |
111 | 111 | * @param int $oldId |
112 | 112 | * @param int $newId |
113 | | - * @return Array (username or null, MW timestamp or null) |
| 113 | + * @return array (username or null, MW timestamp or null) |
114 | 114 | */ |
115 | 115 | public static function getUserReviewingDiff( $oldId, $newId ) { |
116 | 116 | global $wgMemc; |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedArticleView.php |
— | — | @@ -1,1845 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Class representing a web view of a MediaWiki page |
5 | | - */ |
6 | | -class FlaggedArticleView { |
7 | | - protected $article = null; |
8 | | - |
9 | | - protected $diffRevs = null; // assoc array of old and new Revisions for diffs |
10 | | - protected $isReviewableDiff = false; |
11 | | - protected $isDiffFromStable = false; |
12 | | - protected $isMultiPageDiff = false; |
13 | | - protected $reviewNotice = ''; |
14 | | - protected $reviewNotes = ''; |
15 | | - protected $diffNoticeBox = ''; |
16 | | - protected $reviewFormRev = false; |
17 | | - |
18 | | - protected $loaded = false; |
19 | | - |
20 | | - protected static $instance = null; |
21 | | - |
22 | | - /* |
23 | | - * Get the FlaggedArticleView for this request |
24 | | - */ |
25 | | - public static function singleton() { |
26 | | - if ( self::$instance == null ) { |
27 | | - self::$instance = new self(); |
28 | | - } |
29 | | - return self::$instance; |
30 | | - } |
31 | | - protected function __construct() { } |
32 | | - protected function __clone() { } |
33 | | - |
34 | | - /* |
35 | | - * Clear the FlaggedArticleView for this request. |
36 | | - * Only needed when page redirection changes the environment. |
37 | | - */ |
38 | | - public function clear() { |
39 | | - self::$instance = null; |
40 | | - } |
41 | | - |
42 | | - /* |
43 | | - * Load the global FlaggedArticle instance |
44 | | - */ |
45 | | - protected function load() { |
46 | | - if ( !$this->loaded ) { |
47 | | - $this->loaded = true; |
48 | | - $this->article = self::globalArticleInstance(); |
49 | | - if ( $this->article == null ) { |
50 | | - throw new MWException( 'FlaggedArticleView has no context article!' ); |
51 | | - } |
52 | | - } |
53 | | - } |
54 | | - |
55 | | - /** |
56 | | - * Get the FlaggedArticle instance associated with $wgArticle/$wgTitle, |
57 | | - * or false if there isn't such a title |
58 | | - */ |
59 | | - public static function globalArticleInstance() { |
60 | | - global $wgTitle; |
61 | | - if ( !empty( $wgTitle ) ) { |
62 | | - return FlaggedArticle::getTitleInstance( $wgTitle ); |
63 | | - } |
64 | | - return null; |
65 | | - } |
66 | | - |
67 | | - /** |
68 | | - * Is this web response for a request to view a page where both: |
69 | | - * (a) no specific page version was requested via URL params |
70 | | - * (b) a stable version exists and is to be displayed |
71 | | - * This factors in site/page config, user preferences, and web request params. |
72 | | - * @returns bool |
73 | | - */ |
74 | | - protected function showingStableAsDefault() { |
75 | | - global $wgUser, $wgRequest; |
76 | | - $this->load(); |
77 | | - # This only applies to viewing the default version of pages... |
78 | | - if ( !$this->isDefaultPageView( $wgRequest ) ) { |
79 | | - return false; |
80 | | - # ...and the page must be reviewable and have a stable version |
81 | | - } elseif ( !$this->article->getStableRev() ) { |
82 | | - return false; |
83 | | - } |
84 | | - # Check user preferences ("show stable by default?") |
85 | | - if ( $wgUser->getOption( 'flaggedrevsstable' ) ) { |
86 | | - return true; |
87 | | - } |
88 | | - # Viewer may be in a group that sees the draft by default |
89 | | - if ( $this->userViewsDraftByDefault( $wgUser ) ) { |
90 | | - return false; |
91 | | - } |
92 | | - # Does the stable version override the draft? |
93 | | - $config = $this->article->getStabilitySettings(); |
94 | | - return (bool)$config['override']; |
95 | | - } |
96 | | - |
97 | | - /** |
98 | | - * Is this web response for a request to view a page where both: |
99 | | - * (a) the stable version of a page was requested (?stable=1) |
100 | | - * (b) the stable version exists and is to be displayed |
101 | | - * @returns bool |
102 | | - */ |
103 | | - protected function showingStableByRequest() { |
104 | | - global $wgRequest; |
105 | | - $this->load(); |
106 | | - # Are we explicity requesting the stable version? |
107 | | - if ( $wgRequest->getIntOrNull( 'stable' ) === 1 ) { |
108 | | - # This only applies to viewing a version of the page... |
109 | | - if ( !$this->isPageView( $wgRequest ) ) { |
110 | | - return false; |
111 | | - # ...with no version parameters other than ?stable=1... |
112 | | - } elseif ( $wgRequest->getVal( 'oldid' ) || $wgRequest->getVal( 'stableid' ) ) { |
113 | | - return false; // over-determined |
114 | | - # ...and the page must be reviewable and have a stable version |
115 | | - } elseif ( !$this->article->getStableRev() ) { |
116 | | - return false; |
117 | | - } |
118 | | - return true; // show stable version |
119 | | - } |
120 | | - return false; |
121 | | - } |
122 | | - |
123 | | - /** |
124 | | - * Is this web response for a request to view a page |
125 | | - * where a stable version exists and is to be displayed |
126 | | - * @returns bool |
127 | | - */ |
128 | | - public function showingStable() { |
129 | | - return $this->showingStableByRequest() || $this->showingStableAsDefault(); |
130 | | - } |
131 | | - |
132 | | - /** |
133 | | - * Should this be using a simple icon-based UI? |
134 | | - * Check the user's preferences first, using the site settings as the default. |
135 | | - * @returns bool |
136 | | - */ |
137 | | - public function useSimpleUI() { |
138 | | - global $wgUser, $wgSimpleFlaggedRevsUI; |
139 | | - return $wgUser->getOption( 'flaggedrevssimpleui', intval( $wgSimpleFlaggedRevsUI ) ); |
140 | | - } |
141 | | - |
142 | | - /** |
143 | | - * Should this user see the draft revision of pages by default? |
144 | | - * @param $user User |
145 | | - * @returns bool |
146 | | - */ |
147 | | - protected function userViewsDraftByDefault( $user ) { |
148 | | - global $wgFlaggedRevsExceptions; |
149 | | - # Check user preferences ("show stable by default?") |
150 | | - if ( $user->getOption( 'flaggedrevsstable' ) ) { |
151 | | - return false; |
152 | | - } |
153 | | - # Viewer sees current by default (editors, insiders, ect...) ? |
154 | | - foreach ( $wgFlaggedRevsExceptions as $group ) { |
155 | | - if ( $group == 'user' ) { |
156 | | - if ( $user->getId() ) { |
157 | | - return true; |
158 | | - } |
159 | | - } elseif ( in_array( $group, $user->getGroups() ) ) { |
160 | | - return true; |
161 | | - } |
162 | | - } |
163 | | - return false; |
164 | | - } |
165 | | - |
166 | | - /** |
167 | | - * Is this a view page action (including diffs)? |
168 | | - * @param $request WebRequest |
169 | | - * @returns bool |
170 | | - */ |
171 | | - protected function isPageViewOrDiff( WebRequest $request ) { |
172 | | - global $mediaWiki; |
173 | | - $action = isset( $mediaWiki ) |
174 | | - ? $mediaWiki->getAction( $request ) |
175 | | - : $request->getVal( 'action', 'view' ); // cli |
176 | | - return self::isViewAction( $action ); |
177 | | - } |
178 | | - |
179 | | - /** |
180 | | - * Is this a view page action (not including diffs)? |
181 | | - * @param $request WebRequest |
182 | | - * @returns bool |
183 | | - */ |
184 | | - protected function isPageView( WebRequest $request ) { |
185 | | - return $this->isPageViewOrDiff( $request ) |
186 | | - && $request->getVal( 'diff' ) === null; |
187 | | - } |
188 | | - |
189 | | - /** |
190 | | - * Is this a web request to just *view* the *default* version of a page? |
191 | | - * @param $request WebRequest |
192 | | - * @returns bool |
193 | | - */ |
194 | | - protected function isDefaultPageView( WebRequest $request ) { |
195 | | - global $mediaWiki; |
196 | | - $action = isset( $mediaWiki ) |
197 | | - ? $mediaWiki->getAction( $request ) |
198 | | - : $request->getVal( 'action', 'view' ); // cli |
199 | | - return ( self::isViewAction( $action ) |
200 | | - && $request->getVal( 'oldid' ) === null |
201 | | - && $request->getVal( 'stable' ) === null |
202 | | - && $request->getVal( 'stableid' ) === null |
203 | | - && $request->getVal( 'diff' ) === null |
204 | | - ); |
205 | | - } |
206 | | - |
207 | | - /** |
208 | | - * Is this a view page action? |
209 | | - * @param $action string from MediaWiki::getAction() |
210 | | - * @returns bool |
211 | | - */ |
212 | | - protected static function isViewAction( $action ) { |
213 | | - return ( $action == 'view' || $action == 'purge' || $action == 'render' ); |
214 | | - } |
215 | | - |
216 | | - /** |
217 | | - * Output review notice |
218 | | - */ |
219 | | - public function displayTag() { |
220 | | - global $wgOut; |
221 | | - $this->load(); |
222 | | - // Sanity check that this is a reviewable page |
223 | | - if ( $this->article->isReviewable() ) { |
224 | | - $wgOut->appendSubtitle( $this->reviewNotice ); |
225 | | - } |
226 | | - return true; |
227 | | - } |
228 | | - |
229 | | - /** |
230 | | - * Add a stable link when viewing old versions of an article that |
231 | | - * have been reviewed. (e.g. for &oldid=x urls) |
232 | | - */ |
233 | | - public function addStableLink() { |
234 | | - global $wgRequest, $wgOut, $wgLang; |
235 | | - $this->load(); |
236 | | - if ( !$this->article->isReviewable() || !$wgRequest->getVal( 'oldid' ) ) { |
237 | | - return true; |
238 | | - } |
239 | | - # We may have nav links like "direction=prev&oldid=x" |
240 | | - $revID = $this->article->getOldIDFromRequest(); |
241 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID ); |
242 | | - # Give a notice if this rev ID corresponds to a reviewed version... |
243 | | - if ( $frev ) { |
244 | | - $time = $wgLang->date( $frev->getTimestamp(), true ); |
245 | | - $flags = $frev->getTags(); |
246 | | - $quality = FlaggedRevs::isQuality( $flags ); |
247 | | - $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source'; |
248 | | - $tag = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time ); |
249 | | - # Hide clutter |
250 | | - if ( !$this->useSimpleUI() && !empty( $flags ) ) { |
251 | | - $tag .= FlaggedRevsXML::ratingToggle() . |
252 | | - "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
253 | | - wfMsgHtml( 'revreview-oldrating' ) . |
254 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
255 | | - } |
256 | | - $css = 'flaggedrevs_notice plainlinks noprint'; |
257 | | - $tag = "<div id='mw-fr-revisiontag-old' class='$css'>$tag</div>"; |
258 | | - $wgOut->addHTML( $tag ); |
259 | | - } |
260 | | - return true; |
261 | | - } |
262 | | - |
263 | | - /** |
264 | | - * @returns mixed int/false/null |
265 | | - */ |
266 | | - protected function getRequestedStableId() { |
267 | | - global $wgRequest; |
268 | | - $reqId = $wgRequest->getVal( 'stableid' ); |
269 | | - if ( $reqId === "best" ) { |
270 | | - $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article ); |
271 | | - } |
272 | | - return $reqId; |
273 | | - } |
274 | | - |
275 | | - /** |
276 | | - * Replaces a page with the last stable version if possible |
277 | | - * Adds stable version status/info tags and notes |
278 | | - * Adds a quick review form on the bottom if needed |
279 | | - */ |
280 | | - public function setPageContent( &$outputDone, &$useParserCache ) { |
281 | | - global $wgRequest, $wgOut, $wgContLang; |
282 | | - $this->load(); |
283 | | - # Only trigger on page views with no oldid=x param |
284 | | - if ( !$this->isPageView( $wgRequest ) || $wgRequest->getVal( 'oldid' ) ) { |
285 | | - return true; |
286 | | - # Only trigger for reviewable pages that exist |
287 | | - } elseif ( !$this->article->exists() || !$this->article->isReviewable() ) { |
288 | | - return true; |
289 | | - } |
290 | | - $tag = ''; |
291 | | - $old = $stable = false; |
292 | | - # Check the newest stable version. |
293 | | - $srev = $this->article->getStableRev(); |
294 | | - $stableId = $srev ? $srev->getRevId() : 0; |
295 | | - $frev = $srev; // $frev is the revision we are looking at |
296 | | - # Check for any explicitly requested reviewed version (stableid=X)... |
297 | | - $reqId = $this->getRequestedStableId(); |
298 | | - if ( $reqId ) { |
299 | | - if ( !$stableId ) { |
300 | | - $reqId = false; // must be invalid |
301 | | - # Treat requesting the stable version by ID as &stable=1 |
302 | | - } else if ( $reqId != $stableId ) { |
303 | | - $old = true; // old reviewed version requested by ID |
304 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId ); |
305 | | - if ( !$frev ) { |
306 | | - $reqId = false; // invalid ID given |
307 | | - } |
308 | | - } else { |
309 | | - $stable = true; // stable version requested by ID |
310 | | - } |
311 | | - } |
312 | | - // $reqId is null if nothing requested, false if invalid |
313 | | - if ( $reqId === false ) { |
314 | | - $wgOut->addWikiText( wfMsg( 'revreview-invalid' ) ); |
315 | | - $wgOut->returnToMain( false, $this->article->getTitle() ); |
316 | | - # Tell MW that parser output is done |
317 | | - $outputDone = true; |
318 | | - $useParserCache = false; |
319 | | - return true; |
320 | | - } |
321 | | - // Is the page config altered? |
322 | | - $prot = FlaggedRevsXML::lockStatusIcon( $this->article ); |
323 | | - // Is there no stable version? |
324 | | - if ( !$frev ) { |
325 | | - # Add "no reviewed version" tag, but not for printable output |
326 | | - $this->showUnreviewedPage( $tag, $prot ); |
327 | | - return true; |
328 | | - } |
329 | | - # Get flags and date |
330 | | - $flags = $frev->getTags(); |
331 | | - # Get quality level |
332 | | - $quality = FlaggedRevs::isQuality( $flags ); |
333 | | - $pristine = FlaggedRevs::isPristine( $flags ); |
334 | | - // Looking at some specific old stable revision ("&stableid=x") |
335 | | - // set to override given the relevant conditions. If the user is |
336 | | - // requesting the stable revision ("&stableid=x"), defer to override |
337 | | - // behavior below, since it is the same as ("&stable=1"). |
338 | | - if ( $old ) { |
339 | | - $this->showOldReviewedVersion( $srev, $frev, $tag, $prot ); |
340 | | - $outputDone = true; # Tell MW that parser output is done |
341 | | - $useParserCache = false; |
342 | | - // Stable version requested by ID or relevant conditions met to |
343 | | - // to override page view with the stable version. |
344 | | - } else if ( $stable || $this->showingStable() ) { |
345 | | - $this->showStableVersion( $srev, $tag, $prot ); |
346 | | - $outputDone = true; # Tell MW that parser output is done |
347 | | - $useParserCache = false; |
348 | | - // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not |
349 | | - // set to override given the relevant conditions (like &stable=0) or there |
350 | | - // is no stable version. |
351 | | - } else { |
352 | | - $this->showDraftVersion( $srev, $tag, $prot ); |
353 | | - } |
354 | | - $encJS = ''; // JS events to use |
355 | | - # Some checks for which tag CSS to use |
356 | | - if ( $this->useSimpleUI() ) { |
357 | | - $tagClass = 'flaggedrevs_short'; |
358 | | - # Collapse the box details on mouseOut |
359 | | - $encJS .= ' onmouseout="FlaggedRevs.onBoxMouseOut(event)"'; |
360 | | - } elseif ( $pristine ) { |
361 | | - $tagClass = 'flaggedrevs_pristine'; |
362 | | - } elseif ( $quality ) { |
363 | | - $tagClass = 'flaggedrevs_quality'; |
364 | | - } else { |
365 | | - $tagClass = 'flaggedrevs_basic'; |
366 | | - } |
367 | | - # Wrap tag contents in a div |
368 | | - if ( $tag != '' ) { |
369 | | - $rtl = $wgContLang->isRTL() ? " rtl" : ""; // RTL langauges |
370 | | - $css = "{$tagClass}{$rtl} plainlinks noprint"; |
371 | | - $notice = "<div id=\"mw-fr-revisiontag\" class=\"{$css}\"{$encJS}>{$tag}</div>\n"; |
372 | | - $this->reviewNotice .= $notice; |
373 | | - } |
374 | | - return true; |
375 | | - } |
376 | | - |
377 | | - /** |
378 | | - * If the page has a stable version and it shows by default, |
379 | | - * tell search crawlers to index only that version of the page. |
380 | | - * Also index the draft as well if they are synced (bug 27173). |
381 | | - * However, any URL with ?stableid=x should not be indexed (as with ?oldid=x). |
382 | | - */ |
383 | | - public function setRobotPolicy() { |
384 | | - global $wgRequest, $wgOut; |
385 | | - if ( $this->article->getStableRev() && $this->article->isStableShownByDefault() ) { |
386 | | - if ( $this->showingStable() ) { |
387 | | - return; // stable version - index this |
388 | | - } elseif ( !$wgRequest->getVal( 'stableid' ) |
389 | | - && $wgOut->getRevisionId() == $this->article->getStable() |
390 | | - && $this->article->stableVersionIsSynced() ) |
391 | | - { |
392 | | - return; // draft that is synced with the stable version - index this |
393 | | - } |
394 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' ); // don't index this version |
395 | | - } |
396 | | - } |
397 | | - |
398 | | - /** |
399 | | - * @param $tag review box/bar info |
400 | | - * @param $prot protection notice |
401 | | - * Tag output function must be called by caller |
402 | | - */ |
403 | | - protected function showUnreviewedPage( $tag, $prot ) { |
404 | | - global $wgOut, $wgContLang; |
405 | | - if ( $wgOut->isPrintable() ) { |
406 | | - return; // all this function does is add notices; don't show them |
407 | | - } |
408 | | - $icon = FlaggedRevsXML::draftStatusIcon(); |
409 | | - // Simple icon-based UI |
410 | | - if ( $this->useSimpleUI() ) { |
411 | | - // RTL langauges |
412 | | - $rtl = $wgContLang->isRTL() ? " rtl" : ""; |
413 | | - $tag .= $prot . $icon . wfMsgExt( 'revreview-quick-none', 'parseinline' ); |
414 | | - $css = "flaggedrevs_short{$rtl} plainlinks noprint"; |
415 | | - $this->reviewNotice .= "<div id='mw-fr-revisiontag' class='$css'>$tag</div>"; |
416 | | - // Standard UI |
417 | | - } else { |
418 | | - $css = 'flaggedrevs_notice plainlinks noprint'; |
419 | | - $tag = "<div id='mw-fr-revisiontag' class='$css'>" . |
420 | | - $prot . $icon . wfMsgExt( 'revreview-noflagged', 'parseinline' ) . |
421 | | - "</div>"; |
422 | | - $this->reviewNotice .= $tag; |
423 | | - } |
424 | | - } |
425 | | - |
426 | | - /** |
427 | | - * @param $srev stable version |
428 | | - * @param $tag review box/bar info |
429 | | - * @param $prot protection notice icon |
430 | | - * Tag output function must be called by caller |
431 | | - * Parser cache control deferred to caller |
432 | | - */ |
433 | | - protected function showDraftVersion( FlaggedRevision $srev, &$tag, $prot ) { |
434 | | - global $wgUser, $wgOut, $wgLang, $wgRequest; |
435 | | - $this->load(); |
436 | | - if ( $wgOut->isPrintable() ) { |
437 | | - return; // all this function does is add notices; don't show them |
438 | | - } |
439 | | - $flags = $srev->getTags(); |
440 | | - $time = $wgLang->date( $srev->getTimestamp(), true ); |
441 | | - # Get quality level |
442 | | - $quality = FlaggedRevs::isQuality( $flags ); |
443 | | - # Get stable version sync status |
444 | | - $synced = $this->article->stableVersionIsSynced(); |
445 | | - if ( $synced ) { // draft == stable |
446 | | - $diffToggle = ''; // no diff to show |
447 | | - } else { // draft != stable |
448 | | - # The user may want the diff (via prefs) |
449 | | - $diffToggle = $this->getTopDiffToggle( $srev, $quality ); |
450 | | - if ( $diffToggle != '' ) $diffToggle = " $diffToggle"; |
451 | | - # Make sure there is always a notice bar when viewing the draft. |
452 | | - if ( $this->useSimpleUI() ) { // we already one for detailed UI |
453 | | - $this->setPendingNotice( $srev, $diffToggle ); |
454 | | - } |
455 | | - } |
456 | | - # Give a "your edit is pending" notice to newer users if |
457 | | - # an unreviewed edit was completed... |
458 | | - if ( $wgRequest->getVal( 'shownotice' ) |
459 | | - && $this->article->getUserText( Revision::RAW ) == $wgUser->getName() |
460 | | - && $this->article->revsArePending() |
461 | | - && !$wgUser->isAllowed( 'review' ) ) |
462 | | - { |
463 | | - $revsSince = $this->article->getPendingRevCount(); |
464 | | - $pending = $prot; |
465 | | - if ( $this->showRatingIcon() ) { |
466 | | - $pending .= FlaggedRevsXML::draftStatusIcon(); |
467 | | - } |
468 | | - $pending .= wfMsgExt( 'revreview-edited', |
469 | | - 'parseinline', $srev->getRevId(), $revsSince ); |
470 | | - $anchor = $wgRequest->getVal( 'fromsection' ); |
471 | | - if ( $anchor != null ) { |
472 | | - $section = str_replace( '_', ' ', $anchor ); // prettify |
473 | | - $pending .= wfMsgExt( 'revreview-edited-section', 'parse', $anchor, $section ); |
474 | | - } |
475 | | - # Notice should always use subtitle |
476 | | - $this->reviewNotice = "<div id='mw-fr-reviewnotice' " . |
477 | | - "class='flaggedrevs_preview plainlinks'>$pending</div>"; |
478 | | - # Otherwise, construct some tagging info for non-printable outputs. |
479 | | - # Also, if low profile UI is enabled and the page is synced, skip the tag. |
480 | | - # Note: the "your edit is pending" notice has all this info, so we never add both. |
481 | | - } else if ( !( $this->article->lowProfileUI() && $synced ) ) { |
482 | | - $revsSince = $this->article->getPendingRevCount(); |
483 | | - // Simple icon-based UI |
484 | | - if ( $this->useSimpleUI() ) { |
485 | | - if ( !$wgUser->getId() ) { |
486 | | - $msgHTML = ''; // Anons just see simple icons |
487 | | - } else if ( $synced ) { |
488 | | - $msg = $quality |
489 | | - ? 'revreview-quick-quality-same' |
490 | | - : 'revreview-quick-basic-same'; |
491 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', |
492 | | - $srev->getRevId(), $revsSince ); |
493 | | - } else { |
494 | | - $msg = $quality |
495 | | - ? 'revreview-quick-see-quality' |
496 | | - : 'revreview-quick-see-basic'; |
497 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', |
498 | | - $srev->getRevId(), $revsSince ); |
499 | | - } |
500 | | - $icon = ''; |
501 | | - # For protection based configs, show lock only if it's not redundant. |
502 | | - if ( $this->showRatingIcon() ) { |
503 | | - $icon = $synced |
504 | | - ? FlaggedRevsXML::stableStatusIcon( $quality ) |
505 | | - : FlaggedRevsXML::draftStatusIcon(); |
506 | | - } |
507 | | - $msgHTML = $prot . $icon . $msgHTML; |
508 | | - $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, |
509 | | - $revsSince, 'draft', $synced, false ); |
510 | | - // Standard UI |
511 | | - } else { |
512 | | - if ( $synced ) { |
513 | | - if ( $quality ) { |
514 | | - $msg = 'revreview-quality-same'; |
515 | | - } else { |
516 | | - $msg = 'revreview-basic-same'; |
517 | | - } |
518 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', |
519 | | - $srev->getRevId(), $time, $revsSince ); |
520 | | - } else { |
521 | | - $msg = $quality |
522 | | - ? 'revreview-newest-quality' |
523 | | - : 'revreview-newest-basic'; |
524 | | - $msg .= ( $revsSince == 0 ) ? '-i' : ''; |
525 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', |
526 | | - $srev->getRevId(), $time, $revsSince ); |
527 | | - } |
528 | | - $icon = $synced |
529 | | - ? FlaggedRevsXML::stableStatusIcon( $quality ) |
530 | | - : FlaggedRevsXML::draftStatusIcon(); |
531 | | - $tag .= $prot . $icon . $msgHTML . $diffToggle; |
532 | | - } |
533 | | - } |
534 | | - } |
535 | | - |
536 | | - /** |
537 | | - * @param $srev stable version |
538 | | - * @param $frev selected flagged revision |
539 | | - * @param $tag review box/bar info |
540 | | - * @param $prot protection notice icon |
541 | | - * Tag output function must be called by caller |
542 | | - * Parser cache control deferred to caller |
543 | | - */ |
544 | | - protected function showOldReviewedVersion( |
545 | | - FlaggedRevision $srev, FlaggedRevision $frev, &$tag, $prot |
546 | | - ) { |
547 | | - global $wgUser, $wgOut, $wgLang; |
548 | | - $this->load(); |
549 | | - $flags = $frev->getTags(); |
550 | | - $time = $wgLang->date( $frev->getTimestamp(), true ); |
551 | | - # Set display revision ID |
552 | | - $wgOut->setRevisionId( $frev->getRevId() ); |
553 | | - # Get quality level |
554 | | - $quality = FlaggedRevs::isQuality( $flags ); |
555 | | - |
556 | | - # Construct some tagging for non-printable outputs. Note that the pending |
557 | | - # notice has all this info already, so don't do this if we added that already. |
558 | | - if ( !$wgOut->isPrintable() ) { |
559 | | - // Simple icon-based UI |
560 | | - if ( $this->useSimpleUI() ) { |
561 | | - $icon = ''; |
562 | | - # For protection based configs, show lock only if it's not redundant. |
563 | | - if ( $this->showRatingIcon() ) { |
564 | | - $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
565 | | - } |
566 | | - $revsSince = $this->article->getPendingRevCount(); |
567 | | - if ( !$wgUser->getId() ) { |
568 | | - $msgHTML = ''; // Anons just see simple icons |
569 | | - } else { |
570 | | - $msg = $quality |
571 | | - ? 'revreview-quick-quality-old' |
572 | | - : 'revreview-quick-basic-old'; |
573 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $revsSince ); |
574 | | - } |
575 | | - $msgHTML = $prot . $icon . $msgHTML; |
576 | | - $tag = FlaggedRevsXML::prettyRatingBox( $frev, $msgHTML, |
577 | | - $revsSince, 'oldstable', false /*synced*/ ); |
578 | | - // Standard UI |
579 | | - } else { |
580 | | - $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
581 | | - $msg = $quality |
582 | | - ? 'revreview-quality-old' |
583 | | - : 'revreview-basic-old'; |
584 | | - $tag = $prot . $icon; |
585 | | - $tag .= wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time ); |
586 | | - # Hide clutter |
587 | | - if ( !empty( $flags ) ) { |
588 | | - $tag .= FlaggedRevsXML::ratingToggle(); |
589 | | - $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
590 | | - wfMsgHtml( 'revreview-oldrating' ) . |
591 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
592 | | - } |
593 | | - } |
594 | | - } |
595 | | - |
596 | | - # Check if this is a redirect... |
597 | | - $text = $frev->getRevText(); |
598 | | - $redirHtml = $this->getRedirectHtml( $text ); |
599 | | - |
600 | | - # Parse and output HTML |
601 | | - if ( $redirHtml == '' ) { |
602 | | - $parserOptions = FlaggedRevs::makeParserOptions(); |
603 | | - $parserOut = FlaggedRevs::parseStableText( |
604 | | - $this->article->getTitle(), $text, $frev->getRevId(), $parserOptions ); |
605 | | - $this->addParserOutput( $parserOut ); |
606 | | - } else { |
607 | | - $wgOut->addHtml( $redirHtml ); |
608 | | - } |
609 | | - } |
610 | | - |
611 | | - /** |
612 | | - * @param $srev stable version |
613 | | - * @param $tag review box/bar info |
614 | | - * @param $prot protection notice |
615 | | - * Tag output function must be called by caller |
616 | | - * Parser cache control deferred to caller |
617 | | - */ |
618 | | - protected function showStableVersion( FlaggedRevision $srev, &$tag, $prot ) { |
619 | | - global $wgOut, $wgLang, $wgUser; |
620 | | - $this->load(); |
621 | | - $flags = $srev->getTags(); |
622 | | - $time = $wgLang->date( $srev->getTimestamp(), true ); |
623 | | - # Set display revision ID |
624 | | - $wgOut->setRevisionId( $srev->getRevId() ); |
625 | | - # Get quality level |
626 | | - $quality = FlaggedRevs::isQuality( $flags ); |
627 | | - |
628 | | - $synced = $this->article->stableVersionIsSynced(); |
629 | | - # Construct some tagging |
630 | | - if ( !$wgOut->isPrintable() && !( $this->article->lowProfileUI() && $synced ) ) { |
631 | | - $revsSince = $this->article->getPendingRevCount(); |
632 | | - // Simple icon-based UI |
633 | | - if ( $this->useSimpleUI() ) { |
634 | | - $icon = ''; |
635 | | - # For protection based configs, show lock only if it's not redundant. |
636 | | - if ( $this->showRatingIcon() ) { |
637 | | - $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
638 | | - } |
639 | | - if ( !$wgUser->getId() ) { |
640 | | - $msgHTML = ''; // Anons just see simple icons |
641 | | - } else { |
642 | | - $msg = $quality |
643 | | - ? 'revreview-quick-quality' |
644 | | - : 'revreview-quick-basic'; |
645 | | - # Uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same' |
646 | | - $msg = $synced ? "{$msg}-same" : $msg; |
647 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', |
648 | | - $srev->getRevId(), $revsSince ); |
649 | | - } |
650 | | - $msgHTML = $prot . $icon . $msgHTML; |
651 | | - $tag = FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, |
652 | | - $revsSince, 'stable', $synced ); |
653 | | - // Standard UI |
654 | | - } else { |
655 | | - $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
656 | | - $msg = $quality ? 'revreview-quality' : 'revreview-basic'; |
657 | | - if ( $synced ) { |
658 | | - # uses messages 'revreview-quality-same', 'revreview-basic-same' |
659 | | - $msg .= '-same'; |
660 | | - } elseif ( $revsSince == 0 ) { |
661 | | - # uses messages 'revreview-quality-i', 'revreview-basic-i' |
662 | | - $msg .= '-i'; |
663 | | - } |
664 | | - $tag = $prot . $icon; |
665 | | - $tag .= wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince ); |
666 | | - if ( !empty( $flags ) ) { |
667 | | - $tag .= FlaggedRevsXML::ratingToggle(); |
668 | | - $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
669 | | - FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
670 | | - } |
671 | | - } |
672 | | - } |
673 | | - |
674 | | - # Get parsed stable version and output HTML |
675 | | - $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser ); |
676 | | - if ( $parserOut ) { |
677 | | - $this->addParserOutput( $parserOut ); |
678 | | - } else { |
679 | | - $text = $srev->getRevText(); |
680 | | - # Check if this is a redirect... |
681 | | - $redirHtml = $this->getRedirectHtml( $text ); |
682 | | - # Don't parse redirects, use separate handling... |
683 | | - if ( $redirHtml == '' ) { |
684 | | - # Get the new stable output |
685 | | - $parserOptions = FlaggedRevs::makeParserOptions(); |
686 | | - $parserOut = FlaggedRevs::parseStableText( |
687 | | - $this->article->getTitle(), $text, $srev->getRevId(), $parserOptions ); |
688 | | - # Update the stable version cache |
689 | | - FlaggedRevs::updatePageCache( $this->article, $parserOptions, $parserOut ); |
690 | | - # Add the stable output to the page view |
691 | | - $this->addParserOutput( $parserOut ); |
692 | | - |
693 | | - # Update the stable version dependancies |
694 | | - FlaggedRevs::updateCacheTracking( $this->article, $parserOut ); |
695 | | - } else { |
696 | | - $wgOut->addHtml( $redirHtml ); |
697 | | - } |
698 | | - } |
699 | | - |
700 | | - # Update page sync status for tracking purposes. |
701 | | - # NOTE: avoids master hits and doesn't have to be perfect for what it does |
702 | | - if ( $this->article->syncedInTracking() != $synced ) { |
703 | | - if ( wfGetDB( DB_SLAVE )->getLag() <= 5 ) { // avoid write-delay cycles |
704 | | - FlaggedRevs::updateSyncStatus( $this->article, $synced ); |
705 | | - } |
706 | | - } |
707 | | - } |
708 | | - |
709 | | - // Add parser output and update title |
710 | | - // @TODO: refactor MW core to move this back |
711 | | - protected function addParserOutput( ParserOutput $parserOut ) { |
712 | | - global $wgOut; |
713 | | - $wgOut->addParserOutput( $parserOut ); |
714 | | - # Adjust the title if it was set by displaytitle, -{T|}- or language conversion |
715 | | - $titleText = $parserOut->getTitleText(); |
716 | | - if ( strval( $titleText ) !== '' ) { |
717 | | - $wgOut->setPageTitle( $titleText ); |
718 | | - } |
719 | | - } |
720 | | - |
721 | | - // Get fancy redirect arrow and link HTML |
722 | | - protected function getRedirectHtml( $text ) { |
723 | | - $rTargets = Title::newFromRedirectArray( $text ); |
724 | | - if ( $rTargets ) { |
725 | | - return $this->article->viewRedirect( $rTargets ); |
726 | | - } |
727 | | - return ''; |
728 | | - } |
729 | | - |
730 | | - // Show icons for draft/stable/old reviewed versions |
731 | | - protected function showRatingIcon() { |
732 | | - if ( FlaggedRevs::useOnlyIfProtected() ) { |
733 | | - // If there is only one quality level and we have tabs to know |
734 | | - // which version we are looking at, then just use the lock icon... |
735 | | - return FlaggedRevs::qualityVersions(); |
736 | | - } |
737 | | - return true; |
738 | | - } |
739 | | - |
740 | | - /** |
741 | | - * Get collapsible diff-to-stable html to add to the review notice as needed |
742 | | - * @param FlaggedRevision $srev, stable version |
743 | | - * @param bool $quality, revision is quality |
744 | | - * @returns string, the html line (either "" or "<diff toggle><diff div>") |
745 | | - */ |
746 | | - protected function getTopDiffToggle( FlaggedRevision $srev, $quality ) { |
747 | | - global $wgUser; |
748 | | - $this->load(); |
749 | | - if ( !$wgUser->getBoolOption( 'flaggedrevsviewdiffs' ) ) { |
750 | | - return false; // nothing to do here |
751 | | - } |
752 | | - # Diff should only show for the draft |
753 | | - $oldid = $this->article->getOldIDFromRequest(); |
754 | | - $latest = $this->article->getLatest(); |
755 | | - if ( $oldid && $oldid != $latest ) { |
756 | | - return false; // not viewing the draft |
757 | | - } |
758 | | - $revsSince = $this->article->getPendingRevCount(); |
759 | | - if ( !$revsSince ) { |
760 | | - return false; // no pending changes |
761 | | - } |
762 | | - $title = $this->article->getTitle(); // convenience |
763 | | - # Review status of left diff revision... |
764 | | - $leftNote = $quality |
765 | | - ? 'revreview-hist-quality' |
766 | | - : 'revreview-hist-basic'; |
767 | | - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
768 | | - $leftNote = "<span class='$lClass'>[" . wfMsgHtml( $leftNote ) . "]</span>"; |
769 | | - # Review status of right diff revision... |
770 | | - $rClass = FlaggedRevsXML::getQualityColor( false ); |
771 | | - $rightNote = "<span class='$rClass'>[" . |
772 | | - wfMsgHtml( 'revreview-hist-pending' ) . "]</span>"; |
773 | | - # Get the actual body of the diff... |
774 | | - $diffEngine = new DifferenceEngine( $title, $srev->getRevId(), $latest ); |
775 | | - $diffBody = $diffEngine->getDiffBody(); |
776 | | - if ( strlen( $diffBody ) > 0 ) { |
777 | | - $nEdits = $revsSince - 1; // full diff-to-stable, no need for query |
778 | | - if ( $nEdits ) { |
779 | | - $limit = 100; |
780 | | - $nUsers = $title->countAuthorsBetween( $srev->getRevId(), $latest, $limit ); |
781 | | - $multiNotice = DifferenceEngine::intermediateEditsMsg( $nEdits, $nUsers, $limit ); |
782 | | - } else { |
783 | | - $multiNotice = ''; |
784 | | - } |
785 | | - $diffEngine->showDiffStyle(); // add CSS |
786 | | - $this->isDiffFromStable = true; // alter default review form tags |
787 | | - return |
788 | | - FlaggedRevsXML::diffToggle() . |
789 | | - "<div id='mw-fr-stablediff'>\n" . |
790 | | - self::getFormattedDiff( $diffBody, $multiNotice, $leftNote, $rightNote ) . |
791 | | - "</div>\n";; |
792 | | - } |
793 | | - return ''; |
794 | | - } |
795 | | - |
796 | | - // $n number of in-between revs |
797 | | - protected static function getFormattedDiff( |
798 | | - $diffBody, $multiNotice, $leftStatus, $rightStatus |
799 | | - ) { |
800 | | - if ( $multiNotice != '' ) { |
801 | | - $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" . |
802 | | - $multiNotice . "</td></tr>"; |
803 | | - } |
804 | | - return |
805 | | - "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" . |
806 | | - "<col class='diff-marker' />" . |
807 | | - "<col class='diff-content' />" . |
808 | | - "<col class='diff-marker' />" . |
809 | | - "<col class='diff-content' />" . |
810 | | - "<tr>" . |
811 | | - "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" . |
812 | | - $leftStatus . "</b></td>" . |
813 | | - "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" . |
814 | | - $rightStatus . "</b></td>" . |
815 | | - "</tr>" . |
816 | | - $multiNotice . |
817 | | - $diffBody . |
818 | | - "</table>"; |
819 | | - } |
820 | | - |
821 | | - /** |
822 | | - * Get the normal and display files for the underlying ImagePage. |
823 | | - * If the a stable version needs to be displayed, this will set $normalFile |
824 | | - * to the current version, and $displayFile to the desired version. |
825 | | - * |
826 | | - * If no stable version is required, the reference parameters will not be set |
827 | | - * |
828 | | - * Depends on $wgRequest |
829 | | - */ |
830 | | - public function imagePageFindFile( &$normalFile, &$displayFile ) { |
831 | | - global $wgRequest; |
832 | | - $this->load(); |
833 | | - # Determine timestamp. A reviewed version may have explicitly been requested... |
834 | | - $frev = null; |
835 | | - $time = false; |
836 | | - $reqId = $wgRequest->getVal( 'stableid' ); |
837 | | - if ( $reqId ) { |
838 | | - $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId ); |
839 | | - } elseif ( $this->showingStable() ) { |
840 | | - $frev = $this->article->getStableRev(); |
841 | | - } |
842 | | - if ( $frev ) { |
843 | | - $time = $frev->getFileTimestamp(); |
844 | | - // B/C, may be stored in associated image version metadata table |
845 | | - // @TODO: remove, updateTracking.php does this |
846 | | - if ( !$time ) { |
847 | | - $dbr = wfGetDB( DB_SLAVE ); |
848 | | - $time = $dbr->selectField( 'flaggedimages', |
849 | | - 'fi_img_timestamp', |
850 | | - array( 'fi_rev_id' => $frev->getRevId(), |
851 | | - 'fi_name' => $this->article->getTitle()->getDBkey() ), |
852 | | - __METHOD__ |
853 | | - ); |
854 | | - $time = trim( $time ); // remove garbage |
855 | | - $time = $time ? wfTimestamp( TS_MW, $time ) : false; |
856 | | - } |
857 | | - } |
858 | | - if ( !$time ) { |
859 | | - # Try request parameter |
860 | | - $time = $wgRequest->getVal( 'filetimestamp', false ); |
861 | | - } |
862 | | - |
863 | | - if ( !$time ) { |
864 | | - return; // Use the default behaviour |
865 | | - } |
866 | | - |
867 | | - $title = $this->article->getTitle(); |
868 | | - $displayFile = wfFindFile( $title, array( 'time' => $time ) ); |
869 | | - # If none found, try current |
870 | | - if ( !$displayFile ) { |
871 | | - wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: $time not found, using current\n" ); |
872 | | - $displayFile = wfFindFile( $title ); |
873 | | - # If none found, use a valid local placeholder |
874 | | - if ( !$displayFile ) { |
875 | | - $displayFile = wfLocalFile( $title ); // fallback to current |
876 | | - } |
877 | | - $normalFile = $displayFile; |
878 | | - # If found, set $normalFile |
879 | | - } else { |
880 | | - wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: using timestamp $time\n" ); |
881 | | - $normalFile = wfFindFile( $title ); |
882 | | - } |
883 | | - } |
884 | | - |
885 | | - /** |
886 | | - * Adds stable version tags to page when viewing history |
887 | | - */ |
888 | | - public function addToHistView() { |
889 | | - global $wgOut; |
890 | | - $this->load(); |
891 | | - # Add a notice if there are pending edits... |
892 | | - $srev = $this->article->getStableRev(); |
893 | | - if ( $srev && $this->article->revsArePending() ) { |
894 | | - $revsSince = $this->article->getPendingRevCount(); |
895 | | - $tag = "<div id='mw-fr-revisiontag-edit' class='flaggedrevs_notice plainlinks'>" . |
896 | | - FlaggedRevsXML::lockStatusIcon( $this->article ) . # flag protection icon as needed |
897 | | - FlaggedRevsXML::pendingEditNotice( $this->article, $srev, $revsSince ) . "</div>"; |
898 | | - $wgOut->addHTML( $tag ); |
899 | | - } |
900 | | - return true; |
901 | | - } |
902 | | - |
903 | | - /** |
904 | | - * Adds stable version tags to page when editing |
905 | | - */ |
906 | | - public function addToEditView( EditPage $editPage ) { |
907 | | - global $wgOut, $wgUser; |
908 | | - $this->load(); |
909 | | - # Must be reviewable. UI may be limited to unobtrusive patrolling system. |
910 | | - if ( !$this->article->isReviewable() ) { |
911 | | - return true; |
912 | | - } |
913 | | - $items = array(); |
914 | | - # Show stabilization log |
915 | | - $log = $this->stabilityLogNotice(); |
916 | | - if ( $log ) $items[] = $log; |
917 | | - # Check the newest stable version |
918 | | - $frev = $this->article->getStableRev(); |
919 | | - if ( $frev ) { |
920 | | - $quality = $frev->getQuality(); |
921 | | - # Find out revision id of base version |
922 | | - $latestId = $this->article->getLatest(); |
923 | | - $revId = $editPage->oldid ? $editPage->oldid : $latestId; |
924 | | - # Let new users know about review procedure a tag. |
925 | | - # If the log excerpt was shown this is redundant. |
926 | | - if ( !$log && !$wgUser->getId() && $this->article->isStableShownByDefault() ) { |
927 | | - $items[] = wfMsgExt( 'revreview-editnotice', 'parseinline' ); |
928 | | - } |
929 | | - # Add a notice if there are pending edits... |
930 | | - if ( $this->article->revsArePending() ) { |
931 | | - $revsSince = $this->article->getPendingRevCount(); |
932 | | - $items[] = FlaggedRevsXML::pendingEditNotice( $this->article, $frev, $revsSince ); |
933 | | - } |
934 | | - # Show diff to stable, to make things less confusing. |
935 | | - # This can be disabled via user preferences and other conditions... |
936 | | - if ( $frev->getRevId() < $latestId // changes were made |
937 | | - && $wgUser->getBoolOption( 'flaggedrevseditdiffs' ) // not disable via prefs |
938 | | - && $revId == $latestId // only for current rev |
939 | | - && $editPage->section != 'new' // not for new sections |
940 | | - && $editPage->formtype != 'diff' // not "show changes" |
941 | | - ) { |
942 | | - # Left diff side... |
943 | | - $leftNote = $quality |
944 | | - ? 'revreview-hist-quality' |
945 | | - : 'revreview-hist-basic'; |
946 | | - $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
947 | | - $leftNote = "<span class='$lClass'>[" . |
948 | | - wfMsgHtml( $leftNote ) . "]</span>"; |
949 | | - # Right diff side... |
950 | | - $rClass = FlaggedRevsXML::getQualityColor( false ); |
951 | | - $rightNote = "<span class='$rClass'>[" . |
952 | | - wfMsgHtml( 'revreview-hist-pending' ) . "]</span>"; |
953 | | - # Get the stable version source |
954 | | - $text = $frev->getRevText(); |
955 | | - # Are we editing a section? |
956 | | - $section = ( $editPage->section == "" ) ? |
957 | | - false : intval( $editPage->section ); |
958 | | - if ( $section !== false ) { |
959 | | - $text = $this->article->getSection( $text, $section ); |
960 | | - } |
961 | | - if ( $text !== false && strcmp( $text, $editPage->textbox1 ) !== 0 ) { |
962 | | - $diffEngine = new DifferenceEngine( $this->article->getTitle() ); |
963 | | - $diffBody = $diffEngine->generateDiffBody( $text, $editPage->textbox1 ); |
964 | | - $diffHtml = |
965 | | - wfMsgExt( 'review-edit-diff', 'parseinline' ) . ' ' . |
966 | | - FlaggedRevsXML::diffToggle() . |
967 | | - "<div id='mw-fr-stablediff'>" . |
968 | | - self::getFormattedDiff( $diffBody, '', $leftNote, $rightNote ) . |
969 | | - "</div>\n"; |
970 | | - $items[] = $diffHtml; |
971 | | - $diffEngine->showDiffStyle(); // add CSS |
972 | | - } |
973 | | - } |
974 | | - # Output items |
975 | | - if ( count( $items ) ) { |
976 | | - $html = "<table class='flaggedrevs_editnotice plainlinks'>"; |
977 | | - foreach ( $items as $item ) { |
978 | | - $html .= '<tr><td>' . $item . '</td></tr>'; |
979 | | - } |
980 | | - $html .= '</table>'; |
981 | | - $wgOut->addHTML( $html ); |
982 | | - } |
983 | | - } |
984 | | - return true; |
985 | | - } |
986 | | - |
987 | | - protected function stabilityLogNotice() { |
988 | | - $this->load(); |
989 | | - $s = ''; |
990 | | - # Only for pages manually made to be stable... |
991 | | - if ( $this->article->isPageLocked() ) { |
992 | | - $s = wfMsgExt( 'revreview-locked', 'parseinline' ); |
993 | | - $s .= ' ' . FlaggedRevsXML::logDetailsToggle(); |
994 | | - $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article ); |
995 | | - # ...or unstable |
996 | | - } elseif ( $this->article->isPageUnlocked() ) { |
997 | | - $s = wfMsgExt( 'revreview-unlocked', 'parseinline' ); |
998 | | - $s .= ' ' . FlaggedRevsXML::logDetailsToggle(); |
999 | | - $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article ); |
1000 | | - } |
1001 | | - return $s; |
1002 | | - } |
1003 | | - |
1004 | | - public function addToNoSuchSection( EditPage $editPage, &$s ) { |
1005 | | - $this->load(); |
1006 | | - $srev = $this->article->getStableRev(); |
1007 | | - # Add notice for users that may have clicked "edit" for a |
1008 | | - # section in the stable version that isn't in the draft. |
1009 | | - if ( $srev && $this->article->revsArePending() ) { |
1010 | | - $revsSince = $this->article->getPendingRevCount(); |
1011 | | - if ( $revsSince ) { |
1012 | | - $s .= "<div class='flaggedrevs_editnotice plainlinks'>" . |
1013 | | - wfMsgExt( 'revreview-pending-nosection', 'parseinline', |
1014 | | - $srev->getRevId(), $revsSince ) . "</div>"; |
1015 | | - } |
1016 | | - } |
1017 | | - return true; |
1018 | | - } |
1019 | | - |
1020 | | - /** |
1021 | | - * Add unreviewed pages links |
1022 | | - */ |
1023 | | - public function addToCategoryView() { |
1024 | | - global $wgOut, $wgUser; |
1025 | | - $this->load(); |
1026 | | - if ( !$wgUser->isAllowed( 'review' ) ) { |
1027 | | - return true; |
1028 | | - } |
1029 | | - if ( !FlaggedRevs::useOnlyIfProtected() ) { |
1030 | | - # Add links to lists of unreviewed pages and pending changes in this category |
1031 | | - $category = $this->article->getTitle()->getText(); |
1032 | | - $wgOut->appendSubtitle( |
1033 | | - Html::rawElement( |
1034 | | - 'span', |
1035 | | - array( 'class' => 'plainlinks', 'id' => 'mw-fr-category-oldreviewed' ), |
1036 | | - wfMsgExt( 'flaggedrevs-categoryview', 'parseinline', urlencode( $category ) ) |
1037 | | - ) |
1038 | | - ); |
1039 | | - } |
1040 | | - return true; |
1041 | | - } |
1042 | | - |
1043 | | - /** |
1044 | | - * Add review form to pages when necessary |
1045 | | - * on a regular page view (action=view) |
1046 | | - */ |
1047 | | - public function addReviewForm( &$data ) { |
1048 | | - global $wgRequest, $wgUser, $wgOut; |
1049 | | - $this->load(); |
1050 | | - if ( $wgOut->isPrintable() ) { |
1051 | | - return false; // Must be on non-printable output |
1052 | | - } |
1053 | | - # User must have review rights |
1054 | | - if ( !$wgUser->isAllowed( 'review' ) ) { |
1055 | | - return true; |
1056 | | - } |
1057 | | - # Page must exist and be reviewable |
1058 | | - if ( !$this->article->exists() || !$this->article->isReviewable() ) { |
1059 | | - return true; |
1060 | | - } |
1061 | | - # Must be a page view action... |
1062 | | - if ( !$this->isPageViewOrDiff( $wgRequest ) ) { |
1063 | | - return true; |
1064 | | - } |
1065 | | - # Get the revision being displayed |
1066 | | - $rev = false; |
1067 | | - if ( $this->reviewFormRev ) { |
1068 | | - $rev = $this->reviewFormRev; // $newRev for diffs stored here |
1069 | | - } elseif ( $wgOut->getRevisionId() ) { |
1070 | | - $rev = Revision::newFromId( $wgOut->getRevisionId() ); |
1071 | | - } |
1072 | | - # Build the review form as needed |
1073 | | - if ( $rev && ( !$this->diffRevs || $this->isReviewableDiff ) ) { |
1074 | | - $form = new RevisionReviewFormGUI( $wgUser, $this->article, $rev ); |
1075 | | - # Default tags and existence of "reject" button depend on context |
1076 | | - if ( $this->diffRevs ) { |
1077 | | - $form->setDiffPriorRev( $this->diffRevs['old'] ); |
1078 | | - } |
1079 | | - # Review notice box goes in top of form |
1080 | | - $form->setTopNotice( $this->diffNoticeBox ); |
1081 | | - # $wgOut may not already have the inclusion IDs, such as for diffonly=1. |
1082 | | - # RevisionReviewForm will fetch them as needed however. |
1083 | | - if ( $wgOut->getRevisionId() == $rev->getId() ) { |
1084 | | - $form->setIncludeVersions( $wgOut->getTemplateIds(), $wgOut->getImageTimeKeys() ); |
1085 | | - } |
1086 | | - list( $html, $status ) = $form->getHtml(); |
1087 | | - # Diff action: place the form at the top of the page |
1088 | | - if ( $this->diffRevs ) { |
1089 | | - $wgOut->prependHTML( $html ); |
1090 | | - # View action: place the form at the bottom of the page |
1091 | | - } else { |
1092 | | - $data .= $html; |
1093 | | - } |
1094 | | - } |
1095 | | - return true; |
1096 | | - } |
1097 | | - |
1098 | | - /** |
1099 | | - * Add link to stable version setting to protection form |
1100 | | - */ |
1101 | | - public function addVisibilityLink( &$data ) { |
1102 | | - global $wgRequest, $wgOut; |
1103 | | - $this->load(); |
1104 | | - if ( FlaggedRevs::useProtectionLevels() ) { |
1105 | | - return true; // simple custom levels set for action=protect |
1106 | | - } |
1107 | | - # Check only if the title is reviewable |
1108 | | - if ( !FlaggedRevs::inReviewNamespace( $this->article->getTitle() ) ) { |
1109 | | - return true; |
1110 | | - } |
1111 | | - $action = $wgRequest->getVal( 'action', 'view' ); |
1112 | | - if ( $action == 'protect' || $action == 'unprotect' ) { |
1113 | | - $title = SpecialPage::getTitleFor( 'Stabilization' ); |
1114 | | - # Give a link to the page to configure the stable version |
1115 | | - $frev = $this->article->getStableRev(); |
1116 | | - if ( $frev && $frev->getRevId() == $this->article->getLatest() ) { |
1117 | | - $wgOut->prependHTML( "<span class='plainlinks'>" . |
1118 | | - wfMsgExt( 'revreview-visibility-synced', 'parseinline', |
1119 | | - $title->getPrefixedText() ) . "</span>" ); |
1120 | | - } elseif ( $frev ) { |
1121 | | - $wgOut->prependHTML( "<span class='plainlinks'>" . |
1122 | | - wfMsgExt( 'revreview-visibility-outdated', 'parseinline', |
1123 | | - $title->getPrefixedText() ) . "</span>" ); |
1124 | | - } else { |
1125 | | - $wgOut->prependHTML( "<span class='plainlinks'>" . |
1126 | | - wfMsgExt( 'revreview-visibility-nostable', 'parseinline', |
1127 | | - $title->getPrefixedText() ) . "</span>" ); |
1128 | | - } |
1129 | | - } |
1130 | | - return true; |
1131 | | - } |
1132 | | - |
1133 | | - /** |
1134 | | - * Modify an array of action links, as used by SkinTemplateNavigation and |
1135 | | - * SkinTemplateTabs, to inlude flagged revs UI elements |
1136 | | - */ |
1137 | | - public function setActionTabs( $skin, array &$actions ) { |
1138 | | - global $wgUser; |
1139 | | - $this->load(); |
1140 | | - if ( FlaggedRevs::useProtectionLevels() ) { |
1141 | | - return true; // simple custom levels set for action=protect |
1142 | | - } |
1143 | | - $title = $this->article->getTitle()->getSubjectPage(); |
1144 | | - if ( !FlaggedRevs::inReviewNamespace( $title ) ) { |
1145 | | - return true; // Only reviewable pages need these tabs |
1146 | | - } |
1147 | | - // Check if we should show a stabilization tab |
1148 | | - if ( |
1149 | | - !$this->article->getTitle()->isTalkPage() && |
1150 | | - is_array( $actions ) && |
1151 | | - !isset( $actions['protect'] ) && |
1152 | | - !isset( $actions['unprotect'] ) && |
1153 | | - $wgUser->isAllowed( 'stablesettings' ) && |
1154 | | - $title->exists() ) |
1155 | | - { |
1156 | | - $stableTitle = SpecialPage::getTitleFor( 'Stabilization' ); |
1157 | | - // Add the tab |
1158 | | - $actions['default'] = array( |
1159 | | - 'class' => false, |
1160 | | - 'text' => wfMsg( 'stabilization-tab' ), |
1161 | | - 'href' => $stableTitle->getLocalUrl( |
1162 | | - 'page=' . $title->getPrefixedUrl() |
1163 | | - ) |
1164 | | - ); |
1165 | | - } |
1166 | | - return true; |
1167 | | - } |
1168 | | - |
1169 | | - /** |
1170 | | - * Modify an array of tab links to include flagged revs UI elements |
1171 | | - * @param string $type ('flat' for SkinTemplateTabs, 'nav' for SkinTemplateNavigation) |
1172 | | - */ |
1173 | | - public function setViewTabs( Skin $skin, array &$views, $type ) { |
1174 | | - global $wgRequest; |
1175 | | - $this->load(); |
1176 | | - if ( $this->article->getTitle()->isTalkPage() ) { |
1177 | | - return true; // leave talk pages alone |
1178 | | - } |
1179 | | - if ( !$this->article->isReviewable() ) { |
1180 | | - return true; // Not a reviewable page or the UI is hidden |
1181 | | - } |
1182 | | - $srev = $this->article->getStableRev(); |
1183 | | - if ( !$srev ) { |
1184 | | - return true; // No stable revision exists |
1185 | | - } |
1186 | | - $synced = $this->article->stableVersionIsSynced(); |
1187 | | - $pendingEdits = !$synced && $this->article->isStableShownByDefault(); |
1188 | | - // Set the edit tab names as needed... |
1189 | | - if ( $pendingEdits ) { |
1190 | | - if ( isset( $views['edit'] ) ) { |
1191 | | - $views['edit']['text'] = wfMsg( 'revreview-edit' ); |
1192 | | - } |
1193 | | - if ( isset( $views['viewsource'] ) ) { |
1194 | | - $views['viewsource']['text'] = wfMsg( 'revreview-source' ); |
1195 | | - } |
1196 | | - } |
1197 | | - # Add "pending changes" tab if the page is not synced |
1198 | | - if ( !$synced ) { |
1199 | | - $this->addDraftTab( $views, $srev, $type ); |
1200 | | - } |
1201 | | - return true; |
1202 | | - } |
1203 | | - |
1204 | | - // Add "pending changes" tab and set tab selection CSS |
1205 | | - protected function addDraftTab( array &$views, FlaggedRevision $srev, $type ) { |
1206 | | - global $wgRequest, $wgOut; |
1207 | | - $title = $this->article->getTitle(); // convenience |
1208 | | - $tabs = array( |
1209 | | - 'read' => array( // view stable |
1210 | | - 'text' => '', // unused |
1211 | | - 'href' => $title->getLocalUrl( 'stable=1' ), |
1212 | | - 'class' => '' |
1213 | | - ), |
1214 | | - 'draft' => array( // view draft |
1215 | | - 'text' => wfMsg( 'revreview-current' ), |
1216 | | - 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ), |
1217 | | - 'class' => 'collapsible' |
1218 | | - ), |
1219 | | - ); |
1220 | | - // Set tab selection CSS |
1221 | | - if ( $this->showingStable() || $wgRequest->getVal( 'stableid' ) ) { |
1222 | | - // We are looking a the stable version or an old reviewed one |
1223 | | - $tabs['read']['class'] = 'selected'; |
1224 | | - } elseif ( $this->isPageViewOrDiff( $wgRequest ) ) { |
1225 | | - $ts = null; |
1226 | | - if ( $wgOut->getRevisionId() ) { // @TODO: avoid same query in Skin.php |
1227 | | - $ts = ( $wgOut->getRevisionId() == $this->article->getLatest() ) |
1228 | | - ? $this->article->getTimestamp() // skip query |
1229 | | - : Revision::getTimestampFromId( $title, $wgOut->getRevisionId() ); |
1230 | | - } |
1231 | | - // Are we looking at a pending revision? |
1232 | | - if ( $ts > $srev->getRevTimestamp() ) { // bug 15515 |
1233 | | - $tabs['draft']['class'] .= ' selected'; |
1234 | | - // Are there *just* pending template/file changes. |
1235 | | - } elseif ( $this->article->onlyTemplatesOrFilesPending() |
1236 | | - && $wgOut->getRevisionId() == $this->article->getStable() ) |
1237 | | - { |
1238 | | - $tabs['draft']['class'] .= ' selected'; |
1239 | | - // Otherwise, fallback to regular tab behavior |
1240 | | - } else { |
1241 | | - $tabs['read']['class'] = 'selected'; |
1242 | | - } |
1243 | | - } |
1244 | | - $newViews = array(); |
1245 | | - // Rebuild tabs array. Deals with Monobook vs Vector differences. |
1246 | | - if ( $type == 'nav' ) { // Vector et al |
1247 | | - foreach ( $views as $tabAction => $data ) { |
1248 | | - // The 'view' tab. Make it go to the stable version... |
1249 | | - if ( $tabAction == 'view' ) { |
1250 | | - // 'view' for content page; make it go to the stable version |
1251 | | - $newViews[$tabAction]['text'] = $data['text']; // keep tab name |
1252 | | - $newViews[$tabAction]['href'] = $tabs['read']['href']; |
1253 | | - $newViews[$tabAction]['class'] = $tabs['read']['class']; |
1254 | | - // All other tabs... |
1255 | | - } else { |
1256 | | - // Add 'draft' tab to content page to the left of 'edit'... |
1257 | | - if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) { |
1258 | | - $newViews['current'] = $tabs['draft']; |
1259 | | - } |
1260 | | - $newViews[$tabAction] = $data; |
1261 | | - } |
1262 | | - } |
1263 | | - } elseif ( $type == 'flat' ) { // MonoBook et al |
1264 | | - $first = true; |
1265 | | - foreach ( $views as $tabAction => $data ) { |
1266 | | - // The first tab ('page'). Make it go to the stable version... |
1267 | | - if ( $first ) { |
1268 | | - $first = false; |
1269 | | - $newViews[$tabAction]['text'] = $data['text']; // keep tab name |
1270 | | - $newViews[$tabAction]['href'] = $tabs['read']['href']; |
1271 | | - $newViews[$tabAction]['class'] = $data['class']; // keep tab class |
1272 | | - // All other tabs... |
1273 | | - } else { |
1274 | | - // Add 'draft' tab to content page to the left of 'edit'... |
1275 | | - if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) { |
1276 | | - $newViews['current'] = $tabs['draft']; |
1277 | | - } |
1278 | | - $newViews[$tabAction] = $data; |
1279 | | - } |
1280 | | - } |
1281 | | - } |
1282 | | - // Replaces old tabs with new tabs |
1283 | | - $views = $newViews; |
1284 | | - } |
1285 | | - |
1286 | | - /** |
1287 | | - * Adds a notice saying that this revision is pending review |
1288 | | - * @param FlaggedRevision $srev The stable version |
1289 | | - * @param string $diffToggle either "" or " <diff toggle><diff div>" |
1290 | | - * @return void |
1291 | | - */ |
1292 | | - public function setPendingNotice( FlaggedRevision $srev, $diffToggle = '' ) { |
1293 | | - global $wgLang; |
1294 | | - $this->load(); |
1295 | | - $time = $wgLang->date( $srev->getTimestamp(), true ); |
1296 | | - $revsSince = $this->article->getPendingRevCount(); |
1297 | | - $msg = $srev->getQuality() |
1298 | | - ? 'revreview-newest-quality' |
1299 | | - : 'revreview-newest-basic'; |
1300 | | - $msg .= ( $revsSince == 0 ) ? '-i' : ''; |
1301 | | - # Add bar msg to the top of the page... |
1302 | | - $css = 'flaggedrevs_preview plainlinks'; |
1303 | | - $msgHTML = wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince ); |
1304 | | - $this->reviewNotice .= "<div id='mw-fr-reviewnotice' class='$css'>" . |
1305 | | - "$msgHTML$diffToggle</div>"; |
1306 | | - } |
1307 | | - |
1308 | | - /** |
1309 | | - * When viewing a diff: |
1310 | | - * (a) Add the review form to the top of the page |
1311 | | - * (b) Mark off which versions are checked or not |
1312 | | - * (c) When comparing the stable revision to the current: |
1313 | | - * (i) Show a tag with some explanation for the diff |
1314 | | - * (ii) List any template/file changes pending review |
1315 | | - */ |
1316 | | - public function addToDiffView( $diff, $oldRev, $newRev ) { |
1317 | | - global $wgRequest, $wgUser, $wgOut, $wgMemc; |
1318 | | - $this->load(); |
1319 | | - # Exempt printer-friendly output |
1320 | | - if ( $wgOut->isPrintable() ) { |
1321 | | - return true; |
1322 | | - # Multi-page diffs are useless and misbehave (bug 19327). Sanity check $newRev. |
1323 | | - } elseif ( $this->isMultiPageDiff || !$newRev ) { |
1324 | | - return true; |
1325 | | - # Page must be reviewable. |
1326 | | - } elseif ( !$this->article->isReviewable() ) { |
1327 | | - return true; |
1328 | | - } |
1329 | | - $srev = $this->article->getStableRev(); |
1330 | | - # Check if this is a diff-to-stable. If so: |
1331 | | - # (a) prompt reviewers to review the changes |
1332 | | - # (b) list template/file changes if only includes are pending |
1333 | | - if ( $srev |
1334 | | - && $this->isDiffFromStable |
1335 | | - && !$this->article->stableVersionIsSynced() ) // pending changes |
1336 | | - { |
1337 | | - $changeDiv = ''; |
1338 | | - $this->reviewFormRev = $newRev; |
1339 | | - $changeList = array(); |
1340 | | - # Page not synced only due to includes? |
1341 | | - if ( !$this->article->revsArePending() ) { |
1342 | | - # Add a list of links to each changed template... |
1343 | | - $changeList = self::fetchTemplateChanges( $srev ); |
1344 | | - # Add a list of links to each changed file... |
1345 | | - $changeList = array_merge( $changeList, self::fetchFileChanges( $srev ) ); |
1346 | | - # Correct bad cache which said they were not synced... |
1347 | | - if ( !count( $changeList ) ) { |
1348 | | - global $wgParserCacheExpireTime; |
1349 | | - $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->article->getId() ); |
1350 | | - $data = FlaggedRevs::makeMemcObj( "true" ); |
1351 | | - $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
1352 | | - } |
1353 | | - } |
1354 | | - # If there are pending revs or templates/files changes, notify the user... |
1355 | | - if ( $this->article->revsArePending() || count( $changeList ) ) { |
1356 | | - $changeDiv = ''; |
1357 | | - # If the user can review then prompt them to review them... |
1358 | | - if ( $wgUser->isAllowed( 'review' ) ) { |
1359 | | - # Set a key to note that someone is viewing this |
1360 | | - FRUserActivity::setUserReviewingDiff( |
1361 | | - $wgUser, $oldRev->getId(), $newRev->getId() ); |
1362 | | - // Reviewer just edited... |
1363 | | - if ( $wgRequest->getInt( 'shownotice' ) |
1364 | | - && $newRev->isCurrent() |
1365 | | - && $newRev->getRawUserText() == $wgUser->getName() ) |
1366 | | - { |
1367 | | - $title = $this->article->getTitle(); // convenience |
1368 | | - // @TODO: make diff class cache this |
1369 | | - $n = $title->countRevisionsBetween( $oldRev, $newRev ); |
1370 | | - if ( $n ) { |
1371 | | - $msg = 'revreview-update-edited-prev'; // previous pending edits |
1372 | | - } else { |
1373 | | - $msg = 'revreview-update-edited'; // just couldn't autoreview |
1374 | | - } |
1375 | | - // All other cases... |
1376 | | - } else { |
1377 | | - $msg = 'revreview-update'; // generic "please review" notice... |
1378 | | - } |
1379 | | - $changeDiv .= wfMsgExt( $msg, 'parse' ); |
1380 | | - } |
1381 | | - # Add include change list... |
1382 | | - if ( count( $changeList ) ) { |
1383 | | - $changeDiv .= '<p>' . |
1384 | | - wfMsgExt( 'revreview-update-includes', 'parseinline' ) . |
1385 | | - ' ' . implode( ', ', $changeList ) . '</p>'; |
1386 | | - # Add include usage notice... |
1387 | | - if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
1388 | | - $changeDiv .= wfMsgExt( 'revreview-update-use', 'parse' ); |
1389 | | - } |
1390 | | - } |
1391 | | - } |
1392 | | - if ( $changeDiv != '' ) { |
1393 | | - if ( $wgUser->isAllowed( 'review' ) ) { |
1394 | | - $this->diffNoticeBox = $changeDiv; // add as part of form |
1395 | | - } else { |
1396 | | - $css = 'flaggedrevs_diffnotice plainlinks'; |
1397 | | - $wgOut->addHTML( |
1398 | | - "<div id='mw-fr-difftostable' class='$css'>$changeDiv</div>\n" |
1399 | | - ); |
1400 | | - } |
1401 | | - } |
1402 | | - } |
1403 | | - # Add a link to diff from stable to current as needed. |
1404 | | - # Show review status of the diff revision(s). Uses a <table>. |
1405 | | - $wgOut->addHTML( |
1406 | | - '<div id="mw-fr-diff-headeritems">' . |
1407 | | - self::diffLinkAndMarkers( $this->article, $oldRev, $newRev ) . |
1408 | | - '</div>' |
1409 | | - ); |
1410 | | - return true; |
1411 | | - } |
1412 | | - |
1413 | | - // get new diff header items for in-place AJAX page review |
1414 | | - public static function AjaxBuildDiffHeaderItems() { |
1415 | | - $args = func_get_args(); // <oldid, newid> |
1416 | | - if ( count( $args ) >= 2 ) { |
1417 | | - $oldid = (int)$args[0]; |
1418 | | - $newid = (int)$args[1]; |
1419 | | - $oldRev = Revision::newFromId( $oldid ); |
1420 | | - $newRev = Revision::newFromId( $newid ); |
1421 | | - if ( $newRev && $newRev->getTitle() ) { |
1422 | | - $fa = FlaggedArticle::getTitleInstance( $newRev->getTitle() ); |
1423 | | - return self::diffLinkAndMarkers( $fa, $oldRev, $newRev ); |
1424 | | - } |
1425 | | - } |
1426 | | - return ''; |
1427 | | - } |
1428 | | - |
1429 | | - /** |
1430 | | - * (a) Add a link to diff from stable to current as needed |
1431 | | - * (b) Show review status of the diff revision(s). Uses a <table>. |
1432 | | - * Note: used by ajax function to rebuild diff page |
1433 | | - */ |
1434 | | - public static function diffLinkAndMarkers( FlaggedArticle $article, $oldRev, $newRev ) { |
1435 | | - $s = '<form id="mw-fr-diff-dataform">'; |
1436 | | - $s .= Html::hidden( 'oldid', $oldRev ? $oldRev->getId() : 0 ); |
1437 | | - $s .= Html::hidden( 'newid', $newRev ? $newRev->getId() : 0 ); |
1438 | | - $s .= "</form>\n"; |
1439 | | - if ( $newRev ) { // sanity check |
1440 | | - $s .= self::diffToStableLink( $article, $oldRev, $newRev ); |
1441 | | - $s .= self::diffReviewMarkers( $article, $oldRev, $newRev ); |
1442 | | - } |
1443 | | - return $s; |
1444 | | - } |
1445 | | - |
1446 | | - /** |
1447 | | - * Add a link to diff-to-stable for reviewable pages |
1448 | | - */ |
1449 | | - protected static function diffToStableLink( |
1450 | | - FlaggedArticle $article, $oldRev, Revision $newRev |
1451 | | - ) { |
1452 | | - global $wgUser; |
1453 | | - $srev = $article->getStableRev(); |
1454 | | - if ( !$srev ) { |
1455 | | - return ''; // nothing to do |
1456 | | - } |
1457 | | - $review = ''; |
1458 | | - # Is this already the full diff-to-stable? |
1459 | | - $fullStableDiff = $newRev->isCurrent() |
1460 | | - && self::isDiffToStable( $srev, $oldRev, $newRev ); |
1461 | | - # Make a link to the full diff-to-stable if: |
1462 | | - # (a) Actual revs are pending and (b) We are not viewing the full diff-to-stable |
1463 | | - if ( $article->revsArePending() && !$fullStableDiff ) { |
1464 | | - $review = $wgUser->getSkin()->makeKnownLinkObj( |
1465 | | - $article->getTitle(), |
1466 | | - wfMsgHtml( 'review-diff2stable' ), |
1467 | | - 'oldid=' . $srev->getRevId() . '&diff=cur&diffonly=0' |
1468 | | - ); |
1469 | | - $review = wfMsgHtml( 'parentheses', $review ); |
1470 | | - $review = "<div class='fr-diff-to-stable' align='center'>$review</div>"; |
1471 | | - } |
1472 | | - return $review; |
1473 | | - } |
1474 | | - |
1475 | | - /** |
1476 | | - * Add [checked version] and such to left and right side of diff |
1477 | | - */ |
1478 | | - protected static function diffReviewMarkers( FlaggedArticle $article, $oldRev, $newRev ) { |
1479 | | - $table = ''; |
1480 | | - $srev = $article->getStableRev(); |
1481 | | - # Diff between two revisions |
1482 | | - if ( $oldRev && $newRev ) { |
1483 | | - list( $msg, $class ) = self::getDiffRevMsgAndClass( $oldRev, $srev ); |
1484 | | - $table .= "<table class='fr-diff-ratings'><tr>"; |
1485 | | - $table .= "<td width='50%' align='center'>"; |
1486 | | - $table .= "<span class='$class'>[" . |
1487 | | - wfMsgHtml( $msg ) . "]</span>"; |
1488 | | - |
1489 | | - list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev ); |
1490 | | - $table .= "</td><td width='50%' align='center'>"; |
1491 | | - $table .= "<span class='$class'>[" . |
1492 | | - wfMsgHtml( $msg ) . "]</span>"; |
1493 | | - |
1494 | | - $table .= "</td></tr></table>\n"; |
1495 | | - # New page "diffs" - just one rev |
1496 | | - } elseif ( $newRev ) { |
1497 | | - list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev ); |
1498 | | - $table .= "<table class='fr-diff-ratings'>"; |
1499 | | - $table .= "<tr><td align='center'><span class='$class'>"; |
1500 | | - $table .= '[' . wfMsgHtml( $msg ) . ']'; |
1501 | | - $table .= "</span></td></tr></table>\n"; |
1502 | | - } |
1503 | | - return $table; |
1504 | | - } |
1505 | | - |
1506 | | - protected static function getDiffRevMsgAndClass( |
1507 | | - Revision $rev, FlaggedRevision $srev = null |
1508 | | - ) { |
1509 | | - $tier = FlaggedRevs::getRevQuality( $rev->getPage(), $rev->getId() ); |
1510 | | - if ( $tier !== false ) { |
1511 | | - $msg = $tier |
1512 | | - ? 'revreview-hist-quality' |
1513 | | - : 'revreview-hist-basic'; |
1514 | | - } else { |
1515 | | - $msg = ( $srev && $rev->getTimestamp() > $srev->getRevTimestamp() ) // bug 15515 |
1516 | | - ? 'revreview-hist-pending' |
1517 | | - : 'revreview-hist-draft'; |
1518 | | - } |
1519 | | - $css = FlaggedRevsXML::getQualityColor( $tier ); |
1520 | | - return array( $msg, $css ); |
1521 | | - } |
1522 | | - |
1523 | | - // Fetch template changes for a reviewed revision since review |
1524 | | - // @returns array |
1525 | | - protected static function fetchTemplateChanges( FlaggedRevision $frev ) { |
1526 | | - global $wgUser; |
1527 | | - $skin = $wgUser->getSkin(); |
1528 | | - $diffLinks = array(); |
1529 | | - $changes = $frev->findPendingTemplateChanges(); |
1530 | | - foreach ( $changes as $tuple ) { |
1531 | | - list( $title, $revIdStable ) = $tuple; |
1532 | | - $diffLinks[] = $skin->makeLinkObj( $title, |
1533 | | - $title->getPrefixedText(), |
1534 | | - 'diff=cur&oldid=' . (int)$revIdStable ); |
1535 | | - } |
1536 | | - return $diffLinks; |
1537 | | - } |
1538 | | - |
1539 | | - // Fetch file changes for a reviewed revision since review |
1540 | | - // @returns array |
1541 | | - protected static function fetchFileChanges( FlaggedRevision $frev ) { |
1542 | | - global $wgUser; |
1543 | | - $skin = $wgUser->getSkin(); |
1544 | | - $diffLinks = array(); |
1545 | | - $changes = $frev->findPendingFileChanges( 'noForeign' ); |
1546 | | - foreach ( $changes as $tuple ) { |
1547 | | - list( $title, $revIdStable ) = $tuple; |
1548 | | - // @TODO: change when MW has file diffs |
1549 | | - $diffLinks[] = $skin->makeLinkObj( $title, $title->getPrefixedText() ); |
1550 | | - } |
1551 | | - return $diffLinks; |
1552 | | - } |
1553 | | - |
1554 | | - /** |
1555 | | - * Set $this->isDiffFromStable and $this->isMultiPageDiff fields |
1556 | | - * Note: $oldRev could be false |
1557 | | - */ |
1558 | | - public function setViewFlags( $diff, $oldRev, $newRev ) { |
1559 | | - $this->load(); |
1560 | | - // We only want valid diffs that actually make sense... |
1561 | | - if ( $newRev && $oldRev && $newRev->getTimestamp() >= $oldRev->getTimestamp() ) { |
1562 | | - // Is this a diff between two pages? |
1563 | | - if ( $newRev->getPage() != $oldRev->getPage() ) { |
1564 | | - $this->isMultiPageDiff = true; |
1565 | | - // Is there a stable version? |
1566 | | - } elseif ( $this->article->isReviewable() ) { |
1567 | | - $srev = $this->article->getStableRev(); |
1568 | | - // Is this a diff of a draft rev against the stable rev? |
1569 | | - if ( self::isDiffToStable( $srev, $oldRev, $newRev ) ) { |
1570 | | - $this->isDiffFromStable = true; |
1571 | | - $this->isReviewableDiff = true; |
1572 | | - // Is this a diff of a draft rev against a reviewed rev? |
1573 | | - } elseif ( |
1574 | | - FlaggedRevision::newFromTitle( $diff->getTitle(), $oldRev->getId() ) || |
1575 | | - FlaggedRevision::newFromTitle( $diff->getTitle(), $newRev->getId() ) |
1576 | | - ) { |
1577 | | - $this->isReviewableDiff = true; |
1578 | | - } |
1579 | | - } |
1580 | | - $this->diffRevs = array( 'old' => $oldRev, 'new' => $newRev ); |
1581 | | - } |
1582 | | - return true; |
1583 | | - } |
1584 | | - |
1585 | | - // Is a diff from $oldRev to $newRev a diff-to-stable? |
1586 | | - protected static function isDiffToStable( $srev, $oldRev, $newRev ) { |
1587 | | - return ( $srev && $oldRev && $newRev |
1588 | | - && $oldRev->getPage() == $newRev->getPage() // no multipage diffs |
1589 | | - && $oldRev->getId() == $srev->getRevId() |
1590 | | - && $newRev->getTimestamp() >= $oldRev->getTimestamp() // no backwards diffs |
1591 | | - ); |
1592 | | - } |
1593 | | - |
1594 | | - /** |
1595 | | - * Redirect users out to review the changes to the stable version. |
1596 | | - * Only for people who can review and for pages that have a stable version. |
1597 | | - */ |
1598 | | - public function injectPostEditURLParams( &$sectionAnchor, &$extraQuery ) { |
1599 | | - global $wgUser; |
1600 | | - $this->load(); |
1601 | | - $this->article->loadFromDB( FR_MASTER ); |
1602 | | - # Get the stable version from the master |
1603 | | - $frev = $this->article->getStableRev(); |
1604 | | - if ( !$frev || !$this->article->revsArePending() ) { |
1605 | | - return true; // only for pages with pending edits |
1606 | | - } |
1607 | | - // If the edit was not autoreviewed, and the user can actually make a |
1608 | | - // new stable version, then go to the diff... |
1609 | | - if ( $frev->userCanSetFlags( $wgUser ) ) { |
1610 | | - $extraQuery .= $extraQuery ? '&' : ''; |
1611 | | - // Override diffonly setting to make sure the content is shown |
1612 | | - $extraQuery .= 'oldid=' . $frev->getRevId() . '&diff=cur&diffonly=0&shownotice=1'; |
1613 | | - // ...otherwise, go to the draft revision after completing an edit. |
1614 | | - // This allows for users to immediately see their changes. |
1615 | | - } else { |
1616 | | - $extraQuery .= $extraQuery ? '&' : ''; |
1617 | | - $extraQuery .= 'stable=0'; |
1618 | | - // Show a notice at the top of the page for non-reviewers... |
1619 | | - if ( !$wgUser->isAllowed( 'review' ) && $this->article->isStableShownByDefault() ) { |
1620 | | - $extraQuery .= '&shownotice=1'; |
1621 | | - if ( $sectionAnchor ) { |
1622 | | - // Pass a section parameter in the URL as needed to add a link to |
1623 | | - // the "your changes are pending" box on the top of the page... |
1624 | | - $section = str_replace( |
1625 | | - array( ':' , '.' ), array( '%3A', '%' ), // hack: reverse encoding |
1626 | | - substr( $sectionAnchor, 1 ) // remove the '#' |
1627 | | - ); |
1628 | | - $extraQuery .= '&fromsection=' . $section; |
1629 | | - $sectionAnchor = ''; // go to the top of the page to see notice |
1630 | | - } |
1631 | | - } |
1632 | | - } |
1633 | | - return true; |
1634 | | - } |
1635 | | - |
1636 | | - /** |
1637 | | - * If submitting the edit will leave it pending, then change the button text |
1638 | | - * Note: interacts with 'review pending changes' checkbox |
1639 | | - * @TODO: would be nice if hook passed in button attribs, not XML |
1640 | | - */ |
1641 | | - public function changeSaveButton( EditPage $editPage, array &$buttons ) { |
1642 | | - if ( !$this->editWillRequireReview( $editPage ) ) { |
1643 | | - return true; // edit will go live or be reviewed on save |
1644 | | - } |
1645 | | - if ( extension_loaded( 'domxml' ) ) { |
1646 | | - wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" ); |
1647 | | - return true; # PECL extension conflicts with the core DOM extension (see bug 13770) |
1648 | | - } elseif ( isset( $buttons['save'] ) && extension_loaded( 'dom' ) ) { |
1649 | | - $dom = new DOMDocument(); |
1650 | | - $dom->loadXML( $buttons['save'] ); // load button XML from hook |
1651 | | - foreach ( $dom->getElementsByTagName( 'input' ) as $input ) { // one <input> |
1652 | | - $input->setAttribute( 'value', wfMsg( 'revreview-submitedit' ) ); |
1653 | | - $input->setAttribute( 'title', // keep accesskey |
1654 | | - wfMsgExt( 'revreview-submitedit-title', 'parsemag' ) . |
1655 | | - ' [' . wfMsg( 'accesskey-save' ) . ']' ); |
1656 | | - # Change submit button text & title |
1657 | | - $buttons['save'] = $dom->saveXML( $dom->documentElement ); |
1658 | | - } |
1659 | | - } |
1660 | | - return true; |
1661 | | - } |
1662 | | - |
1663 | | - /** |
1664 | | - * If this edit will not go live on submit (accounting for wpReviewEdit) |
1665 | | - * @param EditPage $editPage |
1666 | | - * @return bool |
1667 | | - */ |
1668 | | - protected function editWillRequireReview( EditPage $editPage ) { |
1669 | | - global $wgRequest; |
1670 | | - $title = $this->article->getTitle(); // convenience |
1671 | | - if ( !$this->editRequiresReview( $editPage ) ) { |
1672 | | - return false; // edit will go live immediatly |
1673 | | - } elseif ( $wgRequest->getCheck( 'wpReviewEdit' ) && $title->userCan( 'review' ) ) { |
1674 | | - return false; // edit checked off to be reviewed on save |
1675 | | - } |
1676 | | - return true; // edit needs review |
1677 | | - } |
1678 | | - |
1679 | | - /** |
1680 | | - * If this edit will not go live on submit unless wpReviewEdit is checked |
1681 | | - * @param EditPage $editPage |
1682 | | - * @return bool |
1683 | | - */ |
1684 | | - protected function editRequiresReview( EditPage $editPage ) { |
1685 | | - if ( !$this->article->editsRequireReview() ) { |
1686 | | - return false; // edits go live immediatly |
1687 | | - } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) { |
1688 | | - return false; // edit will be autoreviewed anyway |
1689 | | - } |
1690 | | - return true; // edit needs review |
1691 | | - } |
1692 | | - |
1693 | | - /** |
1694 | | - * If this edit will be auto-reviewed on submit |
1695 | | - * Note: checking wpReviewEdit does not count as auto-reviewed |
1696 | | - * @param EditPage $editPage |
1697 | | - * @return bool |
1698 | | - */ |
1699 | | - protected function editWillBeAutoreviewed( EditPage $editPage ) { |
1700 | | - $title = $this->article->getTitle(); // convenience |
1701 | | - if ( !$this->article->isReviewable() ) { |
1702 | | - return false; |
1703 | | - } |
1704 | | - if ( $title->userCan( 'autoreview' ) ) { |
1705 | | - if ( FlaggedRevs::autoReviewNewPages() && !$this->article->exists() ) { |
1706 | | - return true; // edit will be autoreviewed |
1707 | | - } |
1708 | | - if ( !isset( $editPage->fr_baseFRev ) ) { |
1709 | | - $baseRevId = self::getBaseRevId( $editPage ); |
1710 | | - $editPage->fr_baseFRev = FlaggedRevision::newFromTitle( $title, $baseRevId ); |
1711 | | - } |
1712 | | - if ( $editPage->fr_baseFRev ) { |
1713 | | - return true; // edit will be autoreviewed |
1714 | | - } |
1715 | | - } |
1716 | | - return false; // edit won't be autoreviewed |
1717 | | - } |
1718 | | - |
1719 | | - /** |
1720 | | - * Add a "review pending changes" checkbox to the edit form iff: |
1721 | | - * (a) there are currently any revisions pending (bug 16713) |
1722 | | - * (b) this is an unreviewed page (bug 23970) |
1723 | | - */ |
1724 | | - public function addReviewCheck( EditPage $editPage, array &$checkboxes, &$tabindex ) { |
1725 | | - global $wgRequest; |
1726 | | - $title = $this->article->getTitle(); // convenience |
1727 | | - if ( !$this->article->isReviewable() || !$title->userCan( 'review' ) ) { |
1728 | | - return true; // not needed |
1729 | | - } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) { |
1730 | | - return true; // edit will be auto-reviewed |
1731 | | - } |
1732 | | - if ( self::getBaseRevId( $editPage ) == $this->article->getLatest() ) { |
1733 | | - # For pages with either no stable version, or an outdated one, let |
1734 | | - # the user decide if he/she wants it reviewed on the spot. One might |
1735 | | - # do this if he/she just saw the diff-to-stable and *then* decided to edit. |
1736 | | - # Note: check not shown when editing old revisions, which is confusing. |
1737 | | - $checkbox = Xml::check( |
1738 | | - 'wpReviewEdit', |
1739 | | - $wgRequest->getCheck( 'wpReviewEdit' ), |
1740 | | - array( 'tabindex' => ++$tabindex, 'id' => 'wpReviewEdit' ) |
1741 | | - ); |
1742 | | - $attribs = array( 'for' => 'wpReviewEdit' ); |
1743 | | - // For reviewed pages... |
1744 | | - if ( $this->article->getStable() ) { |
1745 | | - // For pending changes... |
1746 | | - if ( $this->article->revsArePending() ) { |
1747 | | - $n = $this->article->getPendingRevCount(); |
1748 | | - $attribs['title'] = wfMsg( 'revreview-check-flag-p-title' ); |
1749 | | - $labelMsg = wfMsgExt( 'revreview-check-flag-p', 'parseinline', $n ); |
1750 | | - // For just the user's changes... |
1751 | | - } else { |
1752 | | - $attribs['title'] = wfMsgExt( 'revreview-check-flag-y-title', 'parsemag' ); |
1753 | | - $labelMsg = wfMsgExt( 'revreview-check-flag-y', 'parseinline' ); |
1754 | | - } |
1755 | | - // For unreviewed pages... |
1756 | | - } else { |
1757 | | - $attribs['title'] = wfMsg( 'revreview-check-flag-u-title' ); |
1758 | | - $labelMsg = wfMsgExt( 'revreview-check-flag-u', 'parseinline' ); |
1759 | | - } |
1760 | | - $label = Xml::element( 'label', $attribs, $labelMsg ); |
1761 | | - $checkboxes['reviewed'] = $checkbox . ' ' . $label; |
1762 | | - } |
1763 | | - return true; |
1764 | | - } |
1765 | | - |
1766 | | - /** |
1767 | | - * (a) Add a hidden field that has the rev ID the text is based off. |
1768 | | - * (b) If an edit was undone, add a hidden field that has the rev ID of that edit. |
1769 | | - * Needed for autoreview and user stats (for autopromote). |
1770 | | - * Note: baseRevId trusted for Reviewers - text checked for others. |
1771 | | - */ |
1772 | | - public function addRevisionIDField( EditPage $editPage, OutputPage $out ) { |
1773 | | - $this->load(); |
1774 | | - $revId = self::getBaseRevId( $editPage ); |
1775 | | - $out->addHTML( "\n" . Html::hidden( 'baseRevId', $revId ) ); |
1776 | | - $out->addHTML( "\n" . Html::hidden( 'undidRev', |
1777 | | - empty( $editPage->undidRev ) ? 0 : $editPage->undidRev ) |
1778 | | - ); |
1779 | | - return true; |
1780 | | - } |
1781 | | - |
1782 | | - /** |
1783 | | - * Guess the rev ID the text of this form is based off |
1784 | | - * Note: baseRevId trusted for Reviewers - check text for others. |
1785 | | - * @return int |
1786 | | - */ |
1787 | | - protected static function getBaseRevId( EditPage $editPage ) { |
1788 | | - global $wgRequest; |
1789 | | - if ( !isset( $editPage->fr_baseRevId ) ) { |
1790 | | - $article = $editPage->getArticle(); // convenience |
1791 | | - $latestId = $article->getLatest(); // current rev |
1792 | | - $undo = $wgRequest->getIntOrNull( 'undo' ); |
1793 | | - # Undoing consecutive top edits... |
1794 | | - if ( $undo && $undo === $latestId ) { |
1795 | | - # Treat this like a revert to a base revision. |
1796 | | - # We are undoing all edits *after* some rev ID (undoafter). |
1797 | | - # If undoafter is not given, then it is the previous rev ID. |
1798 | | - $revId = $wgRequest->getInt( 'undoafter', |
1799 | | - $article->getTitle()->getPreviousRevisionID( $latestId, Title::GAID_FOR_UPDATE ) ); |
1800 | | - # Undoing other edits... |
1801 | | - } elseif ( $undo ) { |
1802 | | - $revId = $latestId; // current rev is the base rev |
1803 | | - # Other edits... |
1804 | | - } else { |
1805 | | - # If we are editing via oldid=X, then use that rev ID. |
1806 | | - # Otherwise, check if the client specified the ID (bug 23098). |
1807 | | - $revId = $article->getOldID() |
1808 | | - ? $article->getOldID() |
1809 | | - : $wgRequest->getInt( 'baseRevId' ); // e.g. "show changes"/"preview" |
1810 | | - } |
1811 | | - # Zero oldid => draft revision |
1812 | | - if ( !$revId ) { |
1813 | | - $revId = $latestId; |
1814 | | - } |
1815 | | - $editPage->fr_baseRevId = $revId; |
1816 | | - } |
1817 | | - return $editPage->fr_baseRevId; |
1818 | | - } |
1819 | | - |
1820 | | - /** |
1821 | | - * Adds brief review notes to a page. |
1822 | | - * @param OutputPage $out |
1823 | | - */ |
1824 | | - public function addReviewNotes( &$data ) { |
1825 | | - $this->load(); |
1826 | | - if ( $this->reviewNotes ) { |
1827 | | - $data .= $this->reviewNotes; |
1828 | | - } |
1829 | | - return true; |
1830 | | - } |
1831 | | - |
1832 | | - /* |
1833 | | - * If this is a diff page then replace the article contents with a link |
1834 | | - * to the specific revision. This will be replaced with article content |
1835 | | - * using javascript and an api call. |
1836 | | - */ |
1837 | | - public function addCustomContentHtml( OutputPage $out, $newRevId ) { |
1838 | | - $this->load(); |
1839 | | - if ( $newRevId ) { |
1840 | | - $out->addHTML( "<div id='mw-fr-revisioncontents'><span class='plainlinks'>" ); |
1841 | | - $out->addWikiMsg( 'revcontents-getcontents', |
1842 | | - $this->article->getTitle()->getPrefixedDBKey(), $newRevId ); |
1843 | | - $out->addHTML( "</span></div>" ); |
1844 | | - } |
1845 | | - } |
1846 | | -} |
Index: trunk/extensions/FlaggedRevs/presentation/RevisionReviewFormGUI.php |
— | — | @@ -13,10 +13,10 @@ |
14 | 14 | /** |
15 | 15 | * Generates a brief review form for a page |
16 | 16 | * @param User $user |
17 | | - * @param FlaggedArticle $article |
| 17 | + * @param FlaggedPage $article |
18 | 18 | * @param Revision $rev |
19 | 19 | */ |
20 | | - public function __construct( User $user, FlaggedArticle $article, Revision $rev ) { |
| 20 | + public function __construct( User $user, FlaggedPage $article, Revision $rev ) { |
21 | 21 | $this->user = $user; |
22 | 22 | $this->article = $article; |
23 | 23 | $this->rev = $rev; |
— | — | @@ -51,7 +51,7 @@ |
52 | 52 | |
53 | 53 | /** |
54 | 54 | * Generates a brief review form for a page |
55 | | - * @return Array (html string, error string or true) |
| 55 | + * @return array (html string, error string or true) |
56 | 56 | */ |
57 | 57 | public function getHtml() { |
58 | 58 | global $wgOut, $wgLang, $wgParser, $wgEnableParserCache; |
— | — | @@ -220,7 +220,7 @@ |
221 | 221 | * @param array $flags, selected flags |
222 | 222 | * @param bool $disabled, form disabled |
223 | 223 | * @param bool $reviewed, rev already reviewed |
224 | | - * @returns string |
| 224 | + * @return string |
225 | 225 | * Generates a main tag inputs (checkboxes/radios/selects) for review form |
226 | 226 | */ |
227 | 227 | protected static function ratingInputs( $user, $flags, $disabled, $reviewed ) { |
— | — | @@ -328,7 +328,7 @@ |
329 | 329 | * @param FlaggedRevision $frev, the flagged revision, if any |
330 | 330 | * @param bool $disabled, is the form disabled? |
331 | 331 | * @param bool $reviewIncludes, force the review button to be usable? |
332 | | - * @returns string |
| 332 | + * @return string |
333 | 333 | */ |
334 | 334 | protected static function submitButtons( |
335 | 335 | $rejectId, $frev, $disabled, $reviewIncludes = false |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsXML.php |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | * Get a selector of reviewable namespaces |
10 | 10 | * @param int $selected, namespace selected |
11 | 11 | * @param $all Mixed: Value of an item denoting all namespaces, or null to omit |
12 | | - * @returns string |
| 12 | + * @return string |
13 | 13 | */ |
14 | 14 | public static function getNamespaceMenu( $selected = null, $all = null ) { |
15 | 15 | global $wgContLang; |
— | — | @@ -50,7 +50,7 @@ |
51 | 51 | * @param int $selected, selected level |
52 | 52 | * @param string $all, all selector msg? |
53 | 53 | * @param int $max max level? |
54 | | - * @returns string |
| 54 | + * @return string |
55 | 55 | */ |
56 | 56 | public static function getLevelMenu( |
57 | 57 | $selected = null, $all = 'revreview-filter-all', $max = 2 |
— | — | @@ -72,7 +72,7 @@ |
73 | 73 | /** |
74 | 74 | * Get a <select> of default page version (stable or draft). Used for filters. |
75 | 75 | * @param int $selected (0=draft, 1=stable, null=either ) |
76 | | - * @returns string |
| 76 | + * @return string |
77 | 77 | */ |
78 | 78 | public static function getDefaultFilterMenu( $selected = null ) { |
79 | 79 | if ( is_null( $selected ) ) { |
— | — | @@ -91,7 +91,7 @@ |
92 | 92 | /** |
93 | 93 | * Get a <select> of options of 'autoreview' restriction levels. Used for filters. |
94 | 94 | * @param string $selected ('' for "any", 'none' for none) |
95 | | - * @returns string |
| 95 | + * @return string |
96 | 96 | */ |
97 | 97 | public static function getRestrictionFilterMenu( $selected = '' ) { |
98 | 98 | if ( is_null( $selected ) ) { |
— | — | @@ -121,7 +121,7 @@ |
122 | 122 | /** |
123 | 123 | * Get a selector of "approved"/"unapproved". Used for filters. |
124 | 124 | * @param int $selected, selected level |
125 | | - * @returns string |
| 125 | + * @return string |
126 | 126 | */ |
127 | 127 | public static function getStatusFilterMenu( $selected = null ) { |
128 | 128 | $s = "<label for='wpStatus'>" . wfMsgHtml( 'revreview-statusfilter' ) . "</label>\n"; |
— | — | @@ -137,7 +137,7 @@ |
138 | 138 | /** |
139 | 139 | * Get a selector of "auto"/"manual". Used for filters. |
140 | 140 | * @param int $selected, selected level |
141 | | - * @returns string |
| 141 | + * @return string |
142 | 142 | */ |
143 | 143 | public static function getAutoFilterMenu( $selected = null ) { |
144 | 144 | $s = "<label for='wpApproved'>" . wfMsgHtml( 'revreview-typefilter' ) . "</label>\n"; |
— | — | @@ -151,7 +151,7 @@ |
152 | 152 | |
153 | 153 | /** |
154 | 154 | * @param int $quality |
155 | | - * @returns string, css color for this quality |
| 155 | + * @return string, css color for this quality |
156 | 156 | */ |
157 | 157 | public static function getQualityColor( $quality ) { |
158 | 158 | if ( $quality === false ) |
— | — | @@ -174,7 +174,7 @@ |
175 | 175 | * @param array $flags |
176 | 176 | * @param bool $prettybox |
177 | 177 | * @param string $css, class to wrap box in |
178 | | - * @returns string |
| 178 | + * @return string |
179 | 179 | * Generates a review box/tag |
180 | 180 | */ |
181 | 181 | public static function addTagRatings( $flags, $prettyBox = false, $css = '' ) { |
— | — | @@ -213,7 +213,7 @@ |
214 | 214 | * @param string $type (stable/draft/oldstable) |
215 | 215 | * @param bool $stable, are we referring to the stable revision? |
216 | 216 | * @param bool $synced, does stable=current and this is one of them? |
217 | | - * @returns string |
| 217 | + * @return string |
218 | 218 | * Generates a review box using a table using FlaggedRevsXML::addTagRatings() |
219 | 219 | */ |
220 | 220 | public static function prettyRatingBox( |
— | — | @@ -284,7 +284,7 @@ |
285 | 285 | |
286 | 286 | /** |
287 | 287 | * Generates JS toggle arrow icon |
288 | | - * @returns string |
| 288 | + * @return string |
289 | 289 | */ |
290 | 290 | public static function ratingArrow() { |
291 | 291 | $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' ); |
— | — | @@ -297,7 +297,7 @@ |
298 | 298 | |
299 | 299 | /** |
300 | 300 | * Generates (+/-) JS toggle HTML (monospace to keep things in place) |
301 | | - * @returns string |
| 301 | + * @return string |
302 | 302 | */ |
303 | 303 | public static function ratingToggle() { |
304 | 304 | return '<a id="mw-fr-revisiontoggle" class="fr-toggle-symbol"' . |
— | — | @@ -308,7 +308,7 @@ |
309 | 309 | |
310 | 310 | /** |
311 | 311 | * Generates (show/hide) JS toggle HTML |
312 | | - * @returns string |
| 312 | + * @return string |
313 | 313 | */ |
314 | 314 | public static function diffToggle() { |
315 | 315 | $toggle = '<a class="fr-toggle-text" ' . |
— | — | @@ -321,7 +321,7 @@ |
322 | 322 | |
323 | 323 | /** |
324 | 324 | * Generates (show/hide) JS toggle HTML |
325 | | - * @returns string |
| 325 | + * @return string |
326 | 326 | */ |
327 | 327 | public static function logToggle() { |
328 | 328 | $toggle = '<a class="fr-toggle-text" ' . |
— | — | @@ -334,7 +334,7 @@ |
335 | 335 | |
336 | 336 | /** |
337 | 337 | * Generates (show/hide) JS toggle HTML |
338 | | - * @returns string |
| 338 | + * @return string |
339 | 339 | */ |
340 | 340 | public static function logDetailsToggle() { |
341 | 341 | $toggle = '<a class="fr-toggle-text" ' . |
— | — | @@ -347,7 +347,7 @@ |
348 | 348 | |
349 | 349 | /* |
350 | 350 | * Creates CSS draft page icon |
351 | | - * @returns string |
| 351 | + * @return string |
352 | 352 | */ |
353 | 353 | public static function draftStatusIcon() { |
354 | 354 | $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' ); |
— | — | @@ -359,7 +359,7 @@ |
360 | 360 | /* |
361 | 361 | * Creates CSS stable page icon |
362 | 362 | * @param bool $isQuality |
363 | | - * @returns string |
| 363 | + * @return string |
364 | 364 | */ |
365 | 365 | public static function stableStatusIcon( $isQuality ) { |
366 | 366 | $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' ); |
— | — | @@ -373,8 +373,8 @@ |
374 | 374 | |
375 | 375 | /* |
376 | 376 | * Creates CSS lock icon if page is locked/unlocked |
377 | | - * @param FlaggedArticle $flaggedArticle |
378 | | - * @returns string |
| 377 | + * @param FlaggedPage $flaggedArticle |
| 378 | + * @return string |
379 | 379 | */ |
380 | 380 | public static function lockStatusIcon( $flaggedArticle ) { |
381 | 381 | $encPath = htmlspecialchars( FlaggedRevs::styleUrlPath() . '/img' ); |
— | — | @@ -390,10 +390,10 @@ |
391 | 391 | } |
392 | 392 | |
393 | 393 | /* |
394 | | - * @param FlaggedArticle $flaggedArticle |
| 394 | + * @param FlaggedPage $flaggedArticle |
395 | 395 | * @param FlaggedRevision $frev |
396 | 396 | * @param int $revsSince |
397 | | - * @returns string |
| 397 | + * @return string |
398 | 398 | * Creates "stable rev reviewed on"/"x pending edits" message |
399 | 399 | */ |
400 | 400 | public static function pendingEditNotice( $flaggedArticle, $frev, $revsSince ) { |
— | — | @@ -410,7 +410,7 @@ |
411 | 411 | |
412 | 412 | /* |
413 | 413 | * @param Article $article |
414 | | - * @returns string |
| 414 | + * @return string |
415 | 415 | * Creates a stability log excerpt |
416 | 416 | */ |
417 | 417 | public static function stabilityLogExcerpt( $article ) { |
Index: trunk/extensions/FlaggedRevs/presentation/specialpages/reports/QualityOversight_body.php |
— | — | @@ -86,7 +86,7 @@ |
87 | 87 | |
88 | 88 | /* |
89 | 89 | * Get actions for IN clause |
90 | | - * @returns array |
| 90 | + * @return array |
91 | 91 | */ |
92 | 92 | private function getActions() { |
93 | 93 | $actions = array( |
Index: trunk/extensions/FlaggedRevs/presentation/RejectConfirmationFormGUI.php |
— | — | @@ -13,7 +13,7 @@ |
14 | 14 | |
15 | 15 | /** |
16 | 16 | * Get the "are you sure you want to reject these changes?" form |
17 | | - * @return Array (html string, error string or true) |
| 17 | + * @return array (html string, error string or true) |
18 | 18 | */ |
19 | 19 | public function getHtml() { |
20 | 20 | global $wgLang, $wgContLang; |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php |
— | — | @@ -0,0 +1,1845 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class representing a web view of a MediaWiki page |
| 5 | + */ |
| 6 | +class FlaggedPageView { |
| 7 | + protected $article = null; |
| 8 | + |
| 9 | + protected $diffRevs = null; // assoc array of old and new Revisions for diffs |
| 10 | + protected $isReviewableDiff = false; |
| 11 | + protected $isDiffFromStable = false; |
| 12 | + protected $isMultiPageDiff = false; |
| 13 | + protected $reviewNotice = ''; |
| 14 | + protected $reviewNotes = ''; |
| 15 | + protected $diffNoticeBox = ''; |
| 16 | + protected $reviewFormRev = false; |
| 17 | + |
| 18 | + protected $loaded = false; |
| 19 | + |
| 20 | + protected static $instance = null; |
| 21 | + |
| 22 | + /* |
| 23 | + * Get the FlaggedPageView for this request |
| 24 | + */ |
| 25 | + public static function singleton() { |
| 26 | + if ( self::$instance == null ) { |
| 27 | + self::$instance = new self(); |
| 28 | + } |
| 29 | + return self::$instance; |
| 30 | + } |
| 31 | + protected function __construct() { } |
| 32 | + protected function __clone() { } |
| 33 | + |
| 34 | + /* |
| 35 | + * Clear the FlaggedPageView for this request. |
| 36 | + * Only needed when page redirection changes the environment. |
| 37 | + */ |
| 38 | + public function clear() { |
| 39 | + self::$instance = null; |
| 40 | + } |
| 41 | + |
| 42 | + /* |
| 43 | + * Load the global FlaggedPage instance |
| 44 | + */ |
| 45 | + protected function load() { |
| 46 | + if ( !$this->loaded ) { |
| 47 | + $this->loaded = true; |
| 48 | + $this->article = self::globalArticleInstance(); |
| 49 | + if ( $this->article == null ) { |
| 50 | + throw new MWException( 'FlaggedPageView has no context article!' ); |
| 51 | + } |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + /** |
| 56 | + * Get the FlaggedPage instance associated with $wgArticle/$wgTitle, |
| 57 | + * or false if there isn't such a title |
| 58 | + */ |
| 59 | + public static function globalArticleInstance() { |
| 60 | + global $wgTitle; |
| 61 | + if ( !empty( $wgTitle ) ) { |
| 62 | + return FlaggedPage::getTitleInstance( $wgTitle ); |
| 63 | + } |
| 64 | + return null; |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + * Is this web response for a request to view a page where both: |
| 69 | + * (a) no specific page version was requested via URL params |
| 70 | + * (b) a stable version exists and is to be displayed |
| 71 | + * This factors in site/page config, user preferences, and web request params. |
| 72 | + * @return bool |
| 73 | + */ |
| 74 | + protected function showingStableAsDefault() { |
| 75 | + global $wgUser, $wgRequest; |
| 76 | + $this->load(); |
| 77 | + # This only applies to viewing the default version of pages... |
| 78 | + if ( !$this->isDefaultPageView( $wgRequest ) ) { |
| 79 | + return false; |
| 80 | + # ...and the page must be reviewable and have a stable version |
| 81 | + } elseif ( !$this->article->getStableRev() ) { |
| 82 | + return false; |
| 83 | + } |
| 84 | + # Check user preferences ("show stable by default?") |
| 85 | + if ( $wgUser->getOption( 'flaggedrevsstable' ) ) { |
| 86 | + return true; |
| 87 | + } |
| 88 | + # Viewer may be in a group that sees the draft by default |
| 89 | + if ( $this->userViewsDraftByDefault( $wgUser ) ) { |
| 90 | + return false; |
| 91 | + } |
| 92 | + # Does the stable version override the draft? |
| 93 | + $config = $this->article->getStabilitySettings(); |
| 94 | + return (bool)$config['override']; |
| 95 | + } |
| 96 | + |
| 97 | + /** |
| 98 | + * Is this web response for a request to view a page where both: |
| 99 | + * (a) the stable version of a page was requested (?stable=1) |
| 100 | + * (b) the stable version exists and is to be displayed |
| 101 | + * @return bool |
| 102 | + */ |
| 103 | + protected function showingStableByRequest() { |
| 104 | + global $wgRequest; |
| 105 | + $this->load(); |
| 106 | + # Are we explicity requesting the stable version? |
| 107 | + if ( $wgRequest->getIntOrNull( 'stable' ) === 1 ) { |
| 108 | + # This only applies to viewing a version of the page... |
| 109 | + if ( !$this->isPageView( $wgRequest ) ) { |
| 110 | + return false; |
| 111 | + # ...with no version parameters other than ?stable=1... |
| 112 | + } elseif ( $wgRequest->getVal( 'oldid' ) || $wgRequest->getVal( 'stableid' ) ) { |
| 113 | + return false; // over-determined |
| 114 | + # ...and the page must be reviewable and have a stable version |
| 115 | + } elseif ( !$this->article->getStableRev() ) { |
| 116 | + return false; |
| 117 | + } |
| 118 | + return true; // show stable version |
| 119 | + } |
| 120 | + return false; |
| 121 | + } |
| 122 | + |
| 123 | + /** |
| 124 | + * Is this web response for a request to view a page |
| 125 | + * where a stable version exists and is to be displayed |
| 126 | + * @return bool |
| 127 | + */ |
| 128 | + public function showingStable() { |
| 129 | + return $this->showingStableByRequest() || $this->showingStableAsDefault(); |
| 130 | + } |
| 131 | + |
| 132 | + /** |
| 133 | + * Should this be using a simple icon-based UI? |
| 134 | + * Check the user's preferences first, using the site settings as the default. |
| 135 | + * @return bool |
| 136 | + */ |
| 137 | + public function useSimpleUI() { |
| 138 | + global $wgUser, $wgSimpleFlaggedRevsUI; |
| 139 | + return $wgUser->getOption( 'flaggedrevssimpleui', intval( $wgSimpleFlaggedRevsUI ) ); |
| 140 | + } |
| 141 | + |
| 142 | + /** |
| 143 | + * Should this user see the draft revision of pages by default? |
| 144 | + * @param $user User |
| 145 | + * @return bool |
| 146 | + */ |
| 147 | + protected function userViewsDraftByDefault( $user ) { |
| 148 | + global $wgFlaggedRevsExceptions; |
| 149 | + # Check user preferences ("show stable by default?") |
| 150 | + if ( $user->getOption( 'flaggedrevsstable' ) ) { |
| 151 | + return false; |
| 152 | + } |
| 153 | + # Viewer sees current by default (editors, insiders, ect...) ? |
| 154 | + foreach ( $wgFlaggedRevsExceptions as $group ) { |
| 155 | + if ( $group == 'user' ) { |
| 156 | + if ( $user->getId() ) { |
| 157 | + return true; |
| 158 | + } |
| 159 | + } elseif ( in_array( $group, $user->getGroups() ) ) { |
| 160 | + return true; |
| 161 | + } |
| 162 | + } |
| 163 | + return false; |
| 164 | + } |
| 165 | + |
| 166 | + /** |
| 167 | + * Is this a view page action (including diffs)? |
| 168 | + * @param $request WebRequest |
| 169 | + * @return bool |
| 170 | + */ |
| 171 | + protected function isPageViewOrDiff( WebRequest $request ) { |
| 172 | + global $mediaWiki; |
| 173 | + $action = isset( $mediaWiki ) |
| 174 | + ? $mediaWiki->getAction( $request ) |
| 175 | + : $request->getVal( 'action', 'view' ); // cli |
| 176 | + return self::isViewAction( $action ); |
| 177 | + } |
| 178 | + |
| 179 | + /** |
| 180 | + * Is this a view page action (not including diffs)? |
| 181 | + * @param $request WebRequest |
| 182 | + * @return bool |
| 183 | + */ |
| 184 | + protected function isPageView( WebRequest $request ) { |
| 185 | + return $this->isPageViewOrDiff( $request ) |
| 186 | + && $request->getVal( 'diff' ) === null; |
| 187 | + } |
| 188 | + |
| 189 | + /** |
| 190 | + * Is this a web request to just *view* the *default* version of a page? |
| 191 | + * @param $request WebRequest |
| 192 | + * @return bool |
| 193 | + */ |
| 194 | + protected function isDefaultPageView( WebRequest $request ) { |
| 195 | + global $mediaWiki; |
| 196 | + $action = isset( $mediaWiki ) |
| 197 | + ? $mediaWiki->getAction( $request ) |
| 198 | + : $request->getVal( 'action', 'view' ); // cli |
| 199 | + return ( self::isViewAction( $action ) |
| 200 | + && $request->getVal( 'oldid' ) === null |
| 201 | + && $request->getVal( 'stable' ) === null |
| 202 | + && $request->getVal( 'stableid' ) === null |
| 203 | + && $request->getVal( 'diff' ) === null |
| 204 | + ); |
| 205 | + } |
| 206 | + |
| 207 | + /** |
| 208 | + * Is this a view page action? |
| 209 | + * @param $action string from MediaWiki::getAction() |
| 210 | + * @return bool |
| 211 | + */ |
| 212 | + protected static function isViewAction( $action ) { |
| 213 | + return ( $action == 'view' || $action == 'purge' || $action == 'render' ); |
| 214 | + } |
| 215 | + |
| 216 | + /** |
| 217 | + * Output review notice |
| 218 | + */ |
| 219 | + public function displayTag() { |
| 220 | + global $wgOut; |
| 221 | + $this->load(); |
| 222 | + // Sanity check that this is a reviewable page |
| 223 | + if ( $this->article->isReviewable() ) { |
| 224 | + $wgOut->appendSubtitle( $this->reviewNotice ); |
| 225 | + } |
| 226 | + return true; |
| 227 | + } |
| 228 | + |
| 229 | + /** |
| 230 | + * Add a stable link when viewing old versions of an article that |
| 231 | + * have been reviewed. (e.g. for &oldid=x urls) |
| 232 | + */ |
| 233 | + public function addStableLink() { |
| 234 | + global $wgRequest, $wgOut, $wgLang; |
| 235 | + $this->load(); |
| 236 | + if ( !$this->article->isReviewable() || !$wgRequest->getVal( 'oldid' ) ) { |
| 237 | + return true; |
| 238 | + } |
| 239 | + # We may have nav links like "direction=prev&oldid=x" |
| 240 | + $revID = $this->article->getOldIDFromRequest(); |
| 241 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $revID ); |
| 242 | + # Give a notice if this rev ID corresponds to a reviewed version... |
| 243 | + if ( $frev ) { |
| 244 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 245 | + $flags = $frev->getTags(); |
| 246 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 247 | + $msg = $quality ? 'revreview-quality-source' : 'revreview-basic-source'; |
| 248 | + $tag = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time ); |
| 249 | + # Hide clutter |
| 250 | + if ( !$this->useSimpleUI() && !empty( $flags ) ) { |
| 251 | + $tag .= FlaggedRevsXML::ratingToggle() . |
| 252 | + "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
| 253 | + wfMsgHtml( 'revreview-oldrating' ) . |
| 254 | + FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
| 255 | + } |
| 256 | + $css = 'flaggedrevs_notice plainlinks noprint'; |
| 257 | + $tag = "<div id='mw-fr-revisiontag-old' class='$css'>$tag</div>"; |
| 258 | + $wgOut->addHTML( $tag ); |
| 259 | + } |
| 260 | + return true; |
| 261 | + } |
| 262 | + |
| 263 | + /** |
| 264 | + * @return mixed int/false/null |
| 265 | + */ |
| 266 | + protected function getRequestedStableId() { |
| 267 | + global $wgRequest; |
| 268 | + $reqId = $wgRequest->getVal( 'stableid' ); |
| 269 | + if ( $reqId === "best" ) { |
| 270 | + $reqId = FlaggedRevs::getPrimeFlaggedRevId( $this->article ); |
| 271 | + } |
| 272 | + return $reqId; |
| 273 | + } |
| 274 | + |
| 275 | + /** |
| 276 | + * Replaces a page with the last stable version if possible |
| 277 | + * Adds stable version status/info tags and notes |
| 278 | + * Adds a quick review form on the bottom if needed |
| 279 | + */ |
| 280 | + public function setPageContent( &$outputDone, &$useParserCache ) { |
| 281 | + global $wgRequest, $wgOut, $wgContLang; |
| 282 | + $this->load(); |
| 283 | + # Only trigger on page views with no oldid=x param |
| 284 | + if ( !$this->isPageView( $wgRequest ) || $wgRequest->getVal( 'oldid' ) ) { |
| 285 | + return true; |
| 286 | + # Only trigger for reviewable pages that exist |
| 287 | + } elseif ( !$this->article->exists() || !$this->article->isReviewable() ) { |
| 288 | + return true; |
| 289 | + } |
| 290 | + $tag = ''; |
| 291 | + $old = $stable = false; |
| 292 | + # Check the newest stable version. |
| 293 | + $srev = $this->article->getStableRev(); |
| 294 | + $stableId = $srev ? $srev->getRevId() : 0; |
| 295 | + $frev = $srev; // $frev is the revision we are looking at |
| 296 | + # Check for any explicitly requested reviewed version (stableid=X)... |
| 297 | + $reqId = $this->getRequestedStableId(); |
| 298 | + if ( $reqId ) { |
| 299 | + if ( !$stableId ) { |
| 300 | + $reqId = false; // must be invalid |
| 301 | + # Treat requesting the stable version by ID as &stable=1 |
| 302 | + } else if ( $reqId != $stableId ) { |
| 303 | + $old = true; // old reviewed version requested by ID |
| 304 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId ); |
| 305 | + if ( !$frev ) { |
| 306 | + $reqId = false; // invalid ID given |
| 307 | + } |
| 308 | + } else { |
| 309 | + $stable = true; // stable version requested by ID |
| 310 | + } |
| 311 | + } |
| 312 | + // $reqId is null if nothing requested, false if invalid |
| 313 | + if ( $reqId === false ) { |
| 314 | + $wgOut->addWikiText( wfMsg( 'revreview-invalid' ) ); |
| 315 | + $wgOut->returnToMain( false, $this->article->getTitle() ); |
| 316 | + # Tell MW that parser output is done |
| 317 | + $outputDone = true; |
| 318 | + $useParserCache = false; |
| 319 | + return true; |
| 320 | + } |
| 321 | + // Is the page config altered? |
| 322 | + $prot = FlaggedRevsXML::lockStatusIcon( $this->article ); |
| 323 | + // Is there no stable version? |
| 324 | + if ( !$frev ) { |
| 325 | + # Add "no reviewed version" tag, but not for printable output |
| 326 | + $this->showUnreviewedPage( $tag, $prot ); |
| 327 | + return true; |
| 328 | + } |
| 329 | + # Get flags and date |
| 330 | + $flags = $frev->getTags(); |
| 331 | + # Get quality level |
| 332 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 333 | + $pristine = FlaggedRevs::isPristine( $flags ); |
| 334 | + // Looking at some specific old stable revision ("&stableid=x") |
| 335 | + // set to override given the relevant conditions. If the user is |
| 336 | + // requesting the stable revision ("&stableid=x"), defer to override |
| 337 | + // behavior below, since it is the same as ("&stable=1"). |
| 338 | + if ( $old ) { |
| 339 | + $this->showOldReviewedVersion( $srev, $frev, $tag, $prot ); |
| 340 | + $outputDone = true; # Tell MW that parser output is done |
| 341 | + $useParserCache = false; |
| 342 | + // Stable version requested by ID or relevant conditions met to |
| 343 | + // to override page view with the stable version. |
| 344 | + } else if ( $stable || $this->showingStable() ) { |
| 345 | + $this->showStableVersion( $srev, $tag, $prot ); |
| 346 | + $outputDone = true; # Tell MW that parser output is done |
| 347 | + $useParserCache = false; |
| 348 | + // Looking at some specific old revision (&oldid=x) or if FlaggedRevs is not |
| 349 | + // set to override given the relevant conditions (like &stable=0) or there |
| 350 | + // is no stable version. |
| 351 | + } else { |
| 352 | + $this->showDraftVersion( $srev, $tag, $prot ); |
| 353 | + } |
| 354 | + $encJS = ''; // JS events to use |
| 355 | + # Some checks for which tag CSS to use |
| 356 | + if ( $this->useSimpleUI() ) { |
| 357 | + $tagClass = 'flaggedrevs_short'; |
| 358 | + # Collapse the box details on mouseOut |
| 359 | + $encJS .= ' onmouseout="FlaggedRevs.onBoxMouseOut(event)"'; |
| 360 | + } elseif ( $pristine ) { |
| 361 | + $tagClass = 'flaggedrevs_pristine'; |
| 362 | + } elseif ( $quality ) { |
| 363 | + $tagClass = 'flaggedrevs_quality'; |
| 364 | + } else { |
| 365 | + $tagClass = 'flaggedrevs_basic'; |
| 366 | + } |
| 367 | + # Wrap tag contents in a div |
| 368 | + if ( $tag != '' ) { |
| 369 | + $rtl = $wgContLang->isRTL() ? " rtl" : ""; // RTL langauges |
| 370 | + $css = "{$tagClass}{$rtl} plainlinks noprint"; |
| 371 | + $notice = "<div id=\"mw-fr-revisiontag\" class=\"{$css}\"{$encJS}>{$tag}</div>\n"; |
| 372 | + $this->reviewNotice .= $notice; |
| 373 | + } |
| 374 | + return true; |
| 375 | + } |
| 376 | + |
| 377 | + /** |
| 378 | + * If the page has a stable version and it shows by default, |
| 379 | + * tell search crawlers to index only that version of the page. |
| 380 | + * Also index the draft as well if they are synced (bug 27173). |
| 381 | + * However, any URL with ?stableid=x should not be indexed (as with ?oldid=x). |
| 382 | + */ |
| 383 | + public function setRobotPolicy() { |
| 384 | + global $wgRequest, $wgOut; |
| 385 | + if ( $this->article->getStableRev() && $this->article->isStableShownByDefault() ) { |
| 386 | + if ( $this->showingStable() ) { |
| 387 | + return; // stable version - index this |
| 388 | + } elseif ( !$wgRequest->getVal( 'stableid' ) |
| 389 | + && $wgOut->getRevisionId() == $this->article->getStable() |
| 390 | + && $this->article->stableVersionIsSynced() ) |
| 391 | + { |
| 392 | + return; // draft that is synced with the stable version - index this |
| 393 | + } |
| 394 | + $wgOut->setRobotPolicy( 'noindex,nofollow' ); // don't index this version |
| 395 | + } |
| 396 | + } |
| 397 | + |
| 398 | + /** |
| 399 | + * @param $tag review box/bar info |
| 400 | + * @param $prot protection notice |
| 401 | + * Tag output function must be called by caller |
| 402 | + */ |
| 403 | + protected function showUnreviewedPage( $tag, $prot ) { |
| 404 | + global $wgOut, $wgContLang; |
| 405 | + if ( $wgOut->isPrintable() ) { |
| 406 | + return; // all this function does is add notices; don't show them |
| 407 | + } |
| 408 | + $icon = FlaggedRevsXML::draftStatusIcon(); |
| 409 | + // Simple icon-based UI |
| 410 | + if ( $this->useSimpleUI() ) { |
| 411 | + // RTL langauges |
| 412 | + $rtl = $wgContLang->isRTL() ? " rtl" : ""; |
| 413 | + $tag .= $prot . $icon . wfMsgExt( 'revreview-quick-none', 'parseinline' ); |
| 414 | + $css = "flaggedrevs_short{$rtl} plainlinks noprint"; |
| 415 | + $this->reviewNotice .= "<div id='mw-fr-revisiontag' class='$css'>$tag</div>"; |
| 416 | + // Standard UI |
| 417 | + } else { |
| 418 | + $css = 'flaggedrevs_notice plainlinks noprint'; |
| 419 | + $tag = "<div id='mw-fr-revisiontag' class='$css'>" . |
| 420 | + $prot . $icon . wfMsgExt( 'revreview-noflagged', 'parseinline' ) . |
| 421 | + "</div>"; |
| 422 | + $this->reviewNotice .= $tag; |
| 423 | + } |
| 424 | + } |
| 425 | + |
| 426 | + /** |
| 427 | + * @param $srev stable version |
| 428 | + * @param $tag review box/bar info |
| 429 | + * @param $prot protection notice icon |
| 430 | + * Tag output function must be called by caller |
| 431 | + * Parser cache control deferred to caller |
| 432 | + */ |
| 433 | + protected function showDraftVersion( FlaggedRevision $srev, &$tag, $prot ) { |
| 434 | + global $wgUser, $wgOut, $wgLang, $wgRequest; |
| 435 | + $this->load(); |
| 436 | + if ( $wgOut->isPrintable() ) { |
| 437 | + return; // all this function does is add notices; don't show them |
| 438 | + } |
| 439 | + $flags = $srev->getTags(); |
| 440 | + $time = $wgLang->date( $srev->getTimestamp(), true ); |
| 441 | + # Get quality level |
| 442 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 443 | + # Get stable version sync status |
| 444 | + $synced = $this->article->stableVersionIsSynced(); |
| 445 | + if ( $synced ) { // draft == stable |
| 446 | + $diffToggle = ''; // no diff to show |
| 447 | + } else { // draft != stable |
| 448 | + # The user may want the diff (via prefs) |
| 449 | + $diffToggle = $this->getTopDiffToggle( $srev, $quality ); |
| 450 | + if ( $diffToggle != '' ) $diffToggle = " $diffToggle"; |
| 451 | + # Make sure there is always a notice bar when viewing the draft. |
| 452 | + if ( $this->useSimpleUI() ) { // we already one for detailed UI |
| 453 | + $this->setPendingNotice( $srev, $diffToggle ); |
| 454 | + } |
| 455 | + } |
| 456 | + # Give a "your edit is pending" notice to newer users if |
| 457 | + # an unreviewed edit was completed... |
| 458 | + if ( $wgRequest->getVal( 'shownotice' ) |
| 459 | + && $this->article->getUserText( Revision::RAW ) == $wgUser->getName() |
| 460 | + && $this->article->revsArePending() |
| 461 | + && !$wgUser->isAllowed( 'review' ) ) |
| 462 | + { |
| 463 | + $revsSince = $this->article->getPendingRevCount(); |
| 464 | + $pending = $prot; |
| 465 | + if ( $this->showRatingIcon() ) { |
| 466 | + $pending .= FlaggedRevsXML::draftStatusIcon(); |
| 467 | + } |
| 468 | + $pending .= wfMsgExt( 'revreview-edited', |
| 469 | + 'parseinline', $srev->getRevId(), $revsSince ); |
| 470 | + $anchor = $wgRequest->getVal( 'fromsection' ); |
| 471 | + if ( $anchor != null ) { |
| 472 | + $section = str_replace( '_', ' ', $anchor ); // prettify |
| 473 | + $pending .= wfMsgExt( 'revreview-edited-section', 'parse', $anchor, $section ); |
| 474 | + } |
| 475 | + # Notice should always use subtitle |
| 476 | + $this->reviewNotice = "<div id='mw-fr-reviewnotice' " . |
| 477 | + "class='flaggedrevs_preview plainlinks'>$pending</div>"; |
| 478 | + # Otherwise, construct some tagging info for non-printable outputs. |
| 479 | + # Also, if low profile UI is enabled and the page is synced, skip the tag. |
| 480 | + # Note: the "your edit is pending" notice has all this info, so we never add both. |
| 481 | + } else if ( !( $this->article->lowProfileUI() && $synced ) ) { |
| 482 | + $revsSince = $this->article->getPendingRevCount(); |
| 483 | + // Simple icon-based UI |
| 484 | + if ( $this->useSimpleUI() ) { |
| 485 | + if ( !$wgUser->getId() ) { |
| 486 | + $msgHTML = ''; // Anons just see simple icons |
| 487 | + } else if ( $synced ) { |
| 488 | + $msg = $quality |
| 489 | + ? 'revreview-quick-quality-same' |
| 490 | + : 'revreview-quick-basic-same'; |
| 491 | + $msgHTML = wfMsgExt( $msg, 'parseinline', |
| 492 | + $srev->getRevId(), $revsSince ); |
| 493 | + } else { |
| 494 | + $msg = $quality |
| 495 | + ? 'revreview-quick-see-quality' |
| 496 | + : 'revreview-quick-see-basic'; |
| 497 | + $msgHTML = wfMsgExt( $msg, 'parseinline', |
| 498 | + $srev->getRevId(), $revsSince ); |
| 499 | + } |
| 500 | + $icon = ''; |
| 501 | + # For protection based configs, show lock only if it's not redundant. |
| 502 | + if ( $this->showRatingIcon() ) { |
| 503 | + $icon = $synced |
| 504 | + ? FlaggedRevsXML::stableStatusIcon( $quality ) |
| 505 | + : FlaggedRevsXML::draftStatusIcon(); |
| 506 | + } |
| 507 | + $msgHTML = $prot . $icon . $msgHTML; |
| 508 | + $tag .= FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, |
| 509 | + $revsSince, 'draft', $synced, false ); |
| 510 | + // Standard UI |
| 511 | + } else { |
| 512 | + if ( $synced ) { |
| 513 | + if ( $quality ) { |
| 514 | + $msg = 'revreview-quality-same'; |
| 515 | + } else { |
| 516 | + $msg = 'revreview-basic-same'; |
| 517 | + } |
| 518 | + $msgHTML = wfMsgExt( $msg, 'parseinline', |
| 519 | + $srev->getRevId(), $time, $revsSince ); |
| 520 | + } else { |
| 521 | + $msg = $quality |
| 522 | + ? 'revreview-newest-quality' |
| 523 | + : 'revreview-newest-basic'; |
| 524 | + $msg .= ( $revsSince == 0 ) ? '-i' : ''; |
| 525 | + $msgHTML = wfMsgExt( $msg, 'parseinline', |
| 526 | + $srev->getRevId(), $time, $revsSince ); |
| 527 | + } |
| 528 | + $icon = $synced |
| 529 | + ? FlaggedRevsXML::stableStatusIcon( $quality ) |
| 530 | + : FlaggedRevsXML::draftStatusIcon(); |
| 531 | + $tag .= $prot . $icon . $msgHTML . $diffToggle; |
| 532 | + } |
| 533 | + } |
| 534 | + } |
| 535 | + |
| 536 | + /** |
| 537 | + * @param $srev stable version |
| 538 | + * @param $frev selected flagged revision |
| 539 | + * @param $tag review box/bar info |
| 540 | + * @param $prot protection notice icon |
| 541 | + * Tag output function must be called by caller |
| 542 | + * Parser cache control deferred to caller |
| 543 | + */ |
| 544 | + protected function showOldReviewedVersion( |
| 545 | + FlaggedRevision $srev, FlaggedRevision $frev, &$tag, $prot |
| 546 | + ) { |
| 547 | + global $wgUser, $wgOut, $wgLang; |
| 548 | + $this->load(); |
| 549 | + $flags = $frev->getTags(); |
| 550 | + $time = $wgLang->date( $frev->getTimestamp(), true ); |
| 551 | + # Set display revision ID |
| 552 | + $wgOut->setRevisionId( $frev->getRevId() ); |
| 553 | + # Get quality level |
| 554 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 555 | + |
| 556 | + # Construct some tagging for non-printable outputs. Note that the pending |
| 557 | + # notice has all this info already, so don't do this if we added that already. |
| 558 | + if ( !$wgOut->isPrintable() ) { |
| 559 | + // Simple icon-based UI |
| 560 | + if ( $this->useSimpleUI() ) { |
| 561 | + $icon = ''; |
| 562 | + # For protection based configs, show lock only if it's not redundant. |
| 563 | + if ( $this->showRatingIcon() ) { |
| 564 | + $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
| 565 | + } |
| 566 | + $revsSince = $this->article->getPendingRevCount(); |
| 567 | + if ( !$wgUser->getId() ) { |
| 568 | + $msgHTML = ''; // Anons just see simple icons |
| 569 | + } else { |
| 570 | + $msg = $quality |
| 571 | + ? 'revreview-quick-quality-old' |
| 572 | + : 'revreview-quick-basic-old'; |
| 573 | + $msgHTML = wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $revsSince ); |
| 574 | + } |
| 575 | + $msgHTML = $prot . $icon . $msgHTML; |
| 576 | + $tag = FlaggedRevsXML::prettyRatingBox( $frev, $msgHTML, |
| 577 | + $revsSince, 'oldstable', false /*synced*/ ); |
| 578 | + // Standard UI |
| 579 | + } else { |
| 580 | + $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
| 581 | + $msg = $quality |
| 582 | + ? 'revreview-quality-old' |
| 583 | + : 'revreview-basic-old'; |
| 584 | + $tag = $prot . $icon; |
| 585 | + $tag .= wfMsgExt( $msg, 'parseinline', $frev->getRevId(), $time ); |
| 586 | + # Hide clutter |
| 587 | + if ( !empty( $flags ) ) { |
| 588 | + $tag .= FlaggedRevsXML::ratingToggle(); |
| 589 | + $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
| 590 | + wfMsgHtml( 'revreview-oldrating' ) . |
| 591 | + FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
| 592 | + } |
| 593 | + } |
| 594 | + } |
| 595 | + |
| 596 | + # Check if this is a redirect... |
| 597 | + $text = $frev->getRevText(); |
| 598 | + $redirHtml = $this->getRedirectHtml( $text ); |
| 599 | + |
| 600 | + # Parse and output HTML |
| 601 | + if ( $redirHtml == '' ) { |
| 602 | + $parserOptions = FlaggedRevs::makeParserOptions(); |
| 603 | + $parserOut = FlaggedRevs::parseStableText( |
| 604 | + $this->article->getTitle(), $text, $frev->getRevId(), $parserOptions ); |
| 605 | + $this->addParserOutput( $parserOut ); |
| 606 | + } else { |
| 607 | + $wgOut->addHtml( $redirHtml ); |
| 608 | + } |
| 609 | + } |
| 610 | + |
| 611 | + /** |
| 612 | + * @param $srev stable version |
| 613 | + * @param $tag review box/bar info |
| 614 | + * @param $prot protection notice |
| 615 | + * Tag output function must be called by caller |
| 616 | + * Parser cache control deferred to caller |
| 617 | + */ |
| 618 | + protected function showStableVersion( FlaggedRevision $srev, &$tag, $prot ) { |
| 619 | + global $wgOut, $wgLang, $wgUser; |
| 620 | + $this->load(); |
| 621 | + $flags = $srev->getTags(); |
| 622 | + $time = $wgLang->date( $srev->getTimestamp(), true ); |
| 623 | + # Set display revision ID |
| 624 | + $wgOut->setRevisionId( $srev->getRevId() ); |
| 625 | + # Get quality level |
| 626 | + $quality = FlaggedRevs::isQuality( $flags ); |
| 627 | + |
| 628 | + $synced = $this->article->stableVersionIsSynced(); |
| 629 | + # Construct some tagging |
| 630 | + if ( !$wgOut->isPrintable() && !( $this->article->lowProfileUI() && $synced ) ) { |
| 631 | + $revsSince = $this->article->getPendingRevCount(); |
| 632 | + // Simple icon-based UI |
| 633 | + if ( $this->useSimpleUI() ) { |
| 634 | + $icon = ''; |
| 635 | + # For protection based configs, show lock only if it's not redundant. |
| 636 | + if ( $this->showRatingIcon() ) { |
| 637 | + $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
| 638 | + } |
| 639 | + if ( !$wgUser->getId() ) { |
| 640 | + $msgHTML = ''; // Anons just see simple icons |
| 641 | + } else { |
| 642 | + $msg = $quality |
| 643 | + ? 'revreview-quick-quality' |
| 644 | + : 'revreview-quick-basic'; |
| 645 | + # Uses messages 'revreview-quick-quality-same', 'revreview-quick-basic-same' |
| 646 | + $msg = $synced ? "{$msg}-same" : $msg; |
| 647 | + $msgHTML = wfMsgExt( $msg, 'parseinline', |
| 648 | + $srev->getRevId(), $revsSince ); |
| 649 | + } |
| 650 | + $msgHTML = $prot . $icon . $msgHTML; |
| 651 | + $tag = FlaggedRevsXML::prettyRatingBox( $srev, $msgHTML, |
| 652 | + $revsSince, 'stable', $synced ); |
| 653 | + // Standard UI |
| 654 | + } else { |
| 655 | + $icon = FlaggedRevsXML::stableStatusIcon( $quality ); |
| 656 | + $msg = $quality ? 'revreview-quality' : 'revreview-basic'; |
| 657 | + if ( $synced ) { |
| 658 | + # uses messages 'revreview-quality-same', 'revreview-basic-same' |
| 659 | + $msg .= '-same'; |
| 660 | + } elseif ( $revsSince == 0 ) { |
| 661 | + # uses messages 'revreview-quality-i', 'revreview-basic-i' |
| 662 | + $msg .= '-i'; |
| 663 | + } |
| 664 | + $tag = $prot . $icon; |
| 665 | + $tag .= wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince ); |
| 666 | + if ( !empty( $flags ) ) { |
| 667 | + $tag .= FlaggedRevsXML::ratingToggle(); |
| 668 | + $tag .= "<div id='mw-fr-revisiondetails' style='display:block;'>" . |
| 669 | + FlaggedRevsXML::addTagRatings( $flags ) . '</div>'; |
| 670 | + } |
| 671 | + } |
| 672 | + } |
| 673 | + |
| 674 | + # Get parsed stable version and output HTML |
| 675 | + $parserOut = FlaggedRevs::getPageCache( $this->article, $wgUser ); |
| 676 | + if ( $parserOut ) { |
| 677 | + $this->addParserOutput( $parserOut ); |
| 678 | + } else { |
| 679 | + $text = $srev->getRevText(); |
| 680 | + # Check if this is a redirect... |
| 681 | + $redirHtml = $this->getRedirectHtml( $text ); |
| 682 | + # Don't parse redirects, use separate handling... |
| 683 | + if ( $redirHtml == '' ) { |
| 684 | + # Get the new stable output |
| 685 | + $parserOptions = FlaggedRevs::makeParserOptions(); |
| 686 | + $parserOut = FlaggedRevs::parseStableText( |
| 687 | + $this->article->getTitle(), $text, $srev->getRevId(), $parserOptions ); |
| 688 | + # Update the stable version cache |
| 689 | + FlaggedRevs::updatePageCache( $this->article, $parserOptions, $parserOut ); |
| 690 | + # Add the stable output to the page view |
| 691 | + $this->addParserOutput( $parserOut ); |
| 692 | + |
| 693 | + # Update the stable version dependancies |
| 694 | + FlaggedRevs::updateCacheTracking( $this->article, $parserOut ); |
| 695 | + } else { |
| 696 | + $wgOut->addHtml( $redirHtml ); |
| 697 | + } |
| 698 | + } |
| 699 | + |
| 700 | + # Update page sync status for tracking purposes. |
| 701 | + # NOTE: avoids master hits and doesn't have to be perfect for what it does |
| 702 | + if ( $this->article->syncedInTracking() != $synced ) { |
| 703 | + if ( wfGetDB( DB_SLAVE )->getLag() <= 5 ) { // avoid write-delay cycles |
| 704 | + FlaggedRevs::updateSyncStatus( $this->article, $synced ); |
| 705 | + } |
| 706 | + } |
| 707 | + } |
| 708 | + |
| 709 | + // Add parser output and update title |
| 710 | + // @TODO: refactor MW core to move this back |
| 711 | + protected function addParserOutput( ParserOutput $parserOut ) { |
| 712 | + global $wgOut; |
| 713 | + $wgOut->addParserOutput( $parserOut ); |
| 714 | + # Adjust the title if it was set by displaytitle, -{T|}- or language conversion |
| 715 | + $titleText = $parserOut->getTitleText(); |
| 716 | + if ( strval( $titleText ) !== '' ) { |
| 717 | + $wgOut->setPageTitle( $titleText ); |
| 718 | + } |
| 719 | + } |
| 720 | + |
| 721 | + // Get fancy redirect arrow and link HTML |
| 722 | + protected function getRedirectHtml( $text ) { |
| 723 | + $rTargets = Title::newFromRedirectArray( $text ); |
| 724 | + if ( $rTargets ) { |
| 725 | + return $this->article->viewRedirect( $rTargets ); |
| 726 | + } |
| 727 | + return ''; |
| 728 | + } |
| 729 | + |
| 730 | + // Show icons for draft/stable/old reviewed versions |
| 731 | + protected function showRatingIcon() { |
| 732 | + if ( FlaggedRevs::useOnlyIfProtected() ) { |
| 733 | + // If there is only one quality level and we have tabs to know |
| 734 | + // which version we are looking at, then just use the lock icon... |
| 735 | + return FlaggedRevs::qualityVersions(); |
| 736 | + } |
| 737 | + return true; |
| 738 | + } |
| 739 | + |
| 740 | + /** |
| 741 | + * Get collapsible diff-to-stable html to add to the review notice as needed |
| 742 | + * @param FlaggedRevision $srev, stable version |
| 743 | + * @param bool $quality, revision is quality |
| 744 | + * @return string, the html line (either "" or "<diff toggle><diff div>") |
| 745 | + */ |
| 746 | + protected function getTopDiffToggle( FlaggedRevision $srev, $quality ) { |
| 747 | + global $wgUser; |
| 748 | + $this->load(); |
| 749 | + if ( !$wgUser->getBoolOption( 'flaggedrevsviewdiffs' ) ) { |
| 750 | + return false; // nothing to do here |
| 751 | + } |
| 752 | + # Diff should only show for the draft |
| 753 | + $oldid = $this->article->getOldIDFromRequest(); |
| 754 | + $latest = $this->article->getLatest(); |
| 755 | + if ( $oldid && $oldid != $latest ) { |
| 756 | + return false; // not viewing the draft |
| 757 | + } |
| 758 | + $revsSince = $this->article->getPendingRevCount(); |
| 759 | + if ( !$revsSince ) { |
| 760 | + return false; // no pending changes |
| 761 | + } |
| 762 | + $title = $this->article->getTitle(); // convenience |
| 763 | + # Review status of left diff revision... |
| 764 | + $leftNote = $quality |
| 765 | + ? 'revreview-hist-quality' |
| 766 | + : 'revreview-hist-basic'; |
| 767 | + $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
| 768 | + $leftNote = "<span class='$lClass'>[" . wfMsgHtml( $leftNote ) . "]</span>"; |
| 769 | + # Review status of right diff revision... |
| 770 | + $rClass = FlaggedRevsXML::getQualityColor( false ); |
| 771 | + $rightNote = "<span class='$rClass'>[" . |
| 772 | + wfMsgHtml( 'revreview-hist-pending' ) . "]</span>"; |
| 773 | + # Get the actual body of the diff... |
| 774 | + $diffEngine = new DifferenceEngine( $title, $srev->getRevId(), $latest ); |
| 775 | + $diffBody = $diffEngine->getDiffBody(); |
| 776 | + if ( strlen( $diffBody ) > 0 ) { |
| 777 | + $nEdits = $revsSince - 1; // full diff-to-stable, no need for query |
| 778 | + if ( $nEdits ) { |
| 779 | + $limit = 100; |
| 780 | + $nUsers = $title->countAuthorsBetween( $srev->getRevId(), $latest, $limit ); |
| 781 | + $multiNotice = DifferenceEngine::intermediateEditsMsg( $nEdits, $nUsers, $limit ); |
| 782 | + } else { |
| 783 | + $multiNotice = ''; |
| 784 | + } |
| 785 | + $diffEngine->showDiffStyle(); // add CSS |
| 786 | + $this->isDiffFromStable = true; // alter default review form tags |
| 787 | + return |
| 788 | + FlaggedRevsXML::diffToggle() . |
| 789 | + "<div id='mw-fr-stablediff'>\n" . |
| 790 | + self::getFormattedDiff( $diffBody, $multiNotice, $leftNote, $rightNote ) . |
| 791 | + "</div>\n";; |
| 792 | + } |
| 793 | + return ''; |
| 794 | + } |
| 795 | + |
| 796 | + // $n number of in-between revs |
| 797 | + protected static function getFormattedDiff( |
| 798 | + $diffBody, $multiNotice, $leftStatus, $rightStatus |
| 799 | + ) { |
| 800 | + if ( $multiNotice != '' ) { |
| 801 | + $multiNotice = "<tr><td colspan='4' align='center' class='diff-multi'>" . |
| 802 | + $multiNotice . "</td></tr>"; |
| 803 | + } |
| 804 | + return |
| 805 | + "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" . |
| 806 | + "<col class='diff-marker' />" . |
| 807 | + "<col class='diff-content' />" . |
| 808 | + "<col class='diff-marker' />" . |
| 809 | + "<col class='diff-content' />" . |
| 810 | + "<tr>" . |
| 811 | + "<td colspan='2' width='50%' align='center' class='diff-otitle'><b>" . |
| 812 | + $leftStatus . "</b></td>" . |
| 813 | + "<td colspan='2' width='50%' align='center' class='diff-ntitle'><b>" . |
| 814 | + $rightStatus . "</b></td>" . |
| 815 | + "</tr>" . |
| 816 | + $multiNotice . |
| 817 | + $diffBody . |
| 818 | + "</table>"; |
| 819 | + } |
| 820 | + |
| 821 | + /** |
| 822 | + * Get the normal and display files for the underlying ImagePage. |
| 823 | + * If the a stable version needs to be displayed, this will set $normalFile |
| 824 | + * to the current version, and $displayFile to the desired version. |
| 825 | + * |
| 826 | + * If no stable version is required, the reference parameters will not be set |
| 827 | + * |
| 828 | + * Depends on $wgRequest |
| 829 | + */ |
| 830 | + public function imagePageFindFile( &$normalFile, &$displayFile ) { |
| 831 | + global $wgRequest; |
| 832 | + $this->load(); |
| 833 | + # Determine timestamp. A reviewed version may have explicitly been requested... |
| 834 | + $frev = null; |
| 835 | + $time = false; |
| 836 | + $reqId = $wgRequest->getVal( 'stableid' ); |
| 837 | + if ( $reqId ) { |
| 838 | + $frev = FlaggedRevision::newFromTitle( $this->article->getTitle(), $reqId ); |
| 839 | + } elseif ( $this->showingStable() ) { |
| 840 | + $frev = $this->article->getStableRev(); |
| 841 | + } |
| 842 | + if ( $frev ) { |
| 843 | + $time = $frev->getFileTimestamp(); |
| 844 | + // B/C, may be stored in associated image version metadata table |
| 845 | + // @TODO: remove, updateTracking.php does this |
| 846 | + if ( !$time ) { |
| 847 | + $dbr = wfGetDB( DB_SLAVE ); |
| 848 | + $time = $dbr->selectField( 'flaggedimages', |
| 849 | + 'fi_img_timestamp', |
| 850 | + array( 'fi_rev_id' => $frev->getRevId(), |
| 851 | + 'fi_name' => $this->article->getTitle()->getDBkey() ), |
| 852 | + __METHOD__ |
| 853 | + ); |
| 854 | + $time = trim( $time ); // remove garbage |
| 855 | + $time = $time ? wfTimestamp( TS_MW, $time ) : false; |
| 856 | + } |
| 857 | + } |
| 858 | + if ( !$time ) { |
| 859 | + # Try request parameter |
| 860 | + $time = $wgRequest->getVal( 'filetimestamp', false ); |
| 861 | + } |
| 862 | + |
| 863 | + if ( !$time ) { |
| 864 | + return; // Use the default behaviour |
| 865 | + } |
| 866 | + |
| 867 | + $title = $this->article->getTitle(); |
| 868 | + $displayFile = wfFindFile( $title, array( 'time' => $time ) ); |
| 869 | + # If none found, try current |
| 870 | + if ( !$displayFile ) { |
| 871 | + wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: $time not found, using current\n" ); |
| 872 | + $displayFile = wfFindFile( $title ); |
| 873 | + # If none found, use a valid local placeholder |
| 874 | + if ( !$displayFile ) { |
| 875 | + $displayFile = wfLocalFile( $title ); // fallback to current |
| 876 | + } |
| 877 | + $normalFile = $displayFile; |
| 878 | + # If found, set $normalFile |
| 879 | + } else { |
| 880 | + wfDebug( __METHOD__ . ": {$title->getPrefixedDBkey()}: using timestamp $time\n" ); |
| 881 | + $normalFile = wfFindFile( $title ); |
| 882 | + } |
| 883 | + } |
| 884 | + |
| 885 | + /** |
| 886 | + * Adds stable version tags to page when viewing history |
| 887 | + */ |
| 888 | + public function addToHistView() { |
| 889 | + global $wgOut; |
| 890 | + $this->load(); |
| 891 | + # Add a notice if there are pending edits... |
| 892 | + $srev = $this->article->getStableRev(); |
| 893 | + if ( $srev && $this->article->revsArePending() ) { |
| 894 | + $revsSince = $this->article->getPendingRevCount(); |
| 895 | + $tag = "<div id='mw-fr-revisiontag-edit' class='flaggedrevs_notice plainlinks'>" . |
| 896 | + FlaggedRevsXML::lockStatusIcon( $this->article ) . # flag protection icon as needed |
| 897 | + FlaggedRevsXML::pendingEditNotice( $this->article, $srev, $revsSince ) . "</div>"; |
| 898 | + $wgOut->addHTML( $tag ); |
| 899 | + } |
| 900 | + return true; |
| 901 | + } |
| 902 | + |
| 903 | + /** |
| 904 | + * Adds stable version tags to page when editing |
| 905 | + */ |
| 906 | + public function addToEditView( EditPage $editPage ) { |
| 907 | + global $wgOut, $wgUser; |
| 908 | + $this->load(); |
| 909 | + # Must be reviewable. UI may be limited to unobtrusive patrolling system. |
| 910 | + if ( !$this->article->isReviewable() ) { |
| 911 | + return true; |
| 912 | + } |
| 913 | + $items = array(); |
| 914 | + # Show stabilization log |
| 915 | + $log = $this->stabilityLogNotice(); |
| 916 | + if ( $log ) $items[] = $log; |
| 917 | + # Check the newest stable version |
| 918 | + $frev = $this->article->getStableRev(); |
| 919 | + if ( $frev ) { |
| 920 | + $quality = $frev->getQuality(); |
| 921 | + # Find out revision id of base version |
| 922 | + $latestId = $this->article->getLatest(); |
| 923 | + $revId = $editPage->oldid ? $editPage->oldid : $latestId; |
| 924 | + # Let new users know about review procedure a tag. |
| 925 | + # If the log excerpt was shown this is redundant. |
| 926 | + if ( !$log && !$wgUser->getId() && $this->article->isStableShownByDefault() ) { |
| 927 | + $items[] = wfMsgExt( 'revreview-editnotice', 'parseinline' ); |
| 928 | + } |
| 929 | + # Add a notice if there are pending edits... |
| 930 | + if ( $this->article->revsArePending() ) { |
| 931 | + $revsSince = $this->article->getPendingRevCount(); |
| 932 | + $items[] = FlaggedRevsXML::pendingEditNotice( $this->article, $frev, $revsSince ); |
| 933 | + } |
| 934 | + # Show diff to stable, to make things less confusing. |
| 935 | + # This can be disabled via user preferences and other conditions... |
| 936 | + if ( $frev->getRevId() < $latestId // changes were made |
| 937 | + && $wgUser->getBoolOption( 'flaggedrevseditdiffs' ) // not disable via prefs |
| 938 | + && $revId == $latestId // only for current rev |
| 939 | + && $editPage->section != 'new' // not for new sections |
| 940 | + && $editPage->formtype != 'diff' // not "show changes" |
| 941 | + ) { |
| 942 | + # Left diff side... |
| 943 | + $leftNote = $quality |
| 944 | + ? 'revreview-hist-quality' |
| 945 | + : 'revreview-hist-basic'; |
| 946 | + $lClass = FlaggedRevsXML::getQualityColor( (int)$quality ); |
| 947 | + $leftNote = "<span class='$lClass'>[" . |
| 948 | + wfMsgHtml( $leftNote ) . "]</span>"; |
| 949 | + # Right diff side... |
| 950 | + $rClass = FlaggedRevsXML::getQualityColor( false ); |
| 951 | + $rightNote = "<span class='$rClass'>[" . |
| 952 | + wfMsgHtml( 'revreview-hist-pending' ) . "]</span>"; |
| 953 | + # Get the stable version source |
| 954 | + $text = $frev->getRevText(); |
| 955 | + # Are we editing a section? |
| 956 | + $section = ( $editPage->section == "" ) ? |
| 957 | + false : intval( $editPage->section ); |
| 958 | + if ( $section !== false ) { |
| 959 | + $text = $this->article->getSection( $text, $section ); |
| 960 | + } |
| 961 | + if ( $text !== false && strcmp( $text, $editPage->textbox1 ) !== 0 ) { |
| 962 | + $diffEngine = new DifferenceEngine( $this->article->getTitle() ); |
| 963 | + $diffBody = $diffEngine->generateDiffBody( $text, $editPage->textbox1 ); |
| 964 | + $diffHtml = |
| 965 | + wfMsgExt( 'review-edit-diff', 'parseinline' ) . ' ' . |
| 966 | + FlaggedRevsXML::diffToggle() . |
| 967 | + "<div id='mw-fr-stablediff'>" . |
| 968 | + self::getFormattedDiff( $diffBody, '', $leftNote, $rightNote ) . |
| 969 | + "</div>\n"; |
| 970 | + $items[] = $diffHtml; |
| 971 | + $diffEngine->showDiffStyle(); // add CSS |
| 972 | + } |
| 973 | + } |
| 974 | + # Output items |
| 975 | + if ( count( $items ) ) { |
| 976 | + $html = "<table class='flaggedrevs_editnotice plainlinks'>"; |
| 977 | + foreach ( $items as $item ) { |
| 978 | + $html .= '<tr><td>' . $item . '</td></tr>'; |
| 979 | + } |
| 980 | + $html .= '</table>'; |
| 981 | + $wgOut->addHTML( $html ); |
| 982 | + } |
| 983 | + } |
| 984 | + return true; |
| 985 | + } |
| 986 | + |
| 987 | + protected function stabilityLogNotice() { |
| 988 | + $this->load(); |
| 989 | + $s = ''; |
| 990 | + # Only for pages manually made to be stable... |
| 991 | + if ( $this->article->isPageLocked() ) { |
| 992 | + $s = wfMsgExt( 'revreview-locked', 'parseinline' ); |
| 993 | + $s .= ' ' . FlaggedRevsXML::logDetailsToggle(); |
| 994 | + $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article ); |
| 995 | + # ...or unstable |
| 996 | + } elseif ( $this->article->isPageUnlocked() ) { |
| 997 | + $s = wfMsgExt( 'revreview-unlocked', 'parseinline' ); |
| 998 | + $s .= ' ' . FlaggedRevsXML::logDetailsToggle(); |
| 999 | + $s .= FlaggedRevsXML::stabilityLogExcerpt( $this->article ); |
| 1000 | + } |
| 1001 | + return $s; |
| 1002 | + } |
| 1003 | + |
| 1004 | + public function addToNoSuchSection( EditPage $editPage, &$s ) { |
| 1005 | + $this->load(); |
| 1006 | + $srev = $this->article->getStableRev(); |
| 1007 | + # Add notice for users that may have clicked "edit" for a |
| 1008 | + # section in the stable version that isn't in the draft. |
| 1009 | + if ( $srev && $this->article->revsArePending() ) { |
| 1010 | + $revsSince = $this->article->getPendingRevCount(); |
| 1011 | + if ( $revsSince ) { |
| 1012 | + $s .= "<div class='flaggedrevs_editnotice plainlinks'>" . |
| 1013 | + wfMsgExt( 'revreview-pending-nosection', 'parseinline', |
| 1014 | + $srev->getRevId(), $revsSince ) . "</div>"; |
| 1015 | + } |
| 1016 | + } |
| 1017 | + return true; |
| 1018 | + } |
| 1019 | + |
| 1020 | + /** |
| 1021 | + * Add unreviewed pages links |
| 1022 | + */ |
| 1023 | + public function addToCategoryView() { |
| 1024 | + global $wgOut, $wgUser; |
| 1025 | + $this->load(); |
| 1026 | + if ( !$wgUser->isAllowed( 'review' ) ) { |
| 1027 | + return true; |
| 1028 | + } |
| 1029 | + if ( !FlaggedRevs::useOnlyIfProtected() ) { |
| 1030 | + # Add links to lists of unreviewed pages and pending changes in this category |
| 1031 | + $category = $this->article->getTitle()->getText(); |
| 1032 | + $wgOut->appendSubtitle( |
| 1033 | + Html::rawElement( |
| 1034 | + 'span', |
| 1035 | + array( 'class' => 'plainlinks', 'id' => 'mw-fr-category-oldreviewed' ), |
| 1036 | + wfMsgExt( 'flaggedrevs-categoryview', 'parseinline', urlencode( $category ) ) |
| 1037 | + ) |
| 1038 | + ); |
| 1039 | + } |
| 1040 | + return true; |
| 1041 | + } |
| 1042 | + |
| 1043 | + /** |
| 1044 | + * Add review form to pages when necessary |
| 1045 | + * on a regular page view (action=view) |
| 1046 | + */ |
| 1047 | + public function addReviewForm( &$data ) { |
| 1048 | + global $wgRequest, $wgUser, $wgOut; |
| 1049 | + $this->load(); |
| 1050 | + if ( $wgOut->isPrintable() ) { |
| 1051 | + return false; // Must be on non-printable output |
| 1052 | + } |
| 1053 | + # User must have review rights |
| 1054 | + if ( !$wgUser->isAllowed( 'review' ) ) { |
| 1055 | + return true; |
| 1056 | + } |
| 1057 | + # Page must exist and be reviewable |
| 1058 | + if ( !$this->article->exists() || !$this->article->isReviewable() ) { |
| 1059 | + return true; |
| 1060 | + } |
| 1061 | + # Must be a page view action... |
| 1062 | + if ( !$this->isPageViewOrDiff( $wgRequest ) ) { |
| 1063 | + return true; |
| 1064 | + } |
| 1065 | + # Get the revision being displayed |
| 1066 | + $rev = false; |
| 1067 | + if ( $this->reviewFormRev ) { |
| 1068 | + $rev = $this->reviewFormRev; // $newRev for diffs stored here |
| 1069 | + } elseif ( $wgOut->getRevisionId() ) { |
| 1070 | + $rev = Revision::newFromId( $wgOut->getRevisionId() ); |
| 1071 | + } |
| 1072 | + # Build the review form as needed |
| 1073 | + if ( $rev && ( !$this->diffRevs || $this->isReviewableDiff ) ) { |
| 1074 | + $form = new RevisionReviewFormGUI( $wgUser, $this->article, $rev ); |
| 1075 | + # Default tags and existence of "reject" button depend on context |
| 1076 | + if ( $this->diffRevs ) { |
| 1077 | + $form->setDiffPriorRev( $this->diffRevs['old'] ); |
| 1078 | + } |
| 1079 | + # Review notice box goes in top of form |
| 1080 | + $form->setTopNotice( $this->diffNoticeBox ); |
| 1081 | + # $wgOut may not already have the inclusion IDs, such as for diffonly=1. |
| 1082 | + # RevisionReviewForm will fetch them as needed however. |
| 1083 | + if ( $wgOut->getRevisionId() == $rev->getId() ) { |
| 1084 | + $form->setIncludeVersions( $wgOut->getTemplateIds(), $wgOut->getImageTimeKeys() ); |
| 1085 | + } |
| 1086 | + list( $html, $status ) = $form->getHtml(); |
| 1087 | + # Diff action: place the form at the top of the page |
| 1088 | + if ( $this->diffRevs ) { |
| 1089 | + $wgOut->prependHTML( $html ); |
| 1090 | + # View action: place the form at the bottom of the page |
| 1091 | + } else { |
| 1092 | + $data .= $html; |
| 1093 | + } |
| 1094 | + } |
| 1095 | + return true; |
| 1096 | + } |
| 1097 | + |
| 1098 | + /** |
| 1099 | + * Add link to stable version setting to protection form |
| 1100 | + */ |
| 1101 | + public function addVisibilityLink( &$data ) { |
| 1102 | + global $wgRequest, $wgOut; |
| 1103 | + $this->load(); |
| 1104 | + if ( FlaggedRevs::useProtectionLevels() ) { |
| 1105 | + return true; // simple custom levels set for action=protect |
| 1106 | + } |
| 1107 | + # Check only if the title is reviewable |
| 1108 | + if ( !FlaggedRevs::inReviewNamespace( $this->article->getTitle() ) ) { |
| 1109 | + return true; |
| 1110 | + } |
| 1111 | + $action = $wgRequest->getVal( 'action', 'view' ); |
| 1112 | + if ( $action == 'protect' || $action == 'unprotect' ) { |
| 1113 | + $title = SpecialPage::getTitleFor( 'Stabilization' ); |
| 1114 | + # Give a link to the page to configure the stable version |
| 1115 | + $frev = $this->article->getStableRev(); |
| 1116 | + if ( $frev && $frev->getRevId() == $this->article->getLatest() ) { |
| 1117 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 1118 | + wfMsgExt( 'revreview-visibility-synced', 'parseinline', |
| 1119 | + $title->getPrefixedText() ) . "</span>" ); |
| 1120 | + } elseif ( $frev ) { |
| 1121 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 1122 | + wfMsgExt( 'revreview-visibility-outdated', 'parseinline', |
| 1123 | + $title->getPrefixedText() ) . "</span>" ); |
| 1124 | + } else { |
| 1125 | + $wgOut->prependHTML( "<span class='plainlinks'>" . |
| 1126 | + wfMsgExt( 'revreview-visibility-nostable', 'parseinline', |
| 1127 | + $title->getPrefixedText() ) . "</span>" ); |
| 1128 | + } |
| 1129 | + } |
| 1130 | + return true; |
| 1131 | + } |
| 1132 | + |
| 1133 | + /** |
| 1134 | + * Modify an array of action links, as used by SkinTemplateNavigation and |
| 1135 | + * SkinTemplateTabs, to inlude flagged revs UI elements |
| 1136 | + */ |
| 1137 | + public function setActionTabs( $skin, array &$actions ) { |
| 1138 | + global $wgUser; |
| 1139 | + $this->load(); |
| 1140 | + if ( FlaggedRevs::useProtectionLevels() ) { |
| 1141 | + return true; // simple custom levels set for action=protect |
| 1142 | + } |
| 1143 | + $title = $this->article->getTitle()->getSubjectPage(); |
| 1144 | + if ( !FlaggedRevs::inReviewNamespace( $title ) ) { |
| 1145 | + return true; // Only reviewable pages need these tabs |
| 1146 | + } |
| 1147 | + // Check if we should show a stabilization tab |
| 1148 | + if ( |
| 1149 | + !$this->article->getTitle()->isTalkPage() && |
| 1150 | + is_array( $actions ) && |
| 1151 | + !isset( $actions['protect'] ) && |
| 1152 | + !isset( $actions['unprotect'] ) && |
| 1153 | + $wgUser->isAllowed( 'stablesettings' ) && |
| 1154 | + $title->exists() ) |
| 1155 | + { |
| 1156 | + $stableTitle = SpecialPage::getTitleFor( 'Stabilization' ); |
| 1157 | + // Add the tab |
| 1158 | + $actions['default'] = array( |
| 1159 | + 'class' => false, |
| 1160 | + 'text' => wfMsg( 'stabilization-tab' ), |
| 1161 | + 'href' => $stableTitle->getLocalUrl( |
| 1162 | + 'page=' . $title->getPrefixedUrl() |
| 1163 | + ) |
| 1164 | + ); |
| 1165 | + } |
| 1166 | + return true; |
| 1167 | + } |
| 1168 | + |
| 1169 | + /** |
| 1170 | + * Modify an array of tab links to include flagged revs UI elements |
| 1171 | + * @param string $type ('flat' for SkinTemplateTabs, 'nav' for SkinTemplateNavigation) |
| 1172 | + */ |
| 1173 | + public function setViewTabs( Skin $skin, array &$views, $type ) { |
| 1174 | + global $wgRequest; |
| 1175 | + $this->load(); |
| 1176 | + if ( $this->article->getTitle()->isTalkPage() ) { |
| 1177 | + return true; // leave talk pages alone |
| 1178 | + } |
| 1179 | + if ( !$this->article->isReviewable() ) { |
| 1180 | + return true; // Not a reviewable page or the UI is hidden |
| 1181 | + } |
| 1182 | + $srev = $this->article->getStableRev(); |
| 1183 | + if ( !$srev ) { |
| 1184 | + return true; // No stable revision exists |
| 1185 | + } |
| 1186 | + $synced = $this->article->stableVersionIsSynced(); |
| 1187 | + $pendingEdits = !$synced && $this->article->isStableShownByDefault(); |
| 1188 | + // Set the edit tab names as needed... |
| 1189 | + if ( $pendingEdits ) { |
| 1190 | + if ( isset( $views['edit'] ) ) { |
| 1191 | + $views['edit']['text'] = wfMsg( 'revreview-edit' ); |
| 1192 | + } |
| 1193 | + if ( isset( $views['viewsource'] ) ) { |
| 1194 | + $views['viewsource']['text'] = wfMsg( 'revreview-source' ); |
| 1195 | + } |
| 1196 | + } |
| 1197 | + # Add "pending changes" tab if the page is not synced |
| 1198 | + if ( !$synced ) { |
| 1199 | + $this->addDraftTab( $views, $srev, $type ); |
| 1200 | + } |
| 1201 | + return true; |
| 1202 | + } |
| 1203 | + |
| 1204 | + // Add "pending changes" tab and set tab selection CSS |
| 1205 | + protected function addDraftTab( array &$views, FlaggedRevision $srev, $type ) { |
| 1206 | + global $wgRequest, $wgOut; |
| 1207 | + $title = $this->article->getTitle(); // convenience |
| 1208 | + $tabs = array( |
| 1209 | + 'read' => array( // view stable |
| 1210 | + 'text' => '', // unused |
| 1211 | + 'href' => $title->getLocalUrl( 'stable=1' ), |
| 1212 | + 'class' => '' |
| 1213 | + ), |
| 1214 | + 'draft' => array( // view draft |
| 1215 | + 'text' => wfMsg( 'revreview-current' ), |
| 1216 | + 'href' => $title->getLocalUrl( 'stable=0&redirect=no' ), |
| 1217 | + 'class' => 'collapsible' |
| 1218 | + ), |
| 1219 | + ); |
| 1220 | + // Set tab selection CSS |
| 1221 | + if ( $this->showingStable() || $wgRequest->getVal( 'stableid' ) ) { |
| 1222 | + // We are looking a the stable version or an old reviewed one |
| 1223 | + $tabs['read']['class'] = 'selected'; |
| 1224 | + } elseif ( $this->isPageViewOrDiff( $wgRequest ) ) { |
| 1225 | + $ts = null; |
| 1226 | + if ( $wgOut->getRevisionId() ) { // @TODO: avoid same query in Skin.php |
| 1227 | + $ts = ( $wgOut->getRevisionId() == $this->article->getLatest() ) |
| 1228 | + ? $this->article->getTimestamp() // skip query |
| 1229 | + : Revision::getTimestampFromId( $title, $wgOut->getRevisionId() ); |
| 1230 | + } |
| 1231 | + // Are we looking at a pending revision? |
| 1232 | + if ( $ts > $srev->getRevTimestamp() ) { // bug 15515 |
| 1233 | + $tabs['draft']['class'] .= ' selected'; |
| 1234 | + // Are there *just* pending template/file changes. |
| 1235 | + } elseif ( $this->article->onlyTemplatesOrFilesPending() |
| 1236 | + && $wgOut->getRevisionId() == $this->article->getStable() ) |
| 1237 | + { |
| 1238 | + $tabs['draft']['class'] .= ' selected'; |
| 1239 | + // Otherwise, fallback to regular tab behavior |
| 1240 | + } else { |
| 1241 | + $tabs['read']['class'] = 'selected'; |
| 1242 | + } |
| 1243 | + } |
| 1244 | + $newViews = array(); |
| 1245 | + // Rebuild tabs array. Deals with Monobook vs Vector differences. |
| 1246 | + if ( $type == 'nav' ) { // Vector et al |
| 1247 | + foreach ( $views as $tabAction => $data ) { |
| 1248 | + // The 'view' tab. Make it go to the stable version... |
| 1249 | + if ( $tabAction == 'view' ) { |
| 1250 | + // 'view' for content page; make it go to the stable version |
| 1251 | + $newViews[$tabAction]['text'] = $data['text']; // keep tab name |
| 1252 | + $newViews[$tabAction]['href'] = $tabs['read']['href']; |
| 1253 | + $newViews[$tabAction]['class'] = $tabs['read']['class']; |
| 1254 | + // All other tabs... |
| 1255 | + } else { |
| 1256 | + // Add 'draft' tab to content page to the left of 'edit'... |
| 1257 | + if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) { |
| 1258 | + $newViews['current'] = $tabs['draft']; |
| 1259 | + } |
| 1260 | + $newViews[$tabAction] = $data; |
| 1261 | + } |
| 1262 | + } |
| 1263 | + } elseif ( $type == 'flat' ) { // MonoBook et al |
| 1264 | + $first = true; |
| 1265 | + foreach ( $views as $tabAction => $data ) { |
| 1266 | + // The first tab ('page'). Make it go to the stable version... |
| 1267 | + if ( $first ) { |
| 1268 | + $first = false; |
| 1269 | + $newViews[$tabAction]['text'] = $data['text']; // keep tab name |
| 1270 | + $newViews[$tabAction]['href'] = $tabs['read']['href']; |
| 1271 | + $newViews[$tabAction]['class'] = $data['class']; // keep tab class |
| 1272 | + // All other tabs... |
| 1273 | + } else { |
| 1274 | + // Add 'draft' tab to content page to the left of 'edit'... |
| 1275 | + if ( $tabAction == 'edit' || $tabAction == 'viewsource' ) { |
| 1276 | + $newViews['current'] = $tabs['draft']; |
| 1277 | + } |
| 1278 | + $newViews[$tabAction] = $data; |
| 1279 | + } |
| 1280 | + } |
| 1281 | + } |
| 1282 | + // Replaces old tabs with new tabs |
| 1283 | + $views = $newViews; |
| 1284 | + } |
| 1285 | + |
| 1286 | + /** |
| 1287 | + * Adds a notice saying that this revision is pending review |
| 1288 | + * @param FlaggedRevision $srev The stable version |
| 1289 | + * @param string $diffToggle either "" or " <diff toggle><diff div>" |
| 1290 | + * @return void |
| 1291 | + */ |
| 1292 | + public function setPendingNotice( FlaggedRevision $srev, $diffToggle = '' ) { |
| 1293 | + global $wgLang; |
| 1294 | + $this->load(); |
| 1295 | + $time = $wgLang->date( $srev->getTimestamp(), true ); |
| 1296 | + $revsSince = $this->article->getPendingRevCount(); |
| 1297 | + $msg = $srev->getQuality() |
| 1298 | + ? 'revreview-newest-quality' |
| 1299 | + : 'revreview-newest-basic'; |
| 1300 | + $msg .= ( $revsSince == 0 ) ? '-i' : ''; |
| 1301 | + # Add bar msg to the top of the page... |
| 1302 | + $css = 'flaggedrevs_preview plainlinks'; |
| 1303 | + $msgHTML = wfMsgExt( $msg, 'parseinline', $srev->getRevId(), $time, $revsSince ); |
| 1304 | + $this->reviewNotice .= "<div id='mw-fr-reviewnotice' class='$css'>" . |
| 1305 | + "$msgHTML$diffToggle</div>"; |
| 1306 | + } |
| 1307 | + |
| 1308 | + /** |
| 1309 | + * When viewing a diff: |
| 1310 | + * (a) Add the review form to the top of the page |
| 1311 | + * (b) Mark off which versions are checked or not |
| 1312 | + * (c) When comparing the stable revision to the current: |
| 1313 | + * (i) Show a tag with some explanation for the diff |
| 1314 | + * (ii) List any template/file changes pending review |
| 1315 | + */ |
| 1316 | + public function addToDiffView( $diff, $oldRev, $newRev ) { |
| 1317 | + global $wgRequest, $wgUser, $wgOut, $wgMemc; |
| 1318 | + $this->load(); |
| 1319 | + # Exempt printer-friendly output |
| 1320 | + if ( $wgOut->isPrintable() ) { |
| 1321 | + return true; |
| 1322 | + # Multi-page diffs are useless and misbehave (bug 19327). Sanity check $newRev. |
| 1323 | + } elseif ( $this->isMultiPageDiff || !$newRev ) { |
| 1324 | + return true; |
| 1325 | + # Page must be reviewable. |
| 1326 | + } elseif ( !$this->article->isReviewable() ) { |
| 1327 | + return true; |
| 1328 | + } |
| 1329 | + $srev = $this->article->getStableRev(); |
| 1330 | + # Check if this is a diff-to-stable. If so: |
| 1331 | + # (a) prompt reviewers to review the changes |
| 1332 | + # (b) list template/file changes if only includes are pending |
| 1333 | + if ( $srev |
| 1334 | + && $this->isDiffFromStable |
| 1335 | + && !$this->article->stableVersionIsSynced() ) // pending changes |
| 1336 | + { |
| 1337 | + $changeDiv = ''; |
| 1338 | + $this->reviewFormRev = $newRev; |
| 1339 | + $changeList = array(); |
| 1340 | + # Page not synced only due to includes? |
| 1341 | + if ( !$this->article->revsArePending() ) { |
| 1342 | + # Add a list of links to each changed template... |
| 1343 | + $changeList = self::fetchTemplateChanges( $srev ); |
| 1344 | + # Add a list of links to each changed file... |
| 1345 | + $changeList = array_merge( $changeList, self::fetchFileChanges( $srev ) ); |
| 1346 | + # Correct bad cache which said they were not synced... |
| 1347 | + if ( !count( $changeList ) ) { |
| 1348 | + global $wgParserCacheExpireTime; |
| 1349 | + $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->article->getId() ); |
| 1350 | + $data = FlaggedRevs::makeMemcObj( "true" ); |
| 1351 | + $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
| 1352 | + } |
| 1353 | + } |
| 1354 | + # If there are pending revs or templates/files changes, notify the user... |
| 1355 | + if ( $this->article->revsArePending() || count( $changeList ) ) { |
| 1356 | + $changeDiv = ''; |
| 1357 | + # If the user can review then prompt them to review them... |
| 1358 | + if ( $wgUser->isAllowed( 'review' ) ) { |
| 1359 | + # Set a key to note that someone is viewing this |
| 1360 | + FRUserActivity::setUserReviewingDiff( |
| 1361 | + $wgUser, $oldRev->getId(), $newRev->getId() ); |
| 1362 | + // Reviewer just edited... |
| 1363 | + if ( $wgRequest->getInt( 'shownotice' ) |
| 1364 | + && $newRev->isCurrent() |
| 1365 | + && $newRev->getRawUserText() == $wgUser->getName() ) |
| 1366 | + { |
| 1367 | + $title = $this->article->getTitle(); // convenience |
| 1368 | + // @TODO: make diff class cache this |
| 1369 | + $n = $title->countRevisionsBetween( $oldRev, $newRev ); |
| 1370 | + if ( $n ) { |
| 1371 | + $msg = 'revreview-update-edited-prev'; // previous pending edits |
| 1372 | + } else { |
| 1373 | + $msg = 'revreview-update-edited'; // just couldn't autoreview |
| 1374 | + } |
| 1375 | + // All other cases... |
| 1376 | + } else { |
| 1377 | + $msg = 'revreview-update'; // generic "please review" notice... |
| 1378 | + } |
| 1379 | + $changeDiv .= wfMsgExt( $msg, 'parse' ); |
| 1380 | + } |
| 1381 | + # Add include change list... |
| 1382 | + if ( count( $changeList ) ) { |
| 1383 | + $changeDiv .= '<p>' . |
| 1384 | + wfMsgExt( 'revreview-update-includes', 'parseinline' ) . |
| 1385 | + ' ' . implode( ', ', $changeList ) . '</p>'; |
| 1386 | + # Add include usage notice... |
| 1387 | + if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
| 1388 | + $changeDiv .= wfMsgExt( 'revreview-update-use', 'parse' ); |
| 1389 | + } |
| 1390 | + } |
| 1391 | + } |
| 1392 | + if ( $changeDiv != '' ) { |
| 1393 | + if ( $wgUser->isAllowed( 'review' ) ) { |
| 1394 | + $this->diffNoticeBox = $changeDiv; // add as part of form |
| 1395 | + } else { |
| 1396 | + $css = 'flaggedrevs_diffnotice plainlinks'; |
| 1397 | + $wgOut->addHTML( |
| 1398 | + "<div id='mw-fr-difftostable' class='$css'>$changeDiv</div>\n" |
| 1399 | + ); |
| 1400 | + } |
| 1401 | + } |
| 1402 | + } |
| 1403 | + # Add a link to diff from stable to current as needed. |
| 1404 | + # Show review status of the diff revision(s). Uses a <table>. |
| 1405 | + $wgOut->addHTML( |
| 1406 | + '<div id="mw-fr-diff-headeritems">' . |
| 1407 | + self::diffLinkAndMarkers( $this->article, $oldRev, $newRev ) . |
| 1408 | + '</div>' |
| 1409 | + ); |
| 1410 | + return true; |
| 1411 | + } |
| 1412 | + |
| 1413 | + // get new diff header items for in-place AJAX page review |
| 1414 | + public static function AjaxBuildDiffHeaderItems() { |
| 1415 | + $args = func_get_args(); // <oldid, newid> |
| 1416 | + if ( count( $args ) >= 2 ) { |
| 1417 | + $oldid = (int)$args[0]; |
| 1418 | + $newid = (int)$args[1]; |
| 1419 | + $oldRev = Revision::newFromId( $oldid ); |
| 1420 | + $newRev = Revision::newFromId( $newid ); |
| 1421 | + if ( $newRev && $newRev->getTitle() ) { |
| 1422 | + $fa = FlaggedPage::getTitleInstance( $newRev->getTitle() ); |
| 1423 | + return self::diffLinkAndMarkers( $fa, $oldRev, $newRev ); |
| 1424 | + } |
| 1425 | + } |
| 1426 | + return ''; |
| 1427 | + } |
| 1428 | + |
| 1429 | + /** |
| 1430 | + * (a) Add a link to diff from stable to current as needed |
| 1431 | + * (b) Show review status of the diff revision(s). Uses a <table>. |
| 1432 | + * Note: used by ajax function to rebuild diff page |
| 1433 | + */ |
| 1434 | + public static function diffLinkAndMarkers( FlaggedPage $article, $oldRev, $newRev ) { |
| 1435 | + $s = '<form id="mw-fr-diff-dataform">'; |
| 1436 | + $s .= Html::hidden( 'oldid', $oldRev ? $oldRev->getId() : 0 ); |
| 1437 | + $s .= Html::hidden( 'newid', $newRev ? $newRev->getId() : 0 ); |
| 1438 | + $s .= "</form>\n"; |
| 1439 | + if ( $newRev ) { // sanity check |
| 1440 | + $s .= self::diffToStableLink( $article, $oldRev, $newRev ); |
| 1441 | + $s .= self::diffReviewMarkers( $article, $oldRev, $newRev ); |
| 1442 | + } |
| 1443 | + return $s; |
| 1444 | + } |
| 1445 | + |
| 1446 | + /** |
| 1447 | + * Add a link to diff-to-stable for reviewable pages |
| 1448 | + */ |
| 1449 | + protected static function diffToStableLink( |
| 1450 | + FlaggedPage $article, $oldRev, Revision $newRev |
| 1451 | + ) { |
| 1452 | + global $wgUser; |
| 1453 | + $srev = $article->getStableRev(); |
| 1454 | + if ( !$srev ) { |
| 1455 | + return ''; // nothing to do |
| 1456 | + } |
| 1457 | + $review = ''; |
| 1458 | + # Is this already the full diff-to-stable? |
| 1459 | + $fullStableDiff = $newRev->isCurrent() |
| 1460 | + && self::isDiffToStable( $srev, $oldRev, $newRev ); |
| 1461 | + # Make a link to the full diff-to-stable if: |
| 1462 | + # (a) Actual revs are pending and (b) We are not viewing the full diff-to-stable |
| 1463 | + if ( $article->revsArePending() && !$fullStableDiff ) { |
| 1464 | + $review = $wgUser->getSkin()->makeKnownLinkObj( |
| 1465 | + $article->getTitle(), |
| 1466 | + wfMsgHtml( 'review-diff2stable' ), |
| 1467 | + 'oldid=' . $srev->getRevId() . '&diff=cur&diffonly=0' |
| 1468 | + ); |
| 1469 | + $review = wfMsgHtml( 'parentheses', $review ); |
| 1470 | + $review = "<div class='fr-diff-to-stable' align='center'>$review</div>"; |
| 1471 | + } |
| 1472 | + return $review; |
| 1473 | + } |
| 1474 | + |
| 1475 | + /** |
| 1476 | + * Add [checked version] and such to left and right side of diff |
| 1477 | + */ |
| 1478 | + protected static function diffReviewMarkers( FlaggedPage $article, $oldRev, $newRev ) { |
| 1479 | + $table = ''; |
| 1480 | + $srev = $article->getStableRev(); |
| 1481 | + # Diff between two revisions |
| 1482 | + if ( $oldRev && $newRev ) { |
| 1483 | + list( $msg, $class ) = self::getDiffRevMsgAndClass( $oldRev, $srev ); |
| 1484 | + $table .= "<table class='fr-diff-ratings'><tr>"; |
| 1485 | + $table .= "<td width='50%' align='center'>"; |
| 1486 | + $table .= "<span class='$class'>[" . |
| 1487 | + wfMsgHtml( $msg ) . "]</span>"; |
| 1488 | + |
| 1489 | + list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev ); |
| 1490 | + $table .= "</td><td width='50%' align='center'>"; |
| 1491 | + $table .= "<span class='$class'>[" . |
| 1492 | + wfMsgHtml( $msg ) . "]</span>"; |
| 1493 | + |
| 1494 | + $table .= "</td></tr></table>\n"; |
| 1495 | + # New page "diffs" - just one rev |
| 1496 | + } elseif ( $newRev ) { |
| 1497 | + list( $msg, $class ) = self::getDiffRevMsgAndClass( $newRev, $srev ); |
| 1498 | + $table .= "<table class='fr-diff-ratings'>"; |
| 1499 | + $table .= "<tr><td align='center'><span class='$class'>"; |
| 1500 | + $table .= '[' . wfMsgHtml( $msg ) . ']'; |
| 1501 | + $table .= "</span></td></tr></table>\n"; |
| 1502 | + } |
| 1503 | + return $table; |
| 1504 | + } |
| 1505 | + |
| 1506 | + protected static function getDiffRevMsgAndClass( |
| 1507 | + Revision $rev, FlaggedRevision $srev = null |
| 1508 | + ) { |
| 1509 | + $tier = FlaggedRevs::getRevQuality( $rev->getPage(), $rev->getId() ); |
| 1510 | + if ( $tier !== false ) { |
| 1511 | + $msg = $tier |
| 1512 | + ? 'revreview-hist-quality' |
| 1513 | + : 'revreview-hist-basic'; |
| 1514 | + } else { |
| 1515 | + $msg = ( $srev && $rev->getTimestamp() > $srev->getRevTimestamp() ) // bug 15515 |
| 1516 | + ? 'revreview-hist-pending' |
| 1517 | + : 'revreview-hist-draft'; |
| 1518 | + } |
| 1519 | + $css = FlaggedRevsXML::getQualityColor( $tier ); |
| 1520 | + return array( $msg, $css ); |
| 1521 | + } |
| 1522 | + |
| 1523 | + // Fetch template changes for a reviewed revision since review |
| 1524 | + // @return array |
| 1525 | + protected static function fetchTemplateChanges( FlaggedRevision $frev ) { |
| 1526 | + global $wgUser; |
| 1527 | + $skin = $wgUser->getSkin(); |
| 1528 | + $diffLinks = array(); |
| 1529 | + $changes = $frev->findPendingTemplateChanges(); |
| 1530 | + foreach ( $changes as $tuple ) { |
| 1531 | + list( $title, $revIdStable ) = $tuple; |
| 1532 | + $diffLinks[] = $skin->makeLinkObj( $title, |
| 1533 | + $title->getPrefixedText(), |
| 1534 | + 'diff=cur&oldid=' . (int)$revIdStable ); |
| 1535 | + } |
| 1536 | + return $diffLinks; |
| 1537 | + } |
| 1538 | + |
| 1539 | + // Fetch file changes for a reviewed revision since review |
| 1540 | + // @return array |
| 1541 | + protected static function fetchFileChanges( FlaggedRevision $frev ) { |
| 1542 | + global $wgUser; |
| 1543 | + $skin = $wgUser->getSkin(); |
| 1544 | + $diffLinks = array(); |
| 1545 | + $changes = $frev->findPendingFileChanges( 'noForeign' ); |
| 1546 | + foreach ( $changes as $tuple ) { |
| 1547 | + list( $title, $revIdStable ) = $tuple; |
| 1548 | + // @TODO: change when MW has file diffs |
| 1549 | + $diffLinks[] = $skin->makeLinkObj( $title, $title->getPrefixedText() ); |
| 1550 | + } |
| 1551 | + return $diffLinks; |
| 1552 | + } |
| 1553 | + |
| 1554 | + /** |
| 1555 | + * Set $this->isDiffFromStable and $this->isMultiPageDiff fields |
| 1556 | + * Note: $oldRev could be false |
| 1557 | + */ |
| 1558 | + public function setViewFlags( $diff, $oldRev, $newRev ) { |
| 1559 | + $this->load(); |
| 1560 | + // We only want valid diffs that actually make sense... |
| 1561 | + if ( $newRev && $oldRev && $newRev->getTimestamp() >= $oldRev->getTimestamp() ) { |
| 1562 | + // Is this a diff between two pages? |
| 1563 | + if ( $newRev->getPage() != $oldRev->getPage() ) { |
| 1564 | + $this->isMultiPageDiff = true; |
| 1565 | + // Is there a stable version? |
| 1566 | + } elseif ( $this->article->isReviewable() ) { |
| 1567 | + $srev = $this->article->getStableRev(); |
| 1568 | + // Is this a diff of a draft rev against the stable rev? |
| 1569 | + if ( self::isDiffToStable( $srev, $oldRev, $newRev ) ) { |
| 1570 | + $this->isDiffFromStable = true; |
| 1571 | + $this->isReviewableDiff = true; |
| 1572 | + // Is this a diff of a draft rev against a reviewed rev? |
| 1573 | + } elseif ( |
| 1574 | + FlaggedRevision::newFromTitle( $diff->getTitle(), $oldRev->getId() ) || |
| 1575 | + FlaggedRevision::newFromTitle( $diff->getTitle(), $newRev->getId() ) |
| 1576 | + ) { |
| 1577 | + $this->isReviewableDiff = true; |
| 1578 | + } |
| 1579 | + } |
| 1580 | + $this->diffRevs = array( 'old' => $oldRev, 'new' => $newRev ); |
| 1581 | + } |
| 1582 | + return true; |
| 1583 | + } |
| 1584 | + |
| 1585 | + // Is a diff from $oldRev to $newRev a diff-to-stable? |
| 1586 | + protected static function isDiffToStable( $srev, $oldRev, $newRev ) { |
| 1587 | + return ( $srev && $oldRev && $newRev |
| 1588 | + && $oldRev->getPage() == $newRev->getPage() // no multipage diffs |
| 1589 | + && $oldRev->getId() == $srev->getRevId() |
| 1590 | + && $newRev->getTimestamp() >= $oldRev->getTimestamp() // no backwards diffs |
| 1591 | + ); |
| 1592 | + } |
| 1593 | + |
| 1594 | + /** |
| 1595 | + * Redirect users out to review the changes to the stable version. |
| 1596 | + * Only for people who can review and for pages that have a stable version. |
| 1597 | + */ |
| 1598 | + public function injectPostEditURLParams( &$sectionAnchor, &$extraQuery ) { |
| 1599 | + global $wgUser; |
| 1600 | + $this->load(); |
| 1601 | + $this->article->loadFromDB( FR_MASTER ); |
| 1602 | + # Get the stable version from the master |
| 1603 | + $frev = $this->article->getStableRev(); |
| 1604 | + if ( !$frev || !$this->article->revsArePending() ) { |
| 1605 | + return true; // only for pages with pending edits |
| 1606 | + } |
| 1607 | + // If the edit was not autoreviewed, and the user can actually make a |
| 1608 | + // new stable version, then go to the diff... |
| 1609 | + if ( $frev->userCanSetFlags( $wgUser ) ) { |
| 1610 | + $extraQuery .= $extraQuery ? '&' : ''; |
| 1611 | + // Override diffonly setting to make sure the content is shown |
| 1612 | + $extraQuery .= 'oldid=' . $frev->getRevId() . '&diff=cur&diffonly=0&shownotice=1'; |
| 1613 | + // ...otherwise, go to the draft revision after completing an edit. |
| 1614 | + // This allows for users to immediately see their changes. |
| 1615 | + } else { |
| 1616 | + $extraQuery .= $extraQuery ? '&' : ''; |
| 1617 | + $extraQuery .= 'stable=0'; |
| 1618 | + // Show a notice at the top of the page for non-reviewers... |
| 1619 | + if ( !$wgUser->isAllowed( 'review' ) && $this->article->isStableShownByDefault() ) { |
| 1620 | + $extraQuery .= '&shownotice=1'; |
| 1621 | + if ( $sectionAnchor ) { |
| 1622 | + // Pass a section parameter in the URL as needed to add a link to |
| 1623 | + // the "your changes are pending" box on the top of the page... |
| 1624 | + $section = str_replace( |
| 1625 | + array( ':' , '.' ), array( '%3A', '%' ), // hack: reverse encoding |
| 1626 | + substr( $sectionAnchor, 1 ) // remove the '#' |
| 1627 | + ); |
| 1628 | + $extraQuery .= '&fromsection=' . $section; |
| 1629 | + $sectionAnchor = ''; // go to the top of the page to see notice |
| 1630 | + } |
| 1631 | + } |
| 1632 | + } |
| 1633 | + return true; |
| 1634 | + } |
| 1635 | + |
| 1636 | + /** |
| 1637 | + * If submitting the edit will leave it pending, then change the button text |
| 1638 | + * Note: interacts with 'review pending changes' checkbox |
| 1639 | + * @TODO: would be nice if hook passed in button attribs, not XML |
| 1640 | + */ |
| 1641 | + public function changeSaveButton( EditPage $editPage, array &$buttons ) { |
| 1642 | + if ( !$this->editWillRequireReview( $editPage ) ) { |
| 1643 | + return true; // edit will go live or be reviewed on save |
| 1644 | + } |
| 1645 | + if ( extension_loaded( 'domxml' ) ) { |
| 1646 | + wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" ); |
| 1647 | + return true; # PECL extension conflicts with the core DOM extension (see bug 13770) |
| 1648 | + } elseif ( isset( $buttons['save'] ) && extension_loaded( 'dom' ) ) { |
| 1649 | + $dom = new DOMDocument(); |
| 1650 | + $dom->loadXML( $buttons['save'] ); // load button XML from hook |
| 1651 | + foreach ( $dom->getElementsByTagName( 'input' ) as $input ) { // one <input> |
| 1652 | + $input->setAttribute( 'value', wfMsg( 'revreview-submitedit' ) ); |
| 1653 | + $input->setAttribute( 'title', // keep accesskey |
| 1654 | + wfMsgExt( 'revreview-submitedit-title', 'parsemag' ) . |
| 1655 | + ' [' . wfMsg( 'accesskey-save' ) . ']' ); |
| 1656 | + # Change submit button text & title |
| 1657 | + $buttons['save'] = $dom->saveXML( $dom->documentElement ); |
| 1658 | + } |
| 1659 | + } |
| 1660 | + return true; |
| 1661 | + } |
| 1662 | + |
| 1663 | + /** |
| 1664 | + * If this edit will not go live on submit (accounting for wpReviewEdit) |
| 1665 | + * @param EditPage $editPage |
| 1666 | + * @return bool |
| 1667 | + */ |
| 1668 | + protected function editWillRequireReview( EditPage $editPage ) { |
| 1669 | + global $wgRequest; |
| 1670 | + $title = $this->article->getTitle(); // convenience |
| 1671 | + if ( !$this->editRequiresReview( $editPage ) ) { |
| 1672 | + return false; // edit will go live immediatly |
| 1673 | + } elseif ( $wgRequest->getCheck( 'wpReviewEdit' ) && $title->userCan( 'review' ) ) { |
| 1674 | + return false; // edit checked off to be reviewed on save |
| 1675 | + } |
| 1676 | + return true; // edit needs review |
| 1677 | + } |
| 1678 | + |
| 1679 | + /** |
| 1680 | + * If this edit will not go live on submit unless wpReviewEdit is checked |
| 1681 | + * @param EditPage $editPage |
| 1682 | + * @return bool |
| 1683 | + */ |
| 1684 | + protected function editRequiresReview( EditPage $editPage ) { |
| 1685 | + if ( !$this->article->editsRequireReview() ) { |
| 1686 | + return false; // edits go live immediatly |
| 1687 | + } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) { |
| 1688 | + return false; // edit will be autoreviewed anyway |
| 1689 | + } |
| 1690 | + return true; // edit needs review |
| 1691 | + } |
| 1692 | + |
| 1693 | + /** |
| 1694 | + * If this edit will be auto-reviewed on submit |
| 1695 | + * Note: checking wpReviewEdit does not count as auto-reviewed |
| 1696 | + * @param EditPage $editPage |
| 1697 | + * @return bool |
| 1698 | + */ |
| 1699 | + protected function editWillBeAutoreviewed( EditPage $editPage ) { |
| 1700 | + $title = $this->article->getTitle(); // convenience |
| 1701 | + if ( !$this->article->isReviewable() ) { |
| 1702 | + return false; |
| 1703 | + } |
| 1704 | + if ( $title->userCan( 'autoreview' ) ) { |
| 1705 | + if ( FlaggedRevs::autoReviewNewPages() && !$this->article->exists() ) { |
| 1706 | + return true; // edit will be autoreviewed |
| 1707 | + } |
| 1708 | + if ( !isset( $editPage->fr_baseFRev ) ) { |
| 1709 | + $baseRevId = self::getBaseRevId( $editPage ); |
| 1710 | + $editPage->fr_baseFRev = FlaggedRevision::newFromTitle( $title, $baseRevId ); |
| 1711 | + } |
| 1712 | + if ( $editPage->fr_baseFRev ) { |
| 1713 | + return true; // edit will be autoreviewed |
| 1714 | + } |
| 1715 | + } |
| 1716 | + return false; // edit won't be autoreviewed |
| 1717 | + } |
| 1718 | + |
| 1719 | + /** |
| 1720 | + * Add a "review pending changes" checkbox to the edit form iff: |
| 1721 | + * (a) there are currently any revisions pending (bug 16713) |
| 1722 | + * (b) this is an unreviewed page (bug 23970) |
| 1723 | + */ |
| 1724 | + public function addReviewCheck( EditPage $editPage, array &$checkboxes, &$tabindex ) { |
| 1725 | + global $wgRequest; |
| 1726 | + $title = $this->article->getTitle(); // convenience |
| 1727 | + if ( !$this->article->isReviewable() || !$title->userCan( 'review' ) ) { |
| 1728 | + return true; // not needed |
| 1729 | + } elseif ( $this->editWillBeAutoreviewed( $editPage ) ) { |
| 1730 | + return true; // edit will be auto-reviewed |
| 1731 | + } |
| 1732 | + if ( self::getBaseRevId( $editPage ) == $this->article->getLatest() ) { |
| 1733 | + # For pages with either no stable version, or an outdated one, let |
| 1734 | + # the user decide if he/she wants it reviewed on the spot. One might |
| 1735 | + # do this if he/she just saw the diff-to-stable and *then* decided to edit. |
| 1736 | + # Note: check not shown when editing old revisions, which is confusing. |
| 1737 | + $checkbox = Xml::check( |
| 1738 | + 'wpReviewEdit', |
| 1739 | + $wgRequest->getCheck( 'wpReviewEdit' ), |
| 1740 | + array( 'tabindex' => ++$tabindex, 'id' => 'wpReviewEdit' ) |
| 1741 | + ); |
| 1742 | + $attribs = array( 'for' => 'wpReviewEdit' ); |
| 1743 | + // For reviewed pages... |
| 1744 | + if ( $this->article->getStable() ) { |
| 1745 | + // For pending changes... |
| 1746 | + if ( $this->article->revsArePending() ) { |
| 1747 | + $n = $this->article->getPendingRevCount(); |
| 1748 | + $attribs['title'] = wfMsg( 'revreview-check-flag-p-title' ); |
| 1749 | + $labelMsg = wfMsgExt( 'revreview-check-flag-p', 'parseinline', $n ); |
| 1750 | + // For just the user's changes... |
| 1751 | + } else { |
| 1752 | + $attribs['title'] = wfMsgExt( 'revreview-check-flag-y-title', 'parsemag' ); |
| 1753 | + $labelMsg = wfMsgExt( 'revreview-check-flag-y', 'parseinline' ); |
| 1754 | + } |
| 1755 | + // For unreviewed pages... |
| 1756 | + } else { |
| 1757 | + $attribs['title'] = wfMsg( 'revreview-check-flag-u-title' ); |
| 1758 | + $labelMsg = wfMsgExt( 'revreview-check-flag-u', 'parseinline' ); |
| 1759 | + } |
| 1760 | + $label = Xml::element( 'label', $attribs, $labelMsg ); |
| 1761 | + $checkboxes['reviewed'] = $checkbox . ' ' . $label; |
| 1762 | + } |
| 1763 | + return true; |
| 1764 | + } |
| 1765 | + |
| 1766 | + /** |
| 1767 | + * (a) Add a hidden field that has the rev ID the text is based off. |
| 1768 | + * (b) If an edit was undone, add a hidden field that has the rev ID of that edit. |
| 1769 | + * Needed for autoreview and user stats (for autopromote). |
| 1770 | + * Note: baseRevId trusted for Reviewers - text checked for others. |
| 1771 | + */ |
| 1772 | + public function addRevisionIDField( EditPage $editPage, OutputPage $out ) { |
| 1773 | + $this->load(); |
| 1774 | + $revId = self::getBaseRevId( $editPage ); |
| 1775 | + $out->addHTML( "\n" . Html::hidden( 'baseRevId', $revId ) ); |
| 1776 | + $out->addHTML( "\n" . Html::hidden( 'undidRev', |
| 1777 | + empty( $editPage->undidRev ) ? 0 : $editPage->undidRev ) |
| 1778 | + ); |
| 1779 | + return true; |
| 1780 | + } |
| 1781 | + |
| 1782 | + /** |
| 1783 | + * Guess the rev ID the text of this form is based off |
| 1784 | + * Note: baseRevId trusted for Reviewers - check text for others. |
| 1785 | + * @return int |
| 1786 | + */ |
| 1787 | + protected static function getBaseRevId( EditPage $editPage ) { |
| 1788 | + global $wgRequest; |
| 1789 | + if ( !isset( $editPage->fr_baseRevId ) ) { |
| 1790 | + $article = $editPage->getArticle(); // convenience |
| 1791 | + $latestId = $article->getLatest(); // current rev |
| 1792 | + $undo = $wgRequest->getIntOrNull( 'undo' ); |
| 1793 | + # Undoing consecutive top edits... |
| 1794 | + if ( $undo && $undo === $latestId ) { |
| 1795 | + # Treat this like a revert to a base revision. |
| 1796 | + # We are undoing all edits *after* some rev ID (undoafter). |
| 1797 | + # If undoafter is not given, then it is the previous rev ID. |
| 1798 | + $revId = $wgRequest->getInt( 'undoafter', |
| 1799 | + $article->getTitle()->getPreviousRevisionID( $latestId, Title::GAID_FOR_UPDATE ) ); |
| 1800 | + # Undoing other edits... |
| 1801 | + } elseif ( $undo ) { |
| 1802 | + $revId = $latestId; // current rev is the base rev |
| 1803 | + # Other edits... |
| 1804 | + } else { |
| 1805 | + # If we are editing via oldid=X, then use that rev ID. |
| 1806 | + # Otherwise, check if the client specified the ID (bug 23098). |
| 1807 | + $revId = $article->getOldID() |
| 1808 | + ? $article->getOldID() |
| 1809 | + : $wgRequest->getInt( 'baseRevId' ); // e.g. "show changes"/"preview" |
| 1810 | + } |
| 1811 | + # Zero oldid => draft revision |
| 1812 | + if ( !$revId ) { |
| 1813 | + $revId = $latestId; |
| 1814 | + } |
| 1815 | + $editPage->fr_baseRevId = $revId; |
| 1816 | + } |
| 1817 | + return $editPage->fr_baseRevId; |
| 1818 | + } |
| 1819 | + |
| 1820 | + /** |
| 1821 | + * Adds brief review notes to a page. |
| 1822 | + * @param OutputPage $out |
| 1823 | + */ |
| 1824 | + public function addReviewNotes( &$data ) { |
| 1825 | + $this->load(); |
| 1826 | + if ( $this->reviewNotes ) { |
| 1827 | + $data .= $this->reviewNotes; |
| 1828 | + } |
| 1829 | + return true; |
| 1830 | + } |
| 1831 | + |
| 1832 | + /* |
| 1833 | + * If this is a diff page then replace the article contents with a link |
| 1834 | + * to the specific revision. This will be replaced with article content |
| 1835 | + * using javascript and an api call. |
| 1836 | + */ |
| 1837 | + public function addCustomContentHtml( OutputPage $out, $newRevId ) { |
| 1838 | + $this->load(); |
| 1839 | + if ( $newRevId ) { |
| 1840 | + $out->addHTML( "<div id='mw-fr-revisioncontents'><span class='plainlinks'>" ); |
| 1841 | + $out->addWikiMsg( 'revcontents-getcontents', |
| 1842 | + $this->article->getTitle()->getPrefixedDBKey(), $newRevId ); |
| 1843 | + $out->addHTML( "</span></div>" ); |
| 1844 | + } |
| 1845 | + } |
| 1846 | +} |
Property changes on: trunk/extensions/FlaggedRevs/presentation/FlaggedPageView.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 1847 | + native |
Index: trunk/extensions/FlaggedRevs/presentation/modules/review.js |
— | — | @@ -265,7 +265,7 @@ |
266 | 266 | requestArgs.push( diffUIParams.getElementsByTagName('input')[0].value ); |
267 | 267 | requestArgs.push( diffUIParams.getElementsByTagName('input')[1].value ); |
268 | 268 | // Send encoded function plus all arguments... |
269 | | - url_pars = '?action=ajax&rs=FlaggedArticleView::AjaxBuildDiffHeaderItems'; |
| 269 | + url_pars = '?action=ajax&rs=FlaggedPageView::AjaxBuildDiffHeaderItems'; |
270 | 270 | for( var i=0; i<requestArgs.length; i++ ) { |
271 | 271 | url_pars += '&rsargs[]=' + encodeURIComponent(requestArgs[i]); |
272 | 272 | } |
Index: trunk/extensions/FlaggedRevs/presentation/FlaggedRevsLogView.php |
— | — | @@ -3,7 +3,7 @@ |
4 | 4 | class FlaggedRevsLogView { |
5 | 5 | /** |
6 | 6 | * Add setting change description to log line |
7 | | - * @returns string |
| 7 | + * @return string |
8 | 8 | */ |
9 | 9 | public static function stabilityLogText( |
10 | 10 | $type, $action, $title = null, $skin = null, $params = array() |
— | — | @@ -31,7 +31,7 @@ |
32 | 32 | * @param Title $title |
33 | 33 | * @param string $timestamp |
34 | 34 | * @param array $params |
35 | | - * @returns string |
| 35 | + * @return string |
36 | 36 | */ |
37 | 37 | public static function stabilityLogLinks( $title, $timestamp, $params ) { |
38 | 38 | global $wgUser; |
— | — | @@ -51,9 +51,9 @@ |
52 | 52 | * |
53 | 53 | * @param array $pars assoc array |
54 | 54 | * @param bool $forContent |
55 | | - * @returns string |
| 55 | + * @return string |
56 | 56 | */ |
57 | | - public static function stabilitySettings( Array $pars, $forContent ) { |
| 57 | + public static function stabilitySettings( array $pars, $forContent ) { |
58 | 58 | global $wgLang, $wgContLang; |
59 | 59 | $set = array(); |
60 | 60 | $settings = ''; |
Index: trunk/extensions/FlaggedRevs/FlaggedPage.php |
— | — | @@ -0,0 +1,541 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Class representing a MediaWiki article and history |
| 5 | + * |
| 6 | + * FlaggedPage::getTitleInstance() is preferred over constructor calls |
| 7 | + */ |
| 8 | +class FlaggedPage extends Article { |
| 9 | + /* Process cache variables */ |
| 10 | + protected $stable = 0; |
| 11 | + protected $stableRev = null; |
| 12 | + protected $revsArePending = null; |
| 13 | + protected $pendingRevCount = null; |
| 14 | + protected $pageConfig = null; |
| 15 | + protected $syncedInTracking = null; |
| 16 | + |
| 17 | + protected $imagePage = null; // for file pages |
| 18 | + |
| 19 | + /** |
| 20 | + * Get a FlaggedPage for a given title |
| 21 | + * @param Title |
| 22 | + * @return FlaggedPage |
| 23 | + */ |
| 24 | + public static function getTitleInstance( Title $title ) { |
| 25 | + // Check if there is already an instance on this title |
| 26 | + if ( !isset( $title->flaggedRevsArticle ) ) { |
| 27 | + $title->flaggedRevsArticle = new self( $title ); |
| 28 | + } |
| 29 | + return $title->flaggedRevsArticle; |
| 30 | + } |
| 31 | + |
| 32 | + /** |
| 33 | + * Get a FlaggedPage for a given article |
| 34 | + * @param Article |
| 35 | + * @return FlaggedPage |
| 36 | + */ |
| 37 | + public static function getArticleInstance( Article $article ) { |
| 38 | + return self::getTitleInstance( $article->mTitle ); |
| 39 | + } |
| 40 | + |
| 41 | + /** |
| 42 | + * Clear object process cache values |
| 43 | + * @return void |
| 44 | + */ |
| 45 | + public function clear() { |
| 46 | + $this->stable = 0; |
| 47 | + $this->stableRev = null; |
| 48 | + $this->revsArePending = null; |
| 49 | + $this->pendingRevCount = null; |
| 50 | + $this->pageConfig = null; |
| 51 | + $this->syncedInTracking = null; |
| 52 | + $this->imagePage = null; |
| 53 | + parent::clear(); // call super! |
| 54 | + } |
| 55 | + |
| 56 | + /** |
| 57 | + * Get the current file version of this file page |
| 58 | + * @TODO: kind of hacky |
| 59 | + * @return mixed (File/false) |
| 60 | + */ |
| 61 | + public function getFile() { |
| 62 | + if ( $this->mTitle->getNamespace() != NS_FILE ) { |
| 63 | + return false; // not a file page |
| 64 | + } |
| 65 | + if ( is_null( $this->imagePage ) ) { |
| 66 | + $this->imagePage = new ImagePage( $this->mTitle ); |
| 67 | + } |
| 68 | + return $this->imagePage->getFile(); |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * Get the displayed file version of this file page |
| 73 | + * @TODO: kind of hacky |
| 74 | + * @return mixed (File/false) |
| 75 | + */ |
| 76 | + public function getDisplayedFile() { |
| 77 | + if ( $this->mTitle->getNamespace() != NS_FILE ) { |
| 78 | + return false; // not a file page |
| 79 | + } |
| 80 | + if ( is_null( $this->imagePage ) ) { |
| 81 | + $this->imagePage = new ImagePage( $this->mTitle ); |
| 82 | + } |
| 83 | + return $this->imagePage->getDisplayedFile(); |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + * Is the stable version shown by default for this page? |
| 88 | + * @return bool |
| 89 | + */ |
| 90 | + public function isStableShownByDefault() { |
| 91 | + if ( !$this->isReviewable() ) { |
| 92 | + return false; // no stable versions can exist |
| 93 | + } |
| 94 | + $config = $this->getStabilitySettings(); // page configuration |
| 95 | + return (bool)$config['override']; |
| 96 | + } |
| 97 | + |
| 98 | + /** |
| 99 | + * Do edits have to be reviewed before being shown by default (going live)? |
| 100 | + * @return bool |
| 101 | + */ |
| 102 | + public function editsRequireReview() { |
| 103 | + return ( |
| 104 | + $this->isReviewable() && // reviewable page |
| 105 | + $this->isStableShownByDefault() && // and stable versions override |
| 106 | + $this->getStableRev() // and there is a stable version |
| 107 | + ); |
| 108 | + } |
| 109 | + |
| 110 | + /** |
| 111 | + * Are edits to this page currently pending? |
| 112 | + * @return bool |
| 113 | + */ |
| 114 | + public function revsArePending() { |
| 115 | + if ( !$this->mDataLoaded ) { |
| 116 | + $this->loadPageData(); |
| 117 | + } |
| 118 | + return $this->revsArePending; |
| 119 | + } |
| 120 | + |
| 121 | + /** |
| 122 | + * Get number of revs since the stable revision |
| 123 | + * Note: slower than revsArePending() |
| 124 | + * @param int $flags FR_MASTER (be sure to use loadFromDB( FR_MASTER ) if set) |
| 125 | + * @return int |
| 126 | + */ |
| 127 | + public function getPendingRevCount( $flags = 0 ) { |
| 128 | + global $wgMemc, $wgParserCacheExpireTime; |
| 129 | + if ( !$this->mDataLoaded ) { |
| 130 | + $this->loadPageData(); |
| 131 | + } |
| 132 | + # Pending count deferred even after page data load |
| 133 | + if ( $this->pendingRevCount !== null ) { |
| 134 | + return $this->pendingRevCount; // use process cache |
| 135 | + } |
| 136 | + $srev = $this->getStableRev(); |
| 137 | + if ( !$srev ) { |
| 138 | + return 0; // none |
| 139 | + } |
| 140 | + $count = null; |
| 141 | + $sRevId = $srev->getRevId(); |
| 142 | + # Try the cache... |
| 143 | + $key = wfMemcKey( 'flaggedrevs', 'countPending', $this->getId() ); |
| 144 | + if ( !( $flags & FR_MASTER ) ) { |
| 145 | + $tuple = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this ); |
| 146 | + # Items is cached and newer that page_touched... |
| 147 | + if ( $tuple !== false ) { |
| 148 | + # Confirm that cache value was made against the same stable rev Id. |
| 149 | + # This avoids lengthy cache pollution if $sRevId is outdated. |
| 150 | + list( $cRevId, $cPending ) = explode( '-', $tuple, 2 ); |
| 151 | + if ( $cRevId == $sRevId ) { |
| 152 | + $count = (int)$cPending; |
| 153 | + } |
| 154 | + } |
| 155 | + } |
| 156 | + # Otherwise, fetch result from DB as needed... |
| 157 | + if ( is_null( $count ) ) { |
| 158 | + $db = ( $flags & FR_MASTER ) ? |
| 159 | + wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE ); |
| 160 | + $srevTS = $db->timestamp( $srev->getRevTimestamp() ); |
| 161 | + $count = $db->selectField( 'revision', 'COUNT(*)', |
| 162 | + array( 'rev_page' => $this->getId(), |
| 163 | + 'rev_timestamp > ' . $db->addQuotes( $srevTS ) ), // bug 15515 |
| 164 | + __METHOD__ ); |
| 165 | + # Save result to cache... |
| 166 | + $data = FlaggedRevs::makeMemcObj( "{$sRevId}-{$count}" ); |
| 167 | + $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
| 168 | + } |
| 169 | + $this->pendingRevCount = $count; |
| 170 | + return $this->pendingRevCount; |
| 171 | + } |
| 172 | + |
| 173 | + /** |
| 174 | + * Checks if the stable version is synced with the current revision |
| 175 | + * Note: slower than getPendingRevCount() |
| 176 | + * @return bool |
| 177 | + */ |
| 178 | + public function stableVersionIsSynced() { |
| 179 | + global $wgMemc, $wgParserCacheExpireTime; |
| 180 | + $srev = $this->getStableRev(); |
| 181 | + if ( !$srev ) { |
| 182 | + return true; |
| 183 | + } |
| 184 | + # Stable text revision must be the same as the current |
| 185 | + if ( $this->revsArePending() ) { |
| 186 | + return false; |
| 187 | + # Stable file revision must be the same as the current |
| 188 | + } elseif ( $this->mTitle->getNamespace() == NS_FILE ) { |
| 189 | + $file = $this->getFile(); // current upload version |
| 190 | + if ( $file && $file->getTimestamp() > $srev->getFileTimestamp() ) { |
| 191 | + return false; |
| 192 | + } |
| 193 | + } |
| 194 | + # If using the current version of includes, there is nothing else to check. |
| 195 | + if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_CURRENT ) { |
| 196 | + return true; // short-circuit |
| 197 | + } |
| 198 | + # Try the cache... |
| 199 | + $key = wfMemcKey( 'flaggedrevs', 'includesSynced', $this->getId() ); |
| 200 | + $value = FlaggedRevs::getMemcValue( $wgMemc->get( $key ), $this ); |
| 201 | + if ( $value === "true" ) { |
| 202 | + return true; |
| 203 | + } elseif ( $value === "false" ) { |
| 204 | + return false; |
| 205 | + } |
| 206 | + # Since the stable and current revisions have the same text and only outputs, |
| 207 | + # the only other things to check for are template and file differences in the output. |
| 208 | + # (a) Check if the current output has a newer template/file used |
| 209 | + # (b) Check if the stable version has a file/template that was deleted |
| 210 | + $synced = ( !$srev->findPendingTemplateChanges() |
| 211 | + && !$srev->findPendingFileChanges( 'noForeign' ) ); |
| 212 | + # Save to cache. This will be updated whenever the page is touched. |
| 213 | + $data = FlaggedRevs::makeMemcObj( $synced ? "true" : "false" ); |
| 214 | + $wgMemc->set( $key, $data, $wgParserCacheExpireTime ); |
| 215 | + |
| 216 | + return $synced; |
| 217 | + } |
| 218 | + |
| 219 | + /** |
| 220 | + * Are template/file changes and ONLY template/file changes pending? |
| 221 | + * @return bool |
| 222 | + */ |
| 223 | + public function onlyTemplatesOrFilesPending() { |
| 224 | + return ( !$this->revsArePending() && !$this->stableVersionIsSynced() ); |
| 225 | + } |
| 226 | + |
| 227 | + /** |
| 228 | + * Is this page less open than the site defaults? |
| 229 | + * @return bool |
| 230 | + */ |
| 231 | + public function isPageLocked() { |
| 232 | + return ( !FlaggedRevs::isStableShownByDefault() && $this->isStableShownByDefault() ); |
| 233 | + } |
| 234 | + |
| 235 | + /** |
| 236 | + * Is this page more open than the site defaults? |
| 237 | + * @return bool |
| 238 | + */ |
| 239 | + public function isPageUnlocked() { |
| 240 | + return ( FlaggedRevs::isStableShownByDefault() && !$this->isStableShownByDefault() ); |
| 241 | + } |
| 242 | + |
| 243 | + /** |
| 244 | + * Tags are only shown for unreviewed content and this page is not locked/unlocked? |
| 245 | + * @return bool |
| 246 | + */ |
| 247 | + public function lowProfileUI() { |
| 248 | + return FlaggedRevs::lowProfileUI() && |
| 249 | + FlaggedRevs::isStableShownByDefault() == $this->isStableShownByDefault(); |
| 250 | + } |
| 251 | + |
| 252 | + /** |
| 253 | + * Is this article reviewable? |
| 254 | + * @return bool |
| 255 | + */ |
| 256 | + public function isReviewable() { |
| 257 | + if ( !FlaggedRevs::inReviewNamespace( $this->mTitle ) ) { |
| 258 | + return false; |
| 259 | + } |
| 260 | + # Check if flagging is disabled for this page via config |
| 261 | + if ( FlaggedRevs::useOnlyIfProtected() ) { |
| 262 | + $config = $this->getStabilitySettings(); // page configuration |
| 263 | + return (bool)$config['override']; // stable is default or flagging disabled |
| 264 | + } |
| 265 | + return true; |
| 266 | + } |
| 267 | + |
| 268 | + /** |
| 269 | + * Is this page in patrollable? |
| 270 | + * @return bool |
| 271 | + */ |
| 272 | + public function isPatrollable() { |
| 273 | + if ( !FlaggedRevs::inPatrolNamespace( $this->mTitle ) ) { |
| 274 | + return false; |
| 275 | + } |
| 276 | + return !$this->isReviewable(); // pages that are reviewable are not patrollable |
| 277 | + } |
| 278 | + |
| 279 | + /** |
| 280 | + * Get the stable revision ID |
| 281 | + * @return int |
| 282 | + */ |
| 283 | + public function getStable() { |
| 284 | + if ( !$this->mDataLoaded ) { |
| 285 | + $this->loadPageData(); |
| 286 | + } |
| 287 | + return (int)$this->stable; |
| 288 | + } |
| 289 | + |
| 290 | + /** |
| 291 | + * Get the stable revision |
| 292 | + * @return mixed (FlaggedRevision/null) |
| 293 | + */ |
| 294 | + public function getStableRev() { |
| 295 | + if ( !$this->mDataLoaded ) { |
| 296 | + $this->loadPageData(); |
| 297 | + } |
| 298 | + # Stable rev deferred even after page data load |
| 299 | + if ( $this->stableRev === null ) { |
| 300 | + $srev = FlaggedRevision::newFromTitle( $this->mTitle, $this->stable ); |
| 301 | + $this->stableRev = $srev ? $srev : false; // cache negative hits too |
| 302 | + } |
| 303 | + return $this->stableRev ? $this->stableRev : null; // false => null |
| 304 | + } |
| 305 | + |
| 306 | + /** |
| 307 | + * Get visiblity restrictions on page |
| 308 | + * @return array (select,override) |
| 309 | + */ |
| 310 | + public function getStabilitySettings() { |
| 311 | + if ( !$this->mDataLoaded ) { |
| 312 | + $this->loadPageData(); |
| 313 | + } |
| 314 | + return $this->pageConfig; |
| 315 | + } |
| 316 | + |
| 317 | + /* |
| 318 | + * Get the fp_reviewed value for this page |
| 319 | + * @return bool |
| 320 | + */ |
| 321 | + public function syncedInTracking() { |
| 322 | + if ( !$this->mDataLoaded ) { |
| 323 | + $this->loadPageData(); |
| 324 | + } |
| 325 | + return $this->syncedInTracking; |
| 326 | + } |
| 327 | + |
| 328 | + /** |
| 329 | + * Fetch a page record with the given conditions |
| 330 | + * @param $dbr Database object |
| 331 | + * @param $conditions Array |
| 332 | + * @return mixed Database result resource, or false on failure |
| 333 | + */ |
| 334 | + protected function pageData( $dbr, $conditions ) { |
| 335 | + $row = $dbr->selectRow( |
| 336 | + array( 'page', 'flaggedpages', 'flaggedpage_config' ), |
| 337 | + array_merge( |
| 338 | + Article::selectFields(), |
| 339 | + FlaggedPageConfig::selectFields(), |
| 340 | + array( 'fp_pending_since', 'fp_stable', 'fp_reviewed' ) ), |
| 341 | + $conditions, |
| 342 | + __METHOD__, |
| 343 | + array(), |
| 344 | + array( |
| 345 | + 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ), |
| 346 | + 'flaggedpage_config' => array( 'LEFT JOIN', 'fpc_page_id = page_id' ) ) |
| 347 | + ); |
| 348 | + return $row; |
| 349 | + } |
| 350 | + |
| 351 | + /** |
| 352 | + * Set the page field data loaded from some source |
| 353 | + * @param $data Database row object or "fromdb" |
| 354 | + * @return void |
| 355 | + */ |
| 356 | + public function loadPageData( $data = 'fromdb' ) { |
| 357 | + $this->mDataLoaded = true; // sanity |
| 358 | + # Fetch data from DB as needed... |
| 359 | + if ( $data === 'fromdb' ) { |
| 360 | + $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle ); |
| 361 | + } |
| 362 | + # Load in primary page data... |
| 363 | + parent::loadPageData( $data /* Row obj */ ); |
| 364 | + # Load in FlaggedRevs page data... |
| 365 | + $this->stable = 0; // 0 => "found nothing" |
| 366 | + $this->stableRev = null; // defer this one... |
| 367 | + $this->revsArePending = false; // false => "found nothing" or "none pending" |
| 368 | + $this->pendingRevCount = null; // defer this one... |
| 369 | + $this->pageConfig = FlaggedPageConfig::getDefaultVisibilitySettings(); // default |
| 370 | + $this->syncedInTracking = true; // false => "unreviewed" or "synced" |
| 371 | + # Load in Row data if the page exists... |
| 372 | + if ( $data ) { |
| 373 | + if ( $data->fpc_override !== null ) { // page config row found |
| 374 | + $this->pageConfig = FlaggedPageConfig::getVisibilitySettingsFromRow( $data ); |
| 375 | + } |
| 376 | + if ( $data->fp_stable !== null ) { // stable rev found |
| 377 | + $this->stable = (int)$data->fp_stable; |
| 378 | + $this->revsArePending = ( $data->fp_pending_since !== null ); // revs await review |
| 379 | + $this->syncedInTracking = (bool)$data->fp_reviewed; |
| 380 | + } |
| 381 | + } |
| 382 | + } |
| 383 | + |
| 384 | + /** |
| 385 | + * Set the page field data loaded from the DB |
| 386 | + * @param int $flags FR_MASTER |
| 387 | + * @param $data Database row object or "fromdb" |
| 388 | + */ |
| 389 | + public function loadFromDB( $flags = 0 ) { |
| 390 | + $db = ( $flags & FR_MASTER ) ? |
| 391 | + wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE ); |
| 392 | + $this->loadPageData( $this->pageDataFromTitle( $db, $this->mTitle ) ); |
| 393 | + } |
| 394 | + |
| 395 | + /** |
| 396 | + * Updates the flagging tracking tables for this page |
| 397 | + * @param FlaggedRevision $srev The new stable version |
| 398 | + * @param int|null $latest The latest rev ID (optional) |
| 399 | + * @return bool Updates were done |
| 400 | + */ |
| 401 | + public function updateStableVersion( FlaggedRevision $srev, $latest = null ) { |
| 402 | + $rev = $srev->getRevision(); |
| 403 | + if ( !$this->exists() || !$rev ) { |
| 404 | + return false; // no bogus entries |
| 405 | + } |
| 406 | + # Get the latest revision ID if not set |
| 407 | + if ( !$latest ) { |
| 408 | + $latest = $this->mTitle->getLatestRevID( Title::GAID_FOR_UPDATE ); |
| 409 | + } |
| 410 | + $dbw = wfGetDB( DB_MASTER ); |
| 411 | + # Get the highest quality revision (not necessarily this one)... |
| 412 | + if ( $srev->getQuality() === FlaggedRevs::highestReviewTier() ) { |
| 413 | + $maxQuality = $srev->getQuality(); // save a query |
| 414 | + } else { |
| 415 | + $maxQuality = $dbw->selectField( array( 'flaggedrevs', 'revision' ), |
| 416 | + 'fr_quality', |
| 417 | + array( 'fr_page_id' => $this->getId(), |
| 418 | + 'rev_id = fr_rev_id', |
| 419 | + 'rev_page = fr_page_id', |
| 420 | + 'rev_deleted & ' . Revision::DELETED_TEXT => 0 |
| 421 | + ), |
| 422 | + __METHOD__, |
| 423 | + array( 'ORDER BY' => 'fr_quality DESC', 'LIMIT' => 1 ) |
| 424 | + ); |
| 425 | + $maxQuality = max( $maxQuality, $srev->getQuality() ); // sanity |
| 426 | + } |
| 427 | + # Get the timestamp of the first edit after the stable version (if any)... |
| 428 | + $nextTimestamp = null; |
| 429 | + if ( $rev->getId() != $latest ) { |
| 430 | + $timestamp = $dbw->timestamp( $rev->getTimestamp() ); |
| 431 | + $nextEditTS = $dbw->selectField( 'revision', |
| 432 | + 'rev_timestamp', |
| 433 | + array( |
| 434 | + 'rev_page' => $this->getId(), |
| 435 | + "rev_timestamp > " . $dbw->addQuotes( $timestamp ) ), |
| 436 | + __METHOD__, |
| 437 | + array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ) |
| 438 | + ); |
| 439 | + if ( $nextEditTS ) { // sanity check |
| 440 | + $nextTimestamp = $nextEditTS; |
| 441 | + } |
| 442 | + } |
| 443 | + # Get the new page sync status... |
| 444 | + $synced = !( |
| 445 | + $nextTimestamp !== null || // edits pending |
| 446 | + $srev->findPendingTemplateChanges() || // template changes pending |
| 447 | + $srev->findPendingFileChanges( 'noForeign' ) // file changes pending |
| 448 | + ); |
| 449 | + # Alter table metadata |
| 450 | + $dbw->replace( 'flaggedpages', |
| 451 | + array( 'fp_page_id' ), |
| 452 | + array( |
| 453 | + 'fp_page_id' => $this->getId(), |
| 454 | + 'fp_stable' => $rev->getId(), |
| 455 | + 'fp_reviewed' => $synced ? 1 : 0, |
| 456 | + 'fp_quality' => ( $maxQuality === false ) ? null : $maxQuality, |
| 457 | + 'fp_pending_since' => $dbw->timestampOrNull( $nextTimestamp ) |
| 458 | + ), |
| 459 | + __METHOD__ |
| 460 | + ); |
| 461 | + # Update pending edit tracking table |
| 462 | + self::updatePendingList( $this->getId(), $latest ); |
| 463 | + return true; |
| 464 | + } |
| 465 | + |
| 466 | + /** |
| 467 | + * Updates the flagging tracking tables for this page |
| 468 | + * @return void |
| 469 | + */ |
| 470 | + public function clearStableVersion() { |
| 471 | + if ( !$this->exists() ) { |
| 472 | + return; // nothing to do |
| 473 | + } |
| 474 | + $dbw = wfGetDB( DB_MASTER ); |
| 475 | + $dbw->delete( 'flaggedpages', |
| 476 | + array( 'fp_page_id' => $this->getId() ), __METHOD__ ); |
| 477 | + $dbw->delete( 'flaggedpage_pending', |
| 478 | + array( 'fpp_page_id' => $this->getId() ), __METHOD__ ); |
| 479 | + } |
| 480 | + |
| 481 | + /** |
| 482 | + * Updates the flaggedpage_pending table |
| 483 | + * @param int $pageId Page ID |
| 484 | + * @abstract int $latest Latest revision |
| 485 | + * @return void |
| 486 | + */ |
| 487 | + protected static function updatePendingList( $pageId, $latest ) { |
| 488 | + $data = array(); |
| 489 | + $level = FlaggedRevs::highestReviewTier(); |
| 490 | + # Update pending times for each level, going from highest to lowest |
| 491 | + $dbw = wfGetDB( DB_MASTER ); |
| 492 | + $higherLevelId = 0; |
| 493 | + $higherLevelTS = ''; |
| 494 | + while ( $level >= 0 ) { |
| 495 | + # Get the latest revision of this level... |
| 496 | + $row = $dbw->selectRow( array( 'flaggedrevs', 'revision' ), |
| 497 | + array( 'fr_rev_id', 'rev_timestamp' ), |
| 498 | + array( 'fr_page_id' => $pageId, |
| 499 | + 'fr_quality' => $level, |
| 500 | + 'rev_id = fr_rev_id', |
| 501 | + 'rev_page = fr_page_id', |
| 502 | + 'rev_deleted & ' . Revision::DELETED_TEXT => 0, |
| 503 | + 'rev_id > ' . intval( $higherLevelId ) |
| 504 | + ), |
| 505 | + __METHOD__, |
| 506 | + array( 'ORDER BY' => 'fr_rev_id DESC', 'LIMIT' => 1 ) |
| 507 | + ); |
| 508 | + # If there is a revision of this level, track it... |
| 509 | + # Revisions reviewed to one level count as reviewed |
| 510 | + # at the lower levels (i.e. quality -> checked). |
| 511 | + if ( $row ) { |
| 512 | + $id = $row->fr_rev_id; |
| 513 | + $ts = $row->rev_timestamp; |
| 514 | + } else { |
| 515 | + $id = $higherLevelId; // use previous (quality -> checked) |
| 516 | + $ts = $higherLevelTS; // use previous (quality -> checked) |
| 517 | + } |
| 518 | + # Get edits that actually are pending... |
| 519 | + if ( $id && $latest > $id ) { |
| 520 | + # Get the timestamp of the edit after this version (if any) |
| 521 | + $nextTimestamp = $dbw->selectField( 'revision', |
| 522 | + 'rev_timestamp', |
| 523 | + array( 'rev_page' => $pageId, "rev_timestamp > " . $dbw->addQuotes( $ts ) ), |
| 524 | + __METHOD__, |
| 525 | + array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1 ) |
| 526 | + ); |
| 527 | + $data[] = array( |
| 528 | + 'fpp_page_id' => $pageId, |
| 529 | + 'fpp_quality' => $level, |
| 530 | + 'fpp_rev_id' => $id, |
| 531 | + 'fpp_pending_since' => $nextTimestamp |
| 532 | + ); |
| 533 | + $higherLevelId = $id; |
| 534 | + $higherLevelTS = $ts; |
| 535 | + } |
| 536 | + $level--; |
| 537 | + } |
| 538 | + # Clear any old junk, and insert new rows |
| 539 | + $dbw->delete( 'flaggedpage_pending', array( 'fpp_page_id' => $pageId ), __METHOD__ ); |
| 540 | + $dbw->insert( 'flaggedpage_pending', $data, __METHOD__ ); |
| 541 | + } |
| 542 | +} |
Property changes on: trunk/extensions/FlaggedRevs/FlaggedPage.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 543 | + native |
Index: trunk/extensions/FlaggedRevs/FRInclusionManager.php |
— | — | @@ -60,7 +60,7 @@ |
61 | 61 | /** |
62 | 62 | * Clean up a template version array |
63 | 63 | * @param array $tmpParams (ns => dbKey => revId ) |
64 | | - * @returns Array |
| 64 | + * @return array |
65 | 65 | */ |
66 | 66 | protected function formatTemplateArray( array $params ) { |
67 | 67 | $res = array(); |
— | — | @@ -76,7 +76,7 @@ |
77 | 77 | /** |
78 | 78 | * Clean up a file version array |
79 | 79 | * @param array $imgParams (dbKey => array('time' => MW timestamp,'sha1' => sha1) ) |
80 | | - * @returns Array |
| 80 | + * @return array |
81 | 81 | */ |
82 | 82 | protected function formatFileArray( array $params ) { |
83 | 83 | $res = array(); |
— | — | @@ -124,7 +124,7 @@ |
125 | 125 | /** |
126 | 126 | * Get the "review time" template version for parser |
127 | 127 | * @param Title $title |
128 | | - * @returns mixed (int/null) |
| 128 | + * @return mixed (int/null) |
129 | 129 | */ |
130 | 130 | public function getReviewedTemplateVersion( Title $title ) { |
131 | 131 | if ( !is_array( $this->reviewedVersions ) ) { |
— | — | @@ -141,7 +141,7 @@ |
142 | 142 | /** |
143 | 143 | * Get the "review time" file version for parser |
144 | 144 | * @param Title $title |
145 | | - * @returns array (MW timestamp/'0'/null, sha1/''/null ) |
| 145 | + * @return array (MW timestamp/'0'/null, sha1/''/null ) |
146 | 146 | */ |
147 | 147 | public function getReviewedFileVersion( Title $title ) { |
148 | 148 | if ( !is_array( $this->reviewedVersions ) ) { |
— | — | @@ -160,7 +160,7 @@ |
161 | 161 | /** |
162 | 162 | * Get the stable version of a template |
163 | 163 | * @param Title $title |
164 | | - * @returns int |
| 164 | + * @return int |
165 | 165 | */ |
166 | 166 | public function getStableTemplateVersion( Title $title ) { |
167 | 167 | $dbKey = $title->getDBkey(); |
— | — | @@ -180,7 +180,7 @@ |
181 | 181 | /** |
182 | 182 | * Get the stable version of a file |
183 | 183 | * @param Title $title |
184 | | - * @returns array (MW timestamp/'0', sha1/'') |
| 184 | + * @return array (MW timestamp/'0', sha1/'') |
185 | 185 | */ |
186 | 186 | public function getStableFileVersion( Title $title ) { |
187 | 187 | $dbKey = $title->getDBkey(); |