Fix not-loaded DbPageLanguage when Title::getPageLanguage() get's called
authorFlorian <florian.schmidt.stargatewissen@gmail.com>
Sat, 19 Dec 2015 15:25:45 +0000 (16:25 +0100)
committerUmherirrender <umherirrender_de.wp@web.de>
Tue, 16 Feb 2016 20:37:40 +0000 (20:37 +0000)
If the Title object isn't the title of the current viewed WikiPage, the page_lang
field of the database isn't requested. This results in the problem, that
Title::getPageLanguage() always returns the default content language, even if
the page language is different (changed with Special:PageLanguage, if
wgPageLanguageUseDB is true). That is problematic for the Translate extension,
which relies on the correct page language.

This change makes sure, that getPageLanguage() always return the correct page
language. If the page language isn't loaded already, Title::getPageLanguage()
now does a database lookup (if $wgPageLanguageUseDB is true) to get the correct
page language. It will use LinkCache for the page_lang field.

Bug: T121666
Change-Id: I0ae5ea39f7a124ed427ca5dfb26c1a116b27a94e

includes/OutputPage.php
includes/Title.php
includes/api/ApiPageSet.php
includes/cache/LinkBatch.php
includes/cache/LinkCache.php
includes/parser/LinkHolderArray.php
includes/specials/SpecialPageLanguage.php

