Move IDatabase/IMaintainableDatabase to Rdbms namespace
[lhc/web/wiklou.git] / includes / Title.php
index 3ce775b..1046a5c 100644 (file)
@@ -21,6 +21,8 @@
  *
  * @file
  */
+
+use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\MediaWikiServices;
@@ -134,7 +136,7 @@ class Title implements LinkTarget {
 
        /**
         * @var int Namespace index when there is no namespace. Don't change the
-        *   following default, NS_MAIN is hardcoded in several places. See bug 696.
+        *   following default, NS_MAIN is hardcoded in several places. See T2696.
         *   Zero except in {{transclusion}} tags.
         */
        public $mDefaultNamespace = NS_MAIN;
@@ -307,7 +309,7 @@ class Title implements LinkTarget {
                        }
                }
 
-               // Convert things like é ā or 〗 into normalized (bug 14952) text
+               // Convert things like é ā or 〗 into normalized (T16952) text
                $filteredText = Sanitizer::decodeCharReferencesAndNormalize( $text );
 
                $t = new Title();
@@ -2549,6 +2551,29 @@ class Title implements LinkTarget {
         *   protection, or false if there's none.
         */
        public function getTitleProtection() {
+               $protection = $this->getTitleProtectionInternal();
+               if ( $protection ) {
+                       if ( $protection['permission'] == 'sysop' ) {
+                               $protection['permission'] = 'editprotected'; // B/C
+                       }
+                       if ( $protection['permission'] == 'autoconfirmed' ) {
+                               $protection['permission'] = 'editsemiprotected'; // B/C
+                       }
+               }
+               return $protection;
+       }
+
+       /**
+        * Fetch title protection settings
+        *
+        * To work correctly, $this->loadRestrictions() needs to have access to the
+        * actual protections in the database without munging 'sysop' =>
+        * 'editprotected' and 'autoconfirmed' => 'editsemiprotected'. Other
+        * callers probably want $this->getTitleProtection() instead.
+        *
+        * @return array|bool
+        */
+       protected function getTitleProtectionInternal() {
                // Can't protect pages in special namespaces
                if ( $this->getNamespace() < 0 ) {
                        return false;
@@ -2576,12 +2601,6 @@ class Title implements LinkTarget {
                        // fetchRow returns false if there are no rows.
                        $row = $dbr->fetchRow( $res );
                        if ( $row ) {
-                               if ( $row['permission'] == 'sysop' ) {
-                                       $row['permission'] = 'editprotected'; // B/C
-                               }
-                               if ( $row['permission'] == 'autoconfirmed' ) {
-                                       $row['permission'] = 'editsemiprotected'; // B/C
-                               }
                                $row['expiry'] = $dbr->decodeExpiry( $row['expiry'] );
                        }
                        $this->mTitleProtection = $row;
@@ -2926,8 +2945,6 @@ class Title implements LinkTarget {
                                        continue;
                                }
 
-                               // This code should be refactored, now that it's being used more generally,
-                               // But I don't really see any harm in leaving it in Block for now -werdna
                                $expiry = $dbr->decodeExpiry( $row->pr_expiry );
 
                                // Only apply the restrictions if they haven't expired!
@@ -2979,7 +2996,7 @@ class Title implements LinkTarget {
 
                        $this->loadRestrictionsFromRows( $rows, $oldFashionedRestrictions );
                } else {
-                       $title_protection = $this->getTitleProtection();
+                       $title_protection = $this->getTitleProtectionInternal();
 
                        if ( $title_protection ) {
                                $now = wfTimestampNow();
@@ -3741,14 +3758,14 @@ class Title implements LinkTarget {
                        }
                        $newPageName = preg_replace(
                                        '#^' . preg_quote( $this->getDBkey(), '#' ) . '#',
-                                       StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # bug 21234
+                                       StringUtils::escapeRegexReplacement( $nt->getDBkey() ), # T23234
                                        $oldSubpage->getDBkey() );
                        if ( $oldSubpage->isTalkPage() ) {
                                $newNs = $nt->getTalkPage()->getNamespace();
                        } else {
                                $newNs = $nt->getSubjectPage()->getNamespace();
                        }
-                       # Bug 14385: we need makeTitleSafe because the new page names may
+                       # T16385: we need makeTitleSafe because the new page names may
                        # be longer than 255 characters.
                        $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
 
@@ -3865,7 +3882,7 @@ class Title implements LinkTarget {
         * categories' names.
         *
         * @return array Array of parents in the form:
-        *        $parent => $currentarticle
+        *     $parent => $currentarticle
         */
        public function getParentCategories() {
                global $wgContLang;
@@ -3946,14 +3963,22 @@ class Title implements LinkTarget {
         * @return int|bool Old revision ID, or false if none exists
         */
        public function getPreviousRevisionID( $revId, $flags = 0 ) {
-               $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
+               /* This function and getNextRevisionID have bad performance when
+                  used on a page with many revisions on mysql. An explicit extended
+                  primary key may help in some cases, if the PRIMARY KEY is banned:
+                  T159319 */
+               if ( $flags & self::GAID_FOR_UPDATE ) {
+                       $db = wfGetDB( DB_MASTER );
+               } else {
+                       $db = wfGetDB( DB_REPLICA, 'contributions' );
+               }
                $revId = $db->selectField( 'revision', 'rev_id',
                        [
                                'rev_page' => $this->getArticleID( $flags ),
                                'rev_id < ' . intval( $revId )
                        ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'rev_id DESC' ]
+                       [ 'ORDER BY' => 'rev_id DESC', 'IGNORE INDEX' => 'PRIMARY' ]
                );
 
                if ( $revId === false ) {
@@ -3971,14 +3996,18 @@ class Title implements LinkTarget {
         * @return int|bool Next revision ID, or false if none exists
         */
        public function getNextRevisionID( $revId, $flags = 0 ) {
-               $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA );
+               if ( $flags & self::GAID_FOR_UPDATE ) {
+                       $db = wfGetDB( DB_MASTER );
+               } else {
+                       $db = wfGetDB( DB_REPLICA, 'contributions' );
+               }
                $revId = $db->selectField( 'revision', 'rev_id',
                        [
                                'rev_page' => $this->getArticleID( $flags ),
                                'rev_id > ' . intval( $revId )
                        ],
                        __METHOD__,
-                       [ 'ORDER BY' => 'rev_id' ]
+                       [ 'ORDER BY' => 'rev_id', 'IGNORE INDEX' => 'PRIMARY' ]
                );
 
                if ( $revId === false ) {