Merge "Pass $key into CommentStore methods and use MediawikiServices"
[lhc/web/wiklou.git] / includes / Storage / RevisionStore.php
index b358631..bce3ba1 100644 (file)
@@ -42,6 +42,9 @@ use MediaWiki\User\UserIdentityValue;
 use Message;
 use MWException;
 use MWUnknownContentModelException;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
 use RecentChange;
 use stdClass;
 use Title;
@@ -61,7 +64,8 @@ use Wikimedia\Rdbms\LoadBalancer;
  * @note This was written to act as a drop-in replacement for the corresponding
  *       static methods in Revision.
  */
-class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup {
+class RevisionStore
+       implements IDBAccessObject, RevisionFactory, RevisionLookup, LoggerAwareInterface {
 
        /**
         * @var SqlBlobStore
@@ -88,6 +92,11 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup
         */
        private $cache;
 
+       /**
+        * @var LoggerInterface
+        */
+       private $logger;
+
        /**
         * @todo $blobStore should be allowed to be any BlobStore!
         *
@@ -108,6 +117,11 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup
                $this->blobStore = $blobStore;
                $this->cache = $cache;
                $this->wikiId = $wikiId;
+               $this->logger = new NullLogger();
+       }
+
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
        }
 
        /**
@@ -173,23 +187,34 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup
         * @return Title
         * @throws RevisionAccessException
         */
-       public function getTitle( $pageId, $revId, $queryFlags = 0 ) {
+       public function getTitle( $pageId, $revId, $queryFlags = self::READ_NORMAL ) {
                if ( !$pageId && !$revId ) {
                        throw new InvalidArgumentException( '$pageId and $revId cannot both be 0 or null' );
                }
 
-               list( $dbMode, $dbOptions, , ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
-               $titleFlags = $dbMode == DB_MASTER ? Title::GAID_FOR_UPDATE : 0;
-               $title = null;
+               // This method recalls itself with READ_LATEST if READ_NORMAL doesn't get us a Title
+               // So ignore READ_LATEST_IMMUTABLE flags and handle the fallback logic in this method
+               if ( DBAccessObjectUtils::hasFlags( $queryFlags, self::READ_LATEST_IMMUTABLE ) ) {
+                       $queryFlags = self::READ_NORMAL;
+               }
+
+               $canUseTitleNewFromId = ( $pageId !== null && $pageId > 0 && $this->wikiId === false );
+               list( $dbMode, $dbOptions ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
+               $titleFlags = ( $dbMode == DB_MASTER ? Title::GAID_FOR_UPDATE : 0 );
 
                // Loading by ID is best, but Title::newFromID does not support that for foreign IDs.
-               if ( $pageId !== null && $pageId > 0 && $this->wikiId === false ) {
+               if ( $canUseTitleNewFromId ) {
                        // TODO: better foreign title handling (introduce TitleFactory)
                        $title = Title::newFromID( $pageId, $titleFlags );
+                       if ( $title ) {
+                               return $title;
+                       }
                }
 
                // rev_id is defined as NOT NULL, but this revision may not yet have been inserted.
-               if ( !$title && $revId !== null && $revId > 0 ) {
+               $canUseRevId = ( $revId !== null && $revId > 0 );
+
+               if ( $canUseRevId ) {
                        $dbr = $this->getDBConnectionRef( $dbMode );
                        // @todo: Title::getSelectFields(), or Title::getQueryInfo(), or something like that
                        $row = $dbr->selectRow(
@@ -209,17 +234,25 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup
                        );
                        if ( $row ) {
                                // TODO: better foreign title handling (introduce TitleFactory)
-                               $title = Title::newFromRow( $row );
+                               return Title::newFromRow( $row );
                        }
                }
 
-               if ( !$title ) {
-                       throw new RevisionAccessException(
-                               "Could not determine title for page ID $pageId and revision ID $revId"
-                       );
+               // If we still don't have a title, fallback to master if that wasn't already happening.
+               if ( $dbMode !== DB_MASTER ) {
+                       $title = $this->getTitle( $pageId, $revId, self::READ_LATEST );
+                       if ( $title ) {
+                               $this->logger->info(
+                                       __METHOD__ . ' fell back to READ_LATEST and got a Title.',
+                                       [ 'trace' => wfDebugBacktrace() ]
+                               );
+                               return $title;
+                       }
                }
 
-               return $title;
+               throw new RevisionAccessException(
+                       "Could not determine title for page ID $pageId and revision ID $revId"
+               );
        }
 
        /**