index e527001..459fb4d 100644 (file)
@@ -1310,6 +1310,9 @@ class OutputPage extends ContextSource {
                if ( $this->getConfig()->get( 'ContentHandlerUseDB' ) ) {
                        $fields[] = 'page_content_model';
                }
+               if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
+                       $fields[] = 'page_lang';
+               }
 
                $res = $dbr->select( array( 'page', 'page_props' ),
                        $fields,
index e3ceaee..806def2 100644 (file)
@@ -145,8 +145,9 @@ class Title implements LinkTarget {
        /** @var bool The (string) language code of the page's language and content code. */
        private $mPageLanguage = false;
 
-       /** @var string The page language code from the database */
-       private $mDbPageLanguage = null;
+       /** @var string|boolean|null The page language code from the database, null if not saved in
+        * the database or false if not loaded, yet. */
+       private $mDbPageLanguage = false;
 
        /** @var TitleValue A corresponding TitleValue object */
        private $mTitleValue = null;
@@ -385,7 +386,7 @@ class Title implements LinkTarget {
         * @return array
         */
        protected static function getSelectFields() {
-               global $wgContentHandlerUseDB;
+               global $wgContentHandlerUseDB, $wgPageLanguageUseDB;
 
                $fields = array(
                        'page_namespace', 'page_title', 'page_id',
@@ -396,6 +397,10 @@ class Title implements LinkTarget {
                        $fields[] = 'page_content_model';
                }
 
+               if ( $wgPageLanguageUseDB ) {
+                       $fields[] = 'page_lang';
+               }
+
                return $fields;
        }
 
@@ -3303,7 +3308,7 @@ class Title implements LinkTarget {
                $this->mContentModel = false;
                $this->mEstimateRevisions = null;
                $this->mPageLanguage = false;
-               $this->mDbPageLanguage = null;
+               $this->mDbPageLanguage = false;
                $this->mIsBigDeletion = null;
        }
 
@@ -4617,6 +4622,27 @@ class Title implements LinkTarget {
                return $unprefixed;
        }
 
+       /**
+        * Returns the page language code saved in the database, if $wgPageLanguageUseDB is set
+        * to true in LocalSettings.php, otherwise returns false. If there is no language saved in
+        * the db, it will return NULL.
+        *
+        * @return string|null|boolean
+        */
+       private function getDbPageLanguageCode() {
+               global $wgPageLanguageUseDB;
+
+               // check, if the page language could be saved in the database, and if so and
+               // the value is not requested already, lookup the page language using LinkCache
+               if ( $wgPageLanguageUseDB && $this->mDbPageLanguage === false ) {
+                       $linkCache = LinkCache::singleton();
+                       $linkCache->addLinkObj( $this );
+                       $this->mDbPageLanguage = $linkCache->getGoodLinkFieldObj( $this, 'lang' );
+               }
+
+               return $this->mDbPageLanguage;
+       }
+
        /**
         * Get the language in which the content of this page is written in
         * wikitext. Defaults to $wgContLang, but in certain cases it can be
@@ -4633,8 +4659,9 @@ class Title implements LinkTarget {
                }
 
                // Checking if DB language is set
-               if ( $this->mDbPageLanguage ) {
-                       return wfGetLangObj( $this->mDbPageLanguage );
+               $dbPageLanguage = $this->getDbPageLanguageCode();
+               if ( $dbPageLanguage ) {
+                       return wfGetLangObj( $dbPageLanguage );
                }
 
                if ( !$this->mPageLanguage || $this->mPageLanguage[1] !== $wgLanguageCode ) {
index c6abf40..cb08ec1 100644 (file)
@@ -305,6 +305,10 @@ class ApiPageSet extends ApiBase {
                        $pageFlds['page_content_model'] = null;
                }
 
+               if ( $this->getConfig()->get( 'PageLanguageUseDB' ) ) {
+                       $pageFlds['page_lang'] = null;
+               }
+
                // only store non-default fields
                $this->mRequestedPageFields = array_diff_key( $this->mRequestedPageFields, $pageFlds );
 
index 8f334cc..88d8b5a 100644 (file)
@@ -178,7 +178,7 @@ class LinkBatch {
         * @return bool|ResultWrapper
         */
        public function doQuery() {
-               global $wgContentHandlerUseDB;
+               global $wgContentHandlerUseDB, $wgPageLanguageUseDB;
 
                if ( $this->isEmpty() ) {
                        return false;
@@ -193,6 +193,9 @@ class LinkBatch {
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'page_content_model';
                }
+               if ( $wgPageLanguageUseDB ) {
+                       $fields[] = 'page_lang';
+               }
 
                $conds = $this->constructSet( 'page', $dbr );
 
index 5ea926b..f199891 100644 (file)
@@ -150,9 +150,10 @@ class LinkCache {
         * @param int $redir Whether the page is a redirect
         * @param int $revision Latest revision's ID
         * @param string|null $model Latest revision's content model ID
+        * @param string|null $lang Language code of the page, if not the content language
         */
        public function addGoodLinkObj( $id, Title $title, $len = -1, $redir = null,
-               $revision = 0, $model = null
+               $revision = 0, $model = null, $lang = null
        ) {
                $dbkey = $title->getPrefixedDBkey();
                $this->mGoodLinks->set( $dbkey, array(
@@ -161,6 +162,7 @@ class LinkCache {
                        'redirect' => (int)$redir,
                        'revision' => (int)$revision,
                        'model' => $model ? (string)$model : null,
+                       'lang' => $lang ? (string)$lang : null,
                ) );
        }
 
@@ -179,6 +181,7 @@ class LinkCache {
                        'redirect' => intval( $row->page_is_redirect ),
                        'revision' => intval( $row->page_latest ),
                        'model' => !empty( $row->page_content_model ) ? strval( $row->page_content_model ) : null,
+                       'lang' => !empty( $row->page_lang ) ? strval( $row->page_lang ) : null,
                ) );
        }
 
@@ -226,7 +229,7 @@ class LinkCache {
         * @return int Page ID or zero
         */
        public function addLinkObj( Title $nt ) {
-               global $wgContentHandlerUseDB;
+               global $wgContentHandlerUseDB, $wgPageLanguageUseDB;
 
                $key = $nt->getPrefixedDBkey();
                if ( $this->isBadLink( $key ) || $nt->isExternal() ) {
@@ -248,6 +251,9 @@ class LinkCache {
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'page_content_model';
                }
+               if ( $wgPageLanguageUseDB ) {
+                       $fields[] = 'page_lang';
+               }
 
                $row = $db->selectRow( 'page', $fields,
                        array( 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ),
index 7fc9a16..dfc4b53 100644 (file)
@@ -282,7 +282,7 @@ class LinkHolderArray {
                        return;
                }
 
-               global $wgContLang, $wgContentHandlerUseDB;
+               global $wgContLang, $wgContentHandlerUseDB, $wgPageLanguageUseDB;
 
                $colours = array();
                $linkCache = LinkCache::singleton();
@@ -348,6 +348,9 @@ class LinkHolderArray {
                        if ( $wgContentHandlerUseDB ) {
                                $fields[] = 'page_content_model';
                        }
+                       if ( $wgPageLanguageUseDB ) {
+                               $fields[] = 'page_lang';
+                       }
 
                        $res = $dbr->select(
                                'page',
@@ -460,7 +463,7 @@ class LinkHolderArray {
         * @param array $colours
         */
        protected function doVariants( &$colours ) {
-               global $wgContLang, $wgContentHandlerUseDB;
+               global $wgContLang, $wgContentHandlerUseDB, $wgPageLanguageUseDB;
                $linkBatch = new LinkBatch();
                $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders)
                $output = $this->parent->getOutput();
@@ -555,6 +558,9 @@ class LinkHolderArray {
                        if ( $wgContentHandlerUseDB ) {
                                $fields[] = 'page_content_model';
                        }
+                       if ( $wgPageLanguageUseDB ) {
+                               $fields[] = 'page_lang';
+                       }
 
                        $varRes = $dbr->select( 'page',
                                $fields,
index 38093be..20af655 100644 (file)
@@ -122,8 +122,7 @@ class SpecialPageLanguage extends FormSpecialPage {
                }
 
                // Get the default language for the wiki
-               // Returns the default since the page is not loaded from DB
-               $defLang = $title->getPageLanguage()->getCode();
+               $defLang = $this->getConfig()->get( 'LanguageCode' );
 
                $pageId = $title->getArticleID();