Index: trunk/extensions/FlaggedRevs/FlaggedRevision.php |
— | — | @@ -74,7 +74,7 @@ |
75 | 75 | throw new MWException( 'FlaggedRevision constructor passed invalid row format.' ); |
76 | 76 | } |
77 | 77 | } |
78 | | - |
| 78 | + |
79 | 79 | /** |
80 | 80 | * Get a FlaggedRevision for a title and rev ID. |
81 | 81 | * Note: will return NULL if the revision is deleted. |
— | — | @@ -326,7 +326,7 @@ |
327 | 327 | } |
328 | 328 | return true; |
329 | 329 | } |
330 | | - |
| 330 | + |
331 | 331 | /** |
332 | 332 | * @return Array basic select fields (not including text/text flags) |
333 | 333 | */ |
— | — | @@ -344,7 +344,7 @@ |
345 | 345 | public function getRevId() { |
346 | 346 | return $this->mRevId; |
347 | 347 | } |
348 | | - |
| 348 | + |
349 | 349 | /** |
350 | 350 | * @return Title title |
351 | 351 | */ |
— | — | @@ -369,7 +369,7 @@ |
370 | 370 | public function getTimestamp() { |
371 | 371 | return wfTimestamp( TS_MW, $this->mTimestamp ); |
372 | 372 | } |
373 | | - |
| 373 | + |
374 | 374 | /** |
375 | 375 | * Get the corresponding revision |
376 | 376 | * @return Revision |
— | — | @@ -383,7 +383,7 @@ |
384 | 384 | } |
385 | 385 | return $this->mRevision; |
386 | 386 | } |
387 | | - |
| 387 | + |
388 | 388 | /** |
389 | 389 | * Get timestamp of the corresponding revision |
390 | 390 | * @return string revision timestamp in MW format |
— | — | @@ -401,7 +401,7 @@ |
402 | 402 | public function getComment() { |
403 | 403 | return $this->mComment; |
404 | 404 | } |
405 | | - |
| 405 | + |
406 | 406 | /** |
407 | 407 | * @return integer the user ID of the reviewer |
408 | 408 | */ |
— | — | @@ -422,7 +422,7 @@ |
423 | 423 | public function getTags() { |
424 | 424 | return $this->mTags; |
425 | 425 | } |
426 | | - |
| 426 | + |
427 | 427 | /** |
428 | 428 | * @return string, filename accosciated with this revision. |
429 | 429 | * This returns NULL for non-image page revisions. |
— | — | @@ -430,7 +430,7 @@ |
431 | 431 | public function getFileName() { |
432 | 432 | return $this->mFileName; |
433 | 433 | } |
434 | | - |
| 434 | + |
435 | 435 | /** |
436 | 436 | * @return string, sha1 key accosciated with this revision. |
437 | 437 | * This returns NULL for non-image page revisions. |
— | — | @@ -438,7 +438,7 @@ |
439 | 439 | public function getFileSha1() { |
440 | 440 | return $this->mFileSha1; |
441 | 441 | } |
442 | | - |
| 442 | + |
443 | 443 | /** |
444 | 444 | * @return string, timestamp accosciated with this revision. |
445 | 445 | * This returns NULL for non-image page revisions. |
— | — | @@ -446,7 +446,7 @@ |
447 | 447 | public function getFileTimestamp() { |
448 | 448 | return wfTimestampOrNull( TS_MW, $this->mFileTimestamp ); |
449 | 449 | } |
450 | | - |
| 450 | + |
451 | 451 | /** |
452 | 452 | * @param User $user |
453 | 453 | * @return bool |
— | — | @@ -480,7 +480,7 @@ |
481 | 481 | } |
482 | 482 | return $this->mTemplates; |
483 | 483 | } |
484 | | - |
| 484 | + |
485 | 485 | /** |
486 | 486 | * Get original template versions at time of review |
487 | 487 | * @param int $flags FR_MASTER |
— | — | @@ -507,7 +507,7 @@ |
508 | 508 | } |
509 | 509 | return $this->mFiles; |
510 | 510 | } |
511 | | - |
| 511 | + |
512 | 512 | /** |
513 | 513 | * Get the current stable version of the templates used at time of review |
514 | 514 | * @param int $flags FR_MASTER |
— | — | @@ -541,7 +541,7 @@ |
542 | 542 | } |
543 | 543 | return $this->mStableTemplates; |
544 | 544 | } |
545 | | - |
| 545 | + |
546 | 546 | /** |
547 | 547 | * Get the current stable version of the files used at time of review |
548 | 548 | * @param int $flags FR_MASTER |
— | — | @@ -581,10 +581,10 @@ |
582 | 582 | } |
583 | 583 | return $this->mStableFiles; |
584 | 584 | } |
585 | | - |
| 585 | + |
586 | 586 | /* |
587 | 587 | * Fetch pending template changes for this reviewed page version. |
588 | | - * For each template, the "version used" is: |
| 588 | + * For each template, the "version used" (for stable parsing) is: |
589 | 589 | * (a) (the latest rev) if FR_INCLUDES_CURRENT. Might be non-existing. |
590 | 590 | * (b) newest( stable rev, rev at time of review ) if FR_INCLUDES_STABLE |
591 | 591 | * (c) ( rev at time of review ) if FR_INCLUDES_FREEZE |
— | — | @@ -601,44 +601,51 @@ |
602 | 602 | return array(); // short-circuit |
603 | 603 | } |
604 | 604 | $dbr = wfGetDB( DB_SLAVE ); |
| 605 | + # Only get templates with stable or "review time" versions. |
| 606 | + # Note: ft_tmp_rev_id is nullable (for deadlinks), so use ft_title |
| 607 | + if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
| 608 | + $reviewed = "ft_title IS NOT NULL OR fp_stable IS NOT NULL"; |
| 609 | + } else { |
| 610 | + $reviewed = "ft_title IS NOT NULL"; |
| 611 | + } |
605 | 612 | $ret = $dbr->select( |
606 | | - array( 'flaggedtemplates', 'templatelinks', 'page', 'flaggedpages' ), |
607 | | - array( 'ft_namespace', 'ft_title', 'fp_stable', 'ft_tmp_rev_id', 'page_latest' ), |
608 | | - array( 'ft_rev_id' => $this->getRevId() ), // template was in reviewed rev |
| 613 | + array( 'templatelinks', 'flaggedtemplates', 'page', 'flaggedpages' ), |
| 614 | + array( 'tl_namespace', 'tl_title', 'fp_stable', 'ft_tmp_rev_id', 'page_latest' ), |
| 615 | + array( 'tl_from' => $this->getPage(), $reviewed ), // current version templates |
609 | 616 | __METHOD__, |
610 | 617 | array(), /* OPTIONS */ |
611 | 618 | array( |
612 | | - 'templatelinks' => array( 'INNER JOIN', // used in current rev |
613 | | - array( 'tl_from' => $this->getPage(), |
614 | | - 'tl_namespace = ft_namespace AND tl_title = ft_title' ) ), |
615 | | - 'page' => array( 'LEFT JOIN', |
616 | | - 'page_namespace = ft_namespace AND page_title = ft_title' ), |
617 | | - 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ) |
| 619 | + 'flaggedtemplates' => array( 'LEFT JOIN', |
| 620 | + array( 'ft_rev_id' => $this->getRevId(), |
| 621 | + 'ft_namespace = tl_namespace AND ft_title = tl_title' ) ), |
| 622 | + 'page' => array( 'LEFT JOIN', |
| 623 | + 'page_namespace = tl_namespace AND page_title = tl_title' ), |
| 624 | + 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ) |
618 | 625 | ) |
619 | 626 | ); |
620 | 627 | $tmpChanges = array(); |
621 | 628 | while ( $row = $dbr->fetchObject( $ret ) ) { |
622 | | - $title = Title::makeTitleSafe( $row->ft_namespace, $row->ft_title ); |
| 629 | + $title = Title::makeTitleSafe( $row->tl_namespace, $row->tl_title ); |
623 | 630 | $revIdDraft = (int)$row->page_latest; // may be NULL |
624 | 631 | if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
625 | | - # Select newest of (stable rev, rev when reviewed) when parsing |
| 632 | + # Select newest of (stable rev, rev when reviewed) as "version used" |
626 | 633 | $revIdStable = max( $row->fp_stable, $row->ft_tmp_rev_id ); |
627 | 634 | } else { |
628 | | - $revIdStable = (int)$row->ft_tmp_rev_id; |
| 635 | + $revIdStable = (int)$row->ft_tmp_rev_id; // may be NULL |
629 | 636 | } |
630 | 637 | # Compare to current... |
631 | 638 | $deleted = ( !$revIdDraft && $revIdStable ); // later deleted |
632 | | - $updated = ( $revIdDraft && $revIdDraft > $revIdStable ); // updated/created |
| 639 | + $updated = ( $revIdDraft && $revIdDraft > $revIdStable ); // edited/created |
633 | 640 | if ( $deleted || $updated ) { |
634 | 641 | $tmpChanges[] = array( $title, $revIdStable ); |
635 | 642 | } |
636 | 643 | } |
637 | 644 | return $tmpChanges; |
638 | 645 | } |
639 | | - |
| 646 | + |
640 | 647 | /* |
641 | 648 | * Fetch pending file changes for this reviewed page version. |
642 | | - * For each file, the version used is: |
| 649 | + * For each file, the "version used" (for stable parsing) is: |
643 | 650 | * (a) (the latest rev) if FR_INCLUDES_CURRENT. Might be non-existing. |
644 | 651 | * (b) newest( stable rev, rev at time of review ) if FR_INCLUDES_STABLE |
645 | 652 | * (c) ( rev at time of review ) if FR_INCLUDES_FREEZE |
— | — | @@ -648,7 +655,7 @@ |
649 | 656 | * (b) Current file exists and the "version used" was non-existing (created) |
650 | 657 | * (c) Current file doesn't exist and the "version used" existed (deleted) |
651 | 658 | * |
652 | | - * @param string $noForeign Use 'noForeign' to skip Commons images (bug 15748) |
| 659 | + * @param string $noForeign Using 'noForeign' skips new non-local file versions (bug 15748) |
653 | 660 | * @return Array of (file title, MW file timestamp in reviewed version) tuples |
654 | 661 | */ |
655 | 662 | public function findPendingFileChanges( $noForeign = false ) { |
— | — | @@ -656,40 +663,55 @@ |
657 | 664 | return array(); // short-circuit |
658 | 665 | } |
659 | 666 | $dbr = wfGetDB( DB_SLAVE ); |
| 667 | + # Only get templates with stable or "review time" versions. |
| 668 | + # Note: fi_img_timestamp is nullable (for deadlinks), so use fi_name |
| 669 | + if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
| 670 | + $reviewed = "fi_name IS NOT NULL OR fr_img_timestamp IS NOT NULL"; |
| 671 | + } else { |
| 672 | + $reviewed = "fi_name IS NOT NULL"; |
| 673 | + } |
660 | 674 | $ret = $dbr->select( |
661 | | - array( 'flaggedimages', 'imagelinks', 'page', 'flaggedpages', 'flaggedrevs' ), |
662 | | - array( 'fi_name', 'fi_img_timestamp', 'fr_img_timestamp' ), |
663 | | - array( 'fi_rev_id' => $this->getRevId() ), // template was in reviewed rev |
| 675 | + array( 'imagelinks', 'flaggedimages', 'page', 'flaggedpages', 'flaggedrevs' ), |
| 676 | + array( 'il_to', 'fi_img_timestamp', 'fr_img_timestamp' ), |
| 677 | + array( 'il_from' => $this->getPage(), $reviewed ), // current version files |
664 | 678 | __METHOD__, |
665 | 679 | array(), /* OPTIONS */ |
666 | 680 | array( |
667 | | - 'imagelinks' => array( 'INNER JOIN', // used in current rev |
668 | | - array( 'il_from' => $this->getPage(), 'il_to = fi_name' ) ), |
| 681 | + 'flaggedimages' => array( 'LEFT JOIN', |
| 682 | + array( 'fi_rev_id' => $this->getRevId(), 'fi_name = il_to' ) ), |
669 | 683 | 'page' => array( 'LEFT JOIN', |
670 | | - 'page_namespace = ' . NS_FILE . ' AND page_title = fi_name' ), |
| 684 | + 'page_namespace = ' . NS_FILE . ' AND page_title = il_to' ), |
671 | 685 | 'flaggedpages' => array( 'LEFT JOIN', 'fp_page_id = page_id' ), |
672 | 686 | 'flaggedrevs' => array( 'LEFT JOIN', |
673 | | - 'fr_page_id = fp_page_id AND fr_rev_id = fp_stable' ) ) |
| 687 | + 'fr_page_id = fp_page_id AND fr_rev_id = fp_stable' ) |
| 688 | + ) |
674 | 689 | ); |
675 | 690 | $fileChanges = array(); |
676 | 691 | while ( $row = $dbr->fetchObject( $ret ) ) { |
677 | | - $title = Title::makeTitleSafe( NS_FILE, $row->fi_name ); |
| 692 | + $title = Title::makeTitleSafe( NS_FILE, $row->il_to ); |
678 | 693 | $reviewedTS = trim( $row->fi_img_timestamp ); // may be ''/NULL |
| 694 | + $reviewedTS = $reviewedTS ? wfTimestamp( TS_MW, $reviewedTS ) : null; |
679 | 695 | if ( FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE ) { |
680 | | - # Select newest of (stable rev, rev when reviewed) when parsing |
681 | | - $tsStable = $row->fr_img_timestamp >= $reviewedTS |
682 | | - ? $row->fr_img_timestamp |
683 | | - : $reviewedTS; |
| 696 | + $stableTS = wfTimestampOrNull( TS_MW, $row->fr_img_timestamp ); |
| 697 | + # Select newest of (stable rev, rev when reviewed) as "version used" |
| 698 | + $tsStable = ( $stableTS >= $reviewedTS ) |
| 699 | + ? $stableTS |
| 700 | + : $reviewedTS; |
684 | 701 | } else { |
685 | 702 | $tsStable = $reviewedTS; |
686 | 703 | } |
687 | 704 | # Compare to current... |
688 | 705 | $file = wfFindFile( $title ); // current file version |
689 | | - $deleted = ( !$file && $tsStable ); // later deleted |
690 | | - if ( $file && ( $noForeign !== 'noForeign' || $file->isLocal() ) ) { |
691 | | - $updated = ( $file->getTimestamp() > $tsStable ); // updated/created |
692 | | - } else { |
| 706 | + if ( $file ) { // file exists |
| 707 | + if ( $noForeign === 'noForeign' && !$file->isLocal() ) { |
| 708 | + $updated = !$tsStable; // created (ignore new versions) |
| 709 | + } else { |
| 710 | + $updated = ( $file->getTimestamp() > $tsStable ); // edited/created |
| 711 | + } |
| 712 | + $deleted = false; |
| 713 | + } else { // file doesn't exists |
693 | 714 | $updated = false; |
| 715 | + $deleted = (bool)$tsStable; // later deleted |
694 | 716 | } |
695 | 717 | if ( $deleted || $updated ) { |
696 | 718 | $fileChanges[] = array( $title, $tsStable ); |
— | — | @@ -697,7 +719,7 @@ |
698 | 720 | } |
699 | 721 | return $fileChanges; |
700 | 722 | } |
701 | | - |
| 723 | + |
702 | 724 | /** |
703 | 725 | * Get text of the corresponding revision |
704 | 726 | * @return mixed (string/false) revision timestamp in MW format |
— | — | @@ -708,7 +730,7 @@ |
709 | 731 | $text = $rev ? $rev->getText() : false; |
710 | 732 | return $text; |
711 | 733 | } |
712 | | - |
| 734 | + |
713 | 735 | /** |
714 | 736 | * Get flags for a revision |
715 | 737 | * @param string $tags |