Merge "'lang' attrib in #mw-content-text should be set to variant code."
[lhc/web/wiklou.git] / includes / Title.php
index 4f7984e..f9c7bdf 100644 (file)
@@ -347,7 +347,7 @@ class Title {
         * @return Title the new object
         */
        public static function newMainPage() {
-               $title = Title::newFromText( wfMsgForContent( 'mainpage' ) );
+               $title = Title::newFromText( wfMessage( 'mainpage' )->inContentLanguage()->text() );
                // Don't give fatal errors if the message is broken
                if ( !$title ) {
                        $title = Title::newFromText( 'Main Page' );
@@ -825,7 +825,7 @@ class Title {
 
        /**
         * Returns true if the title is inside the specified namespace.
-        * 
+        *
         * Please make use of this instead of comparing to getNamespace()
         * This function is much more resistant to changes we may make
         * to namespaces than code that makes direct comparisons.
@@ -1270,9 +1270,11 @@ class Title {
         * See getLocalURL for the arguments.
         *
         * @see self::getLocalURL
+        * @see wfExpandUrl
+        * @param $proto Protocol type to use in URL
         * @return String the URL
         */
-       public function getFullURL( $query = '', $query2 = false ) {
+       public function getFullURL( $query = '', $query2 = false, $proto = PROTO_RELATIVE ) {
                $query = self::fixUrlQueryArgs( $query, $query2 );
 
                # Hand off all the decisions on urls to getLocalURL
@@ -1281,7 +1283,7 @@ class Title {
                # Expand the url to make it a full url. Note that getLocalURL has the
                # potential to output full urls for a variety of reasons, so we use
                # wfExpandUrl instead of simply prepending $wgServer
-               $url = wfExpandUrl( $url, PROTO_RELATIVE );
+               $url = wfExpandUrl( $url, $proto );
 
                # Finally, add the fragment.
                $url .= $this->getFragmentForURL();
@@ -1592,7 +1594,7 @@ class Title {
         *   queries by skipping checks for cascading protections and user blocks.
         * @param $ignoreErrors Array of Strings Set this to a list of message keys
         *   whose corresponding errors may be ignored.
-        * @return Array of arguments to wfMsg to explain permissions problems.
+        * @return Array of arguments to wfMessage to explain permissions problems.
         */
        public function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) {
                $errors = $this->getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries );
@@ -1749,7 +1751,7 @@ class Title {
                # Check $wgNamespaceProtection for restricted namespaces
                if ( $this->isNamespaceProtected( $user ) ) {
                        $ns = $this->mNamespace == NS_MAIN ?
-                               wfMsg( 'nstab-main' ) : $this->getNsText();
+                               wfMessage( 'nstab-main' )->text() : $this->getNsText();
                        $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
                                array( 'protectedinterface' ) : array( 'namespaceprotected',  $ns );
                }
@@ -1882,7 +1884,7 @@ class Title {
                                        $title_protection['pt_create_perm'] = 'protect'; // B/C
                                }
                                if( $title_protection['pt_create_perm'] == '' ||
-                                       !$user->isAllowed( $title_protection['pt_create_perm'] ) ) 
+                                       !$user->isAllowed( $title_protection['pt_create_perm'] ) )
                                {
                                        $errors[] = array( 'titleprotected', User::whoIs( $title_protection['pt_user'] ), $title_protection['pt_reason'] );
                                }
@@ -1948,7 +1950,7 @@ class Title {
                        $id = $user->blockedBy();
                        $reason = $user->blockedFor();
                        if ( $reason == '' ) {
-                               $reason = wfMsg( 'blockednoreason' );
+                               $reason = wfMessage( 'blockednoreason' )->text();
                        }
                        $ip = $user->getRequest()->getIP();
 
@@ -2106,7 +2108,7 @@ class Title {
         * @param $user User to check
         * @param $doExpensiveQueries Bool Set this to false to avoid doing unnecessary queries.
         * @param $short Bool Set this to true to stop after the first permission error.
-        * @return Array of arrays of the arguments to wfMsg to explain permissions problems.
+        * @return Array of arrays of the arguments to wfMessage to explain permissions problems.
         */
        protected function getUserPermissionsErrorsInternal( $action, $user, $doExpensiveQueries = true, $short = false ) {
                wfProfileIn( __METHOD__ );
@@ -3544,9 +3546,13 @@ class Title {
                        );
                        # Update the protection log
                        $log = new LogPage( 'protect' );
-                       $comment = wfMsgForContent( 'prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
+                       $comment = wfMessage(
+                               'prot_1movedto2',
+                               $this->getPrefixedText(),
+                               $nt->getPrefixedText()
+                       )->inContentLanguage()->text();
                        if ( $reason ) {
-                               $comment .= wfMsgForContent( 'colon-separator' ) . $reason;
+                               $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                        }
                        // @todo FIXME: $params?
                        $log->addEntry( 'move_prot', $nt, $comment, array( $this->getPrefixedText() ) );
@@ -3604,7 +3610,7 @@ class Title {
                $formatter->setContext( RequestContext::newExtraneousContext( $this ) );
                $comment = $formatter->getPlainActionText();
                if ( $reason ) {
-                       $comment .= wfMsgForContent( 'colon-separator' ) . $reason;
+                       $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                }
                # Truncate for whole multibyte characters.
                $comment = $wgContLang->truncate( $comment, 255 );
@@ -3818,7 +3824,7 @@ class Title {
                        return false;
                }
                # Get the article text
-               $rev = Revision::newFromTitle( $nt );
+               $rev = Revision::newFromTitle( $nt, false, Revision::READ_LATEST );
                if( !is_object( $rev ) ){
                        return false;
                }
@@ -4079,30 +4085,60 @@ class Title {
        }
 
        /**
-        * Get the number of authors between the given revision IDs.
+        * Get the number of authors between the given revisions or revision IDs.
         * Used for diffs and other things that really need it.
         *
-        * @param $old int|Revision Old revision or rev ID (first before range)
-        * @param $new int|Revision New revision or rev ID (first after range)
-        * @param $limit Int Maximum number of authors
-        * @return Int Number of revision authors between these revisions.
-        */
-       public function countAuthorsBetween( $old, $new, $limit ) {
+        * @param $old int|Revision Old revision or rev ID (first before range by default)
+        * @param $new int|Revision New revision or rev ID (first after range by default)
+        * @param $limit int Maximum number of authors
+        * @param $options string|array (Optional): Single option, or an array of options:
+        *     'include_old' Include $old in the range; $new is excluded.
+        *     'include_new' Include $new in the range; $old is excluded.
+        *     'include_both' Include both $old and $new in the range.
+        *     Unknown option values are ignored.
+        * @return int Number of revision authors in the range; zero if not both revisions exist
+        */
+       public function countAuthorsBetween( $old, $new, $limit, $options = array() ) {
                if ( !( $old instanceof Revision ) ) {
                        $old = Revision::newFromTitle( $this, (int)$old );
                }
                if ( !( $new instanceof Revision ) ) {
                        $new = Revision::newFromTitle( $this, (int)$new );
                }
+               // XXX: what if Revision objects are passed in, but they don't refer to this title?
+               // Add $old->getPage() != $new->getPage() || $old->getPage() != $this->getArticleID()
+               // in the sanity check below?
                if ( !$old || !$new ) {
                        return 0; // nothing to compare
                }
+               $old_cmp = '>';
+               $new_cmp = '<';
+               $options = (array) $options;
+               if ( in_array( 'include_old', $options ) ) {
+                       $old_cmp = '>=';
+               }
+               if ( in_array( 'include_new', $options ) ) {
+                       $new_cmp = '<=';
+               }
+               if ( in_array( 'include_both', $options ) ) {
+                       $old_cmp = '>=';
+                       $new_cmp = '<=';
+               }
+               // No DB query needed if $old and $new are the same or successive revisions:
+               if ( $old->getId() === $new->getId() ) {
+                       return ( $old_cmp === '>' && $new_cmp === '<' ) ? 0 : 1;
+               } else if ( $old->getId() === $new->getParentId() ) {
+                       if ( $old_cmp === '>' || $new_cmp === '<' ) {
+                               return ( $old_cmp === '>' && $new_cmp === '<' ) ? 0 : 1;
+                       }
+                       return ( $old->getRawUserText() === $new->getRawUserText() ) ? 1 : 2;
+               }
                $dbr = wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'revision', 'DISTINCT rev_user_text',
                        array(
                                'rev_page' => $this->getArticleID(),
-                               'rev_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
-                               'rev_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $new->getTimestamp() ) )
+                               "rev_timestamp $old_cmp " . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
+                               "rev_timestamp $new_cmp " . $dbr->addQuotes( $dbr->timestamp( $new->getTimestamp() ) )
                        ), __METHOD__,
                        array( 'LIMIT' => $limit + 1 ) // add one so caller knows it was truncated
                );
@@ -4494,9 +4530,9 @@ class Title {
        }
 
        /**
-        * Get the language in which the content of this page is written.
-        * Defaults to $wgContLang, but in certain cases it can be e.g.
-        * $wgLang (such as special pages, which are in the user language).
+        * Get the language in which the content of this page is written in
+        * wikitext. Defaults to $wgContLang, but in certain cases it can be
+        * e.g. $wgLang (such as special pages, which are in the user language).
         *
         * @since 1.18
         * @return Language
@@ -4521,4 +4557,29 @@ class Title {
                wfRunHooks( 'PageContentLanguage', array( $this, &$pageLang, $wgLang ) );
                return wfGetLangObj( $pageLang );
        }
+
+       /**
+        * Get the language in which the content of this page is written when
+        * viewed by user. Defaults to $wgContLang, but in certain cases it can be
+        * e.g. $wgLang (such as special pages, which are in the user language).
+        *
+        * @since 1.20
+        * @return Language
+        */
+       public function getPageViewLanguage() {
+               $pageLang = $this->getPageLanguage();
+               // If this is nothing special (so the content is converted when viewed)
+               if ( !$this->isSpecialPage()
+                       && !$this->isCssOrJsPage() && !$this->isCssJsSubpage()
+                       && $this->getNamespace() !== NS_MEDIAWIKI
+               ) {
+                       // If the user chooses a variant, the content is actually
+                       // in a language whose code is the variant code.
+                       $variant = $pageLang->getPreferredVariant();
+                       if ( $pageLang->getCode() !== $variant ) {
+                               $pageLang = Language::factory( $variant );
+                       }
+               }
+               return $pageLang;
+       }
 }