Addshore has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/403693 )

Change subject: Make Revision::__construct work with bad page ID
......................................................................

Make Revision::__construct work with bad page ID

For backwards-copatibility, we need to be able to construct a Revision
object even for bad page IDs.

Bug: T184689
Change-Id: I18c823d7b72504447982364d581b34e98924b67f
---
M includes/Revision.php
M includes/Storage/RevisionStore.php
M tests/phpunit/includes/RevisionTest.php
3 files changed, 72 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/93/403693/1

diff --git a/includes/Revision.php b/includes/Revision.php
index 0844e89..8849697 100644
--- a/includes/Revision.php
+++ b/includes/Revision.php
@@ -495,13 +495,13 @@
                        $this->mRecord = 
self::getRevisionStore()->newMutableRevisionFromArray(
                                $row,
                                $queryFlags,
-                               $title
+                               $this->ensureTitle( $row, $queryFlags, $title )
                        );
                } elseif ( is_object( $row ) ) {
                        $this->mRecord = 
self::getRevisionStore()->newRevisionFromRow(
                                $row,
                                $queryFlags,
-                               $title
+                               $this->ensureTitle( $row, $queryFlags, $title )
                        );
                } else {
                        throw new InvalidArgumentException(
@@ -511,6 +511,51 @@
        }
 
        /**
+        * Make sure we have *some* Title object for use by the constructor.
+        * For B/C, the constructor shouldn't fail even for a bad page ID or 
bad revision ID.
+        *
+        * @param array|object $row
+        * @param int $queryFlags
+        * @param Title|null $title
+        *
+        * @return Title $title if not null, or a Title constructed from 
information in $row.
+        */
+       private function ensureTitle( $row, $queryFlags, $title = null ) {
+               if ( $title ) {
+                       return $title;
+               }
+
+               if ( is_array( $row ) ) {
+                       if ( isset( $row['title'] ) ) {
+                               if ( !( $row['title'] instanceof Title ) ) {
+                                       throw new MWException( 'title field 
must contain a Title object.' );
+                               }
+
+                               return $row['title'];
+                       }
+
+                       $pageId = isset( $row['page'] ) ? $row['page'] : 0;
+                       $revId = isset( $row['id'] ) ? $row['id'] : 0;
+               } else {
+                       $pageId = isset( $row->rev_page ) ? $row->rev_page : 0;
+                       $revId = isset( $row->rev_id ) ? $row->rev_id : 0;
+               }
+
+               try {
+                       $title = self::getRevisionStore()->getTitle( $pageId, 
$revId, $queryFlags );
+               } catch ( RevisionAccessException $ex ) {
+                       // construct a dummy title!
+                       wfLogWarning( __METHOD__ . ': ' . $ex->getMessage() );
+
+                       // NOTE: this Title will only be used inside 
RevisionRecord
+                       $title = Title::makeTitleSafe( NS_SPECIAL, 
"Badtitle/ID=$pageId" );
+                       $title->resetArticleID( $pageId );
+               }
+
+               return $title;
+       }
+
+       /**
         * @return RevisionRecord
         */
        public function getRevisionRecord() {
diff --git a/includes/Storage/RevisionStore.php 
b/includes/Storage/RevisionStore.php
index 2429e1c..2efaa9d 100644
--- a/includes/Storage/RevisionStore.php
+++ b/includes/Storage/RevisionStore.php
@@ -178,6 +178,8 @@
         *
         * MCR migration note: this corresponds to Revision::getTitle
         *
+        * @note this method should be private, external use should be avoided!
+        *
         * @param int|null $pageId
         * @param int|null $revId
         * @param int $queryFlags
@@ -185,7 +187,7 @@
         * @return Title
         * @throws RevisionAccessException
         */
-       private function getTitle( $pageId, $revId, $queryFlags = 0 ) {
+       public function getTitle( $pageId, $revId, $queryFlags = 0 ) {
                if ( !$pageId && !$revId ) {
                        throw new InvalidArgumentException( '$pageId and $revId 
cannot both be 0 or null' );
                }
diff --git a/tests/phpunit/includes/RevisionTest.php 
b/tests/phpunit/includes/RevisionTest.php
index 0db76ff..7ce43ed 100644
--- a/tests/phpunit/includes/RevisionTest.php
+++ b/tests/phpunit/includes/RevisionTest.php
@@ -76,6 +76,17 @@
                $this->assertNull( $rev->getContent(), 'no content object 
should be available' );
        }
 
+       /**
+        * @covers Revision::__construct
+        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
+        */
+       public function testConstructFromArrayWithBadPageId() {
+               MediaWiki\suppressWarnings();
+               $rev = new Revision( [ 'page' => 77777777 ] );
+               $this->assertSame( 77777777, $rev->getPage() );
+               MediaWiki\restoreWarnings();
+       }
+
        public function provideConstructFromArray_userSetAsExpected() {
                yield 'no user defaults to wgUser' => [
                        [
@@ -297,6 +308,17 @@
                $assertions( $this, $rev );
        }
 
+       /**
+        * @covers Revision::__construct
+        * @covers \MediaWiki\Storage\RevisionStore::newMutableRevisionFromArray
+        */
+       public function testConstructFromRowWithBadPageId() {
+               MediaWiki\suppressWarnings();
+               $rev = new Revision( (object)[ 'rev_page' => 77777777 ] );
+               $this->assertSame( 77777777, $rev->getPage() );
+               MediaWiki\restoreWarnings();
+       }
+
        public function provideGetRevisionText() {
                yield 'Generic test' => [
                        'This is a goat of revision text.',

-- 
To view, visit https://gerrit.wikimedia.org/r/403693
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I18c823d7b72504447982364d581b34e98924b67f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: wmf/1.31.0-wmf.16
Gerrit-Owner: Addshore <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to