Merge "Html::closeElement: Don't omit closing tags."
[lhc/web/wiklou.git] / includes / Title.php
index 9d8614d..2481178 100644 (file)
@@ -95,7 +95,7 @@ class Title {
        /** @var array Array of groups allowed to edit this article */
        public $mRestrictions = array();
 
-       /** @var bool  */
+       /** @var bool */
        protected $mOldRestrictions = false;
 
        /** @var bool Cascade restrictions on this page to included templates and images? */
@@ -150,6 +150,9 @@ class Title {
        /** @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 TitleValue A corresponding TitleValue object */
        private $mTitleValue = null;
        // @}
@@ -439,6 +442,9 @@ class Title {
                        } else {
                                $this->mContentModel = false; # initialized lazily in getContentModel()
                        }
+                       if ( isset( $row->page_lang ) ) {
+                               $this->mDbPageLanguage = (string)$row->page_lang;
+                       }
                } else { // page not found
                        $this->mArticleID = 0;
                        $this->mLength = 0;
@@ -602,7 +608,7 @@ class Title {
         * Note that this doesn't pick up many things that could be wrong with titles, but that
         * replacing this regex with something valid will make many titles valid.
         *
-        * @todo: move this into MediaWikiTitleCodec
+        * @todo move this into MediaWikiTitleCodec
         *
         * @return string Regex string
         */
@@ -847,7 +853,7 @@ class Title {
        /**
         * Get a TitleValue object representing this Title.
         *
-        * @note: Not all valid Titles have a corresponding valid TitleValue
+        * @note Not all valid Titles have a corresponding valid TitleValue
         * (e.g. TitleValues cannot represent page-local links that have a
         * fragment but no title text).
         *
@@ -971,9 +977,9 @@ class Title {
                }
 
                try {
-                       $formatter = $this->getTitleFormatter();
+                       $formatter = self::getTitleFormatter();
                        return $formatter->getNamespaceName( $this->mNamespace, $this->mDbkeyform );
-               } catch ( InvalidArgumentException $ex )  {
+               } catch ( InvalidArgumentException $ex ) {
                        wfDebug( __METHOD__ . ': ' . $ex->getMessage() . "\n" );
                        return false;
                }
@@ -1088,7 +1094,7 @@ class Title {
        /**
         * Returns true if the title is inside one of the specified namespaces.
         *
-        * @param ...$namespaces The namespaces to check for
+        * @param int $namespaces,... The namespaces to check for
         * @return bool
         * @since 1.19
         */
@@ -1365,7 +1371,6 @@ class Title {
         *
         * @param string $name The text
         * @return string The prefixed text
-        * @private
         */
        private function prefix( $name ) {
                $p = '';
@@ -1541,18 +1546,6 @@ class Title {
                return Title::makeTitleSafe( $this->getNamespace(), $this->getText() . '/' . $text );
        }
 
-       /**
-        * Get the HTML-escaped displayable text form.
-        * Used for the title field in <a> tags.
-        *
-        * @return string The text, including any prefixes
-        * @deprecated since 1.19
-        */
-       public function getEscapedText() {
-               wfDeprecated( __METHOD__, '1.19' );
-               return htmlspecialchars( $this->getPrefixedText() );
-       }
-
        /**
         * Get a URL-encoded form of the subpage text
         *
@@ -1650,9 +1643,11 @@ class Title {
         * $wgServer is prepended to make an absolute URL.
         *
         * @see self::getFullURL to always get an absolute URL.
+        * @see self::getLinkURL to always get a URL that's the simplest URL that will be
+        *  valid to link, locally, to the current Title.
         * @see self::newFromText to produce a Title object.
         *
-        * @param string|array $query an optional query string,
+        * @param string|array $query An optional query string,
         *   not used for interwiki links. Can be specified as an associative array as well,
         *   e.g., array( 'action' => 'edit' ) (keys and values will be URL-escaped).
         *   Some query patterns will trigger various shorturl path replacements.
@@ -1770,34 +1765,6 @@ class Title {
                return $ret;
        }
 
-       /**
-        * Get an HTML-escaped version of the URL form, suitable for
-        * using in a link, without a server name or fragment
-        *
-        * @see self::getLocalURL for the arguments.
-        * @param string $query
-        * @param bool|string $query2
-        * @return string The URL
-        * @deprecated since 1.19
-        */
-       public function escapeLocalURL( $query = '', $query2 = false ) {
-               wfDeprecated( __METHOD__, '1.19' );
-               return htmlspecialchars( $this->getLocalURL( $query, $query2 ) );
-       }
-
-       /**
-        * Get an HTML-escaped version of the URL form, suitable for
-        * using in a link, including the server name and fragment
-        *
-        * @see self::getLocalURL for the arguments.
-        * @return string The URL
-        * @deprecated since 1.19
-        */
-       public function escapeFullURL( $query = '', $query2 = false ) {
-               wfDeprecated( __METHOD__, '1.19' );
-               return htmlspecialchars( $this->getFullURL( $query, $query2 ) );
-       }
-
        /**
         * Get the URL form for an internal link.
         * - Used in various Squid-related code, in case we have a different
@@ -1837,19 +1804,6 @@ class Title {
                return $url;
        }
 
-       /**
-        * HTML-escaped version of getCanonicalURL()
-        *
-        * @see self::getLocalURL for the arguments.
-        * @since 1.18
-        * @return string
-        * @deprecated since 1.19
-        */
-       public function escapeCanonicalURL( $query = '', $query2 = false ) {
-               wfDeprecated( __METHOD__, '1.19' );
-               return htmlspecialchars( $this->getCanonicalURL( $query, $query2 ) );
-       }
-
        /**
         * Get the edit URL for this Title
         *
@@ -1883,17 +1837,6 @@ class Title {
                return $this->mWatched;
        }
 
-       /**
-        * Can $wgUser read this page?
-        *
-        * @deprecated since 1.19; use userCan(), quickUserCan() or getUserPermissionsErrors() instead
-        * @return bool
-        */
-       public function userCanRead() {
-               wfDeprecated( __METHOD__, '1.19' );
-               return $this->userCan( 'read' );
-       }
-
        /**
         * Can $user perform $action on this page?
         * This skips potentially expensive cascading permission checks
@@ -1937,11 +1880,11 @@ class Title {
         *
         * @todo FIXME: This *does not* check throttles (User::pingLimiter()).
         *
-        * @param string $action action that permission needs to be checked for
+        * @param string $action Action that permission needs to be checked for
         * @param User $user User to check
         * @param bool $doExpensiveQueries Set this to false to avoid doing unnecessary
         *   queries by skipping checks for cascading protections and user blocks.
-        * @param array $ignoreErrors of Strings Set this to a list of message keys
+        * @param array $ignoreErrors Array of Strings Set this to a list of message keys
         *   whose corresponding errors may be ignored.
         * @return array Array of arguments to wfMessage to explain permissions problems.
         */
@@ -1965,7 +1908,7 @@ class Title {
        /**
         * Permissions checks that fail most often, and which are easiest to test.
         *
-        * @param string $action the action to check
+        * @param string $action The action to check
         * @param User $user User to check
         * @param array $errors List of current errors
         * @param bool $doExpensiveQueries Whether or not to perform expensive queries
@@ -2563,7 +2506,7 @@ class Title {
                        return false;
                }
 
-               if ( !isset( $this->mTitleProtection ) ) {
+               if ( $this->mTitleProtection === null ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $res = $dbr->select(
                                'protected_titles',
@@ -2578,30 +2521,6 @@ class Title {
                return $this->mTitleProtection;
        }
 
-       /**
-        * Update the title protection status
-        *
-        * @deprecated since 1.19; use WikiPage::doUpdateRestrictions() instead.
-        * @param string $create_perm Permission required for creation
-        * @param string $reason Reason for protection
-        * @param string $expiry Expiry timestamp
-        * @return bool
-        */
-       public function updateTitleProtection( $create_perm, $reason, $expiry ) {
-               wfDeprecated( __METHOD__, '1.19' );
-
-               global $wgUser;
-
-               $limit = array( 'create' => $create_perm );
-               $expiry = array( 'create' => $expiry );
-
-               $page = WikiPage::factory( $this );
-               $cascade = false;
-               $status = $page->doUpdateRestrictions( $limit, $expiry, $cascade, $reason, $wgUser );
-
-               return $status->isOK();
-       }
-
        /**
         * Remove any title protection due to page existing
         */
@@ -2647,7 +2566,7 @@ class Title {
        /**
         * Does the title correspond to a protected article?
         *
-        * @param string $action the action the page is protected from,
+        * @param string $action The action the page is protected from,
         * by default checks all actions.
         * @return bool
         */
@@ -2716,7 +2635,7 @@ class Title {
         * @since 1.23
         */
        public function areCascadeProtectionSourcesLoaded( $getPages = true ) {
-               return $getPages ? isset( $this->mCascadeSources ) : isset( $this->mHasCascadingRestrictions );
+               return $getPages ? $this->mCascadeSources !== null : $this->mHasCascadingRestrictions !== null;
        }
 
        /**
@@ -2736,9 +2655,9 @@ class Title {
                global $wgContLang;
                $pagerestrictions = array();
 
-               if ( isset( $this->mCascadeSources ) && $getPages ) {
+               if ( $this->mCascadeSources !== null && $getPages ) {
                        return array( $this->mCascadeSources, $this->mCascadingRestrictions );
-               } elseif ( isset( $this->mHasCascadingRestrictions ) && !$getPages ) {
+               } elseif ( $this->mHasCascadingRestrictions !== null && !$getPages ) {
                        return array( $this->mHasCascadingRestrictions, $pagerestrictions );
                }
 
@@ -3055,7 +2974,7 @@ class Title {
 
                $method = __METHOD__;
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->onTransactionIdle( function() use ( $dbw, $method ) {
+               $dbw->onTransactionIdle( function () use ( $dbw, $method ) {
                        $dbw->delete(
                                'page_restrictions',
                                array( 'pr_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ),
@@ -3084,7 +3003,7 @@ class Title {
                # alone to cache the result.  There's no point in having it hanging
                # around uninitialized in every Title object; therefore we only add it
                # if needed and don't declare it statically.
-               if ( !isset( $this->mHasSubpages ) ) {
+               if ( $this->mHasSubpages === null ) {
                        $this->mHasSubpages = false;
                        $subpages = $this->getSubpages( 1 );
                        if ( $subpages instanceof TitleArray ) {
@@ -3320,6 +3239,7 @@ class Title {
                $this->mContentModel = false;
                $this->mEstimateRevisions = null;
                $this->mPageLanguage = false;
+               $this->mDbPageLanguage = null;
        }
 
        /**
@@ -3362,7 +3282,7 @@ class Title {
                        // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share
                        //        the parsing code with Title, while avoiding massive refactoring.
                        // @todo: get rid of secureAndSplit, refactor parsing code.
-                       $parser = $this->getTitleParser();
+                       $parser = self::getTitleParser();
                        $parts = $parser->splitTitleString( $dbkey, $this->getDefaultNamespace() );
                } catch ( MalformedTitleException $ex ) {
                        return false;
@@ -3896,13 +3816,31 @@ class Title {
                        $log->addRelations( 'pr_id', $logRelationsValues, $logId );
                }
 
+               // Update *_from_namespace fields as needed
+               if ( $this->getNamespace() != $nt->getNamespace() ) {
+                       $dbw->update( 'pagelinks',
+                               array( 'pl_from_namespace' => $nt->getNamespace() ),
+                               array( 'pl_from' => $pageid ),
+                               __METHOD__
+                       );
+                       $dbw->update( 'templatelinks',
+                               array( 'tl_from_namespace' => $nt->getNamespace() ),
+                               array( 'tl_from' => $pageid ),
+                               __METHOD__
+                       );
+                       $dbw->update( 'imagelinks',
+                               array( 'il_from_namespace' => $nt->getNamespace() ),
+                               array( 'il_from' => $pageid ),
+                               __METHOD__
+                       );
+               }
+
                # Update watchlists
-               $oldnamespace = MWNamespace::getSubject( $this->getNamespace() );
-               $newnamespace = MWNamespace::getSubject( $nt->getNamespace() );
                $oldtitle = $this->getDBkey();
                $newtitle = $nt->getDBkey();
-
-               if ( $oldnamespace != $newnamespace || $oldtitle != $newtitle ) {
+               $oldsnamespace = MWNamespace::getSubject( $this->getNamespace() );
+               $newsnamespace = MWNamespace::getSubject( $nt->getNamespace() );
+               if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
                        WatchedItem::duplicateEntries( $this, $nt );
                }
 
@@ -4738,7 +4676,7 @@ class Title {
                $method = __METHOD__;
                $dbw = wfGetDB( DB_MASTER );
                $conds = $this->pageCond();
-               $dbw->onTransactionIdle( function() use ( $dbw, $conds, $method ) {
+               $dbw->onTransactionIdle( function () use ( $dbw, $conds, $method ) {
                        $dbw->update(
                                'page',
                                array( 'page_touched' => $dbw->timestamp() ),
@@ -4772,7 +4710,9 @@ class Title {
         * @return string Last-touched timestamp
         */
        public function getTouched( $db = null ) {
-               $db = isset( $db ) ? $db : wfGetDB( DB_SLAVE );
+               if ( $db === null ) {
+                       $db = wfGetDB( DB_SLAVE );
+               }
                $touched = $db->selectField( 'page', 'page_touched', $this->pageCond(), __METHOD__ );
                return $touched;
        }
@@ -4977,6 +4917,12 @@ class Title {
                        return $wgLang;
                }
 
+               // Checking if DB language is set
+               if ( $this->mDbPageLanguage ) {
+                       wfProfileOut( __METHOD__ );
+                       return wfGetLangObj( $this->mDbPageLanguage );
+               }
+
                if ( !$this->mPageLanguage || $this->mPageLanguage[1] !== $wgLanguageCode ) {
                        // Note that this may depend on user settings, so the cache should
                        // be only per-request.
@@ -4990,6 +4936,7 @@ class Title {
                } else {
                        $langObj = wfGetLangObj( $this->mPageLanguage[0] );
                }
+
                wfProfileOut( __METHOD__ );
                return $langObj;
        }