Merge "Revision: Handle all return values of Title::newFromId"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 1 Jan 2018 00:05:25 +0000 (00:05 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 1 Jan 2018 00:05:25 +0000 (00:05 +0000)
1  2 
includes/Revision.php
tests/phpunit/includes/RevisionDbTestBase.php

diff --combined includes/Revision.php
@@@ -94,11 -94,54 +94,11 @@@ class Revision implements IDBAccessObje
         *
         * @param int $id
         * @param int $flags (optional)
 -       * @param Title $title (optional) If known you can pass the Title in here.
 -       *  Passing no Title may result in another DB query if there are recent writes.
         * @return Revision|null
         */
 -      public static function newFromId( $id, $flags = 0, Title $title = null ) {
 -              /**
 -               * MCR RevisionStore Compat
 -               *
 -               * If the title is not passed in as a param (already known) then select it here.
 -               *
 -               * Do the selection with MASTER if $flags includes READ_LATEST or recent changes
 -               * have happened on our load balancer.
 -               *
 -               * If we select the title here and pass it down it will results in fewer queries
 -               * further down the stack.
 -               */
 -              if ( !$title ) {
 -                      if (
 -                              $flags & self::READ_LATEST ||
 -                              wfGetLB()->hasOrMadeRecentMasterChanges()
 -                      ) {
 -                              $dbr = wfGetDB( DB_MASTER );
 -                      } else {
 -                              $dbr = wfGetDB( DB_REPLICA );
 -                      }
 -                      $row = $dbr->selectRow(
 -                              [ 'revision', 'page' ],
 -                              [
 -                                      'page_namespace',
 -                                      'page_title',
 -                                      'page_id',
 -                                      'page_latest',
 -                                      'page_is_redirect',
 -                                      'page_len',
 -                              ],
 -                              [ 'rev_id' => $id ],
 -                              __METHOD__,
 -                              [],
 -                              [ 'page' => [ 'JOIN', 'page_id=rev_page' ] ]
 -                      );
 -                      if ( $row ) {
 -                              $title = Title::newFromRow( $row );
 -                      }
 -                      wfGetLB()->reuseConnection( $dbr );
 -              }
 -
 -              $rec = self::getRevisionStore()->getRevisionById( $id, $flags, $title );
 -              return $rec === null ? null : new Revision( $rec, $flags, $title );
 +      public static function newFromId( $id, $flags = 0 ) {
 +              $rec = self::getRevisionStore()->getRevisionById( $id, $flags );
 +              return $rec === null ? null : new Revision( $rec, $flags );
        }
  
        /**
         *
         * @param object $row
         * @param array $overrides
 -       * @param Title $title (optional)
         *
         * @throws MWException
         * @return Revision
         */
 -      public static function newFromArchiveRow( $row, $overrides = [], Title $title = null ) {
 +      public static function newFromArchiveRow( $row, $overrides = [] ) {
                /**
                 * MCR Migration: https://phabricator.wikimedia.org/T183564
                 * This method used to overwrite attributes, then passed to Revision::__construct
                        unset( $overrides['page'] );
                }
  
 -              $rec = self::getRevisionStore()->newRevisionFromArchiveRow( $row, 0, $title, $overrides );
 +              /**
 +               * We require a Title for both the Revision object and the RevisionRecord.
 +               * Below is duplicated logic from RevisionStore::newRevisionFromArchiveRow
 +               * to fetch a title in order pass it into the Revision object.
 +               */
 +              $title = null;
 +              if ( isset( $overrides['title'] ) ) {
 +                      if ( !( $overrides['title'] instanceof Title ) ) {
 +                              throw new MWException( 'title field override must contain a Title object.' );
 +                      }
 +
 +                      $title = $overrides['title'];
 +              }
 +              if ( $title !== null ) {
 +                      if ( isset( $row->ar_namespace ) && isset( $row->ar_title ) ) {
 +                              $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
 +                      } else {
 +                              throw new InvalidArgumentException(
 +                                      'A Title or ar_namespace and ar_title must be given'
 +                              );
 +                      }
 +              }
 +
 +              $rec = self::getRevisionStore()->newRevisionFromArchiveRow( $row, 0, null, $overrides );
                return new Revision( $rec, self::READ_NORMAL, $title );
        }
  
         * @return Revision|null
         */
        public function getPrevious() {
 -              $rec = self::getRevisionStore()->getPreviousRevision( $this->mRecord, $this->getTitle() );
 -              return $rec === null
 -                      ? null
 -                      : new Revision( $rec, self::READ_NORMAL, $this->getTitle() );
 +              $rec = self::getRevisionStore()->getPreviousRevision( $this->mRecord );
 +              return $rec === null ? null : new Revision( $rec );
        }
  
        /**
         * @return Revision|null
         */
        public function getNext() {
 -              $rec = self::getRevisionStore()->getNextRevision( $this->mRecord, $this->getTitle() );
 -              return $rec === null
 -                      ? null
 -                      : new Revision( $rec, self::READ_NORMAL, $this->getTitle() );
 +              $rec = self::getRevisionStore()->getNextRevision( $this->mRecord );
 +              return $rec === null ? null : new Revision( $rec );
        }
  
        /**
                        ? $pageIdOrTitle
                        : Title::newFromID( $pageIdOrTitle );
  
+               if ( !$title ) {
+                       return false;
+               }
                $record = self::getRevisionStore()->getKnownCurrentRevision( $title, $revId );
                return $record ? new Revision( $record ) : false;
        }
@@@ -649,7 -649,6 +649,7 @@@ abstract class RevisionDbTestBase exten
        }
  
        /**
 +       * @covers Revision::userWasLastToEdit
         * @dataProvider provideUserWasLastToEdit
         */
        public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) {
                $this->assertEquals( $rev->getId(), $cachedRow->rev_id );
        }
  
+       public function testNewKnownCurrent_withPageId() {
+               $db = wfGetDB( DB_MASTER );
+               $this->testPage->doEditContent( new WikitextContent( __METHOD__ ), __METHOD__ );
+               $rev = $this->testPage->getRevision();
+               $pageId = $this->testPage->getId();
+               $newRev = Revision::newKnownCurrent( $db, $pageId, $rev->getId() );
+               $this->assertRevEquals( $rev, $newRev );
+       }
+       public function testNewKnownCurrent_returnsFalseWhenTitleDoesntExist() {
+               $db = wfGetDB( DB_MASTER );
+               $this->assertFalse( Revision::newKnownCurrent( $db, 0 ) );
+       }
        public function provideUserCanBitfield() {
                yield [ 0, 0, [], null, true ];
                // Bitfields match, user has no permissions