Expose the log_id of the deletion log entry in the action=delete API
[lhc/web/wiklou.git] / includes / Title.php
index f72a5ea..6e3f16c 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Representation a title within %MediaWiki.
+ *
  * See title.txt
  *
  * This program is free software; you can redistribute it and/or modify
@@ -83,6 +85,7 @@ class Title {
        var $mRedirect = null;            // /< Is the article at this title a redirect?
        var $mNotificationTimestamp = array(); // /< Associative array of user ID -> timestamp/false
        var $mBacklinkCache = null;       // /< Cache of links to this title
+       var $mHasSubpage;                 // /< Whether a page has any subpages
        // @}
 
 
@@ -119,7 +122,8 @@ class Title {
         *   fied by a prefix.  If you want to force a specific namespace even if
         *   $text might begin with a namespace prefix, use makeTitle() or
         *   makeTitleSafe().
-        * @return Title, or null on an error.
+        * @throws MWException
+        * @return Title|null - Title or null on an error.
         */
        public static function newFromText( $text, $defaultNamespace = NS_MAIN ) {
                if ( is_object( $text ) ) {
@@ -179,13 +183,12 @@ class Title {
         * @return Title the new object, or NULL on an error
         */
        public static function newFromURL( $url ) {
-               global $wgLegalTitleChars;
                $t = new Title();
 
                # For compatibility with old buggy URLs. "+" is usually not valid in titles,
                # but some URLs used it as a space replacement and they still come
                # from some external search tools.
-               if ( strpos( $wgLegalTitleChars, '+' ) === false ) {
+               if ( strpos( self::legalChars(), '+' ) === false ) {
                        $url = str_replace( '+', ' ', $url );
                }
 
@@ -317,6 +320,10 @@ class Title {
         * @return Title the new object, or NULL on an error
         */
        public static function makeTitleSafe( $ns, $title, $fragment = '', $interwiki = '' ) {
+               if ( !MWNamespace::exists( $ns ) ) {
+                       return null;
+               }
+
                $t = new Title();
                $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki );
                if ( $t->secureAndSplit() ) {
@@ -707,17 +714,9 @@ class Title {
                        }
                }
 
-               // Strip off subpages
-               $pagename = $this->getText();
-               if ( strpos( $pagename, '/' ) !== false ) {
-                       list( $username , ) = explode( '/', $pagename, 2 );
-               } else {
-                       $username = $pagename;
-               }
-
                if ( $wgContLang->needsGenderDistinction() &&
                                MWNamespace::hasGenderDistinction( $this->mNamespace ) ) {
-                       $gender = GenderCache::singleton()->getGenderOf( $username, __METHOD__ );
+                       $gender = GenderCache::singleton()->getGenderOf( $this->getText(), __METHOD__ );
                        return $wgContLang->getGenderNsText( $this->mNamespace, $gender );
                }
 
@@ -862,6 +861,7 @@ class Title {
         * This is MUCH simpler than individually testing for equivilance
         * against both NS_USER and NS_USER_TALK, and is also forward compatible.
         * @since 1.19
+        * @param $ns int
         * @return bool
         */
        public function hasSubjectNamespace( $ns ) {
@@ -1226,6 +1226,8 @@ class Title {
         * andthe wfArrayToCGI moved to getLocalURL();
         *
         * @since 1.19 (r105919)
+        * @param $query
+        * @param $query2 bool
         * @return String
         */
        private static function fixUrlQueryArgs( $query, $query2 = false ) {
@@ -1408,6 +1410,8 @@ class Title {
         * See getLocalURL for the arguments.
         *
         * @see self::getLocalURL
+        * @param $query string
+        * @param $query2 bool|string
         * @return String the URL
         */
        public function escapeLocalURL( $query = '', $query2 = false ) {
@@ -1927,7 +1931,7 @@ class Title {
                        // Don't block the user from editing their own talk page unless they've been
                        // explicitly blocked from that too.
                } elseif( $user->isBlocked() && $user->mBlock->prevents( $action ) !== false ) {
-                       $block = $user->mBlock;
+                       $block = $user->getBlock();
 
                        // This is from OutputPage::blockedPage
                        // Copied at r23888 by werdna
@@ -1947,15 +1951,15 @@ class Title {
 
                        $link = '[[' . $wgContLang->getNsText( NS_USER ) . ":{$name}|{$name}]]";
                        $blockid = $block->getId();
-                       $blockExpiry = $user->mBlock->mExpiry;
-                       $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $user->mBlock->mTimestamp ), true );
+                       $blockExpiry = $block->getExpiry();
+                       $blockTimestamp = $wgLang->timeanddate( wfTimestamp( TS_MW, $block->mTimestamp ), true );
                        if ( $blockExpiry == 'infinity' ) {
                                $blockExpiry = wfMessage( 'infiniteblock' )->text();
                        } else {
                                $blockExpiry = $wgLang->timeanddate( wfTimestamp( TS_MW, $blockExpiry ), true );
                        }
 
-                       $intended = strval( $user->mBlock->getTarget() );
+                       $intended = strval( $block->getTarget() );
 
                        $errors[] = array( ( $block->mAuto ? 'autoblockedtext' : 'blockedtext' ), $link, $reason, $ip, $name,
                                $blockid, $blockExpiry, $intended, $blockTimestamp );
@@ -2472,8 +2476,9 @@ class Title {
        /**
         * Get the expiry time for the restriction against a given action
         *
+        * @param $action
         * @return String|Bool 14-char timestamp, or 'infinity' if the page is protected forever
-        *      or not protected at all, or false if the action is not recognised.
+        *     or not protected at all, or false if the action is not recognised.
         */
        public function getRestrictionExpiry( $action ) {
                if ( !$this->mRestrictionsLoaded ) {
@@ -2538,7 +2543,7 @@ class Title {
 
                if ( $oldFashionedRestrictions === null ) {
                        $oldFashionedRestrictions = $dbr->selectField( 'page', 'page_restrictions',
-                               array( 'page_id' => $this->getArticleId() ), __METHOD__ );
+                               array( 'page_id' => $this->getArticleID() ), __METHOD__ );
                }
 
                if ( $oldFashionedRestrictions != '' ) {
@@ -2609,7 +2614,7 @@ class Title {
                                $res = $dbr->select(
                                        'page_restrictions',
                                        '*',
-                                       array( 'pr_page' => $this->getArticleId() ),
+                                       array( 'pr_page' => $this->getArticleID() ),
                                        __METHOD__
                                );
 
@@ -2861,7 +2866,7 @@ class Title {
         *
         * - This is called from WikiPage::doEdit() and WikiPage::insertOn() to allow
         * loading of the new page_id. It's also called from
-        * WikiPage::doDeleteArticle()
+        * WikiPage::doDeleteArticleReal()
         *
         * @param $newid Int the new Article ID
         */
@@ -3167,7 +3172,7 @@ class Title {
         * @return Array of Title objects linking here
         */
        public function getLinksFrom( $options = array(), $table = 'pagelinks', $prefix = 'pl' ) {
-               $id = $this->getArticleId();
+               $id = $this->getArticleID();
 
                # If the page doesn't exist; there can't be any link from this page
                if ( !$id ) {
@@ -3231,7 +3236,7 @@ class Title {
         * @return Array of Title the Title objects
         */
        public function getBrokenLinksFrom() {
-               if ( $this->getArticleId() == 0 ) {
+               if ( $this->getArticleID() == 0 ) {
                        # All links from article ID 0 are false positives
                        return array();
                }
@@ -3241,7 +3246,7 @@ class Title {
                        array( 'page', 'pagelinks' ),
                        array( 'pl_namespace', 'pl_title' ),
                        array(
-                               'pl_from' => $this->getArticleId(),
+                               'pl_from' => $this->getArticleID(),
                                'page_namespace IS NULL'
                        ),
                        __METHOD__, array(),
@@ -3476,7 +3481,7 @@ class Title {
                        RepoGroup::singleton()->clearCache( $nt ); # clear false negative cache
                }
 
-               $dbw->begin(); # If $file was a LocalFile, its transaction would have closed our own.
+               $dbw->begin( __METHOD__ ); # If $file was a LocalFile, its transaction would have closed our own.
                $pageid = $this->getArticleID( self::GAID_FOR_UPDATE );
                $protected = $this->isProtected();
 
@@ -3484,7 +3489,7 @@ class Title {
                $err = $this->moveToInternal( $nt, $reason, $createRedirect );
                if ( is_array( $err ) ) {
                        # @todo FIXME: What about the File we have already moved?
-                       $dbw->rollback();
+                       $dbw->rollback( __METHOD__ );
                        return $err;
                }
 
@@ -3548,7 +3553,7 @@ class Title {
                        WatchedItem::duplicateEntries( $this, $nt );
                }
 
-               $dbw->commit();
+               $dbw->commit( __METHOD__ );
 
                wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );
                return true;
@@ -3595,7 +3600,6 @@ class Title {
                $comment = $wgContLang->truncate( $comment, 255 );
 
                $oldid = $this->getArticleID();
-               $latest = $this->getLatestRevID();
 
                $dbw = wfGetDB( DB_MASTER );
 
@@ -3636,10 +3640,14 @@ class Title {
                $newpage->updateRevisionOn( $dbw, $nullRevision );
 
                wfRunHooks( 'NewRevisionFromEditComplete',
-                       array( $newpage, $nullRevision, $latest, $wgUser ) );
+                       array( $newpage, $nullRevision, $nullRevision->getParentId(), $wgUser ) );
 
                $newpage->doEditUpdates( $nullRevision, $wgUser, array( 'changed' => false ) );
 
+               if ( !$moveOverRedirect ) {
+                       WikiPage::onArticleCreate( $nt );
+               }
+
                # Recreate the redirect, this time in the other direction.
                if ( $redirectSuppressed ) {
                        WikiPage::onArticleDelete( $this );
@@ -3711,8 +3719,8 @@ class Title {
                        // We don't know whether this function was called before
                        // or after moving the root page, so check both
                        // $this and $nt
-                       if ( $oldSubpage->getArticleId() == $this->getArticleId() ||
-                                       $oldSubpage->getArticleID() == $nt->getArticleId() )
+                       if ( $oldSubpage->getArticleID() == $this->getArticleID() ||
+                                       $oldSubpage->getArticleID() == $nt->getArticleID() )
                        {
                                // When moving a page to a subpage of itself,
                                // don't move it twice
@@ -3836,7 +3844,7 @@ class Title {
 
                $data = array();
 
-               $titleKey = $this->getArticleId();
+               $titleKey = $this->getArticleID();
 
                if ( $titleKey === 0 ) {
                        return $data;
@@ -3912,14 +3920,20 @@ class Title {
         */
        public function getPreviousRevisionID( $revId, $flags = 0 ) {
                $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
-               return $db->selectField( 'revision', 'rev_id',
+               $revId = $db->selectField( 'revision', 'rev_id',
                        array(
-                               'rev_page' => $this->getArticleId( $flags ),
+                               'rev_page' => $this->getArticleID( $flags ),
                                'rev_id < ' . intval( $revId )
                        ),
                        __METHOD__,
                        array( 'ORDER BY' => 'rev_id DESC' )
                );
+
+               if ( $revId === false ) {
+                       return false;
+               } else {
+                       return intval( $revId );
+               }
        }
 
        /**
@@ -3931,14 +3945,20 @@ class Title {
         */
        public function getNextRevisionID( $revId, $flags = 0 ) {
                $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
-               return $db->selectField( 'revision', 'rev_id',
+               $revId = $db->selectField( 'revision', 'rev_id',
                        array(
-                               'rev_page' => $this->getArticleId( $flags ),
+                               'rev_page' => $this->getArticleID( $flags ),
                                'rev_id > ' . intval( $revId )
                        ),
                        __METHOD__,
                        array( 'ORDER BY' => 'rev_id' )
                );
+
+               if ( $revId === false ) {
+                       return false;
+               } else {
+                       return intval( $revId );
+               }
        }
 
        /**
@@ -3948,7 +3968,7 @@ class Title {
         * @return Revision|Null if page doesn't exist
         */
        public function getFirstRevision( $flags = 0 ) {
-               $pageId = $this->getArticleId( $flags );
+               $pageId = $this->getArticleID( $flags );
                if ( $pageId ) {
                        $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_SLAVE );
                        $row = $db->selectRow( 'revision', '*',
@@ -4013,7 +4033,7 @@ class Title {
                if ( $this->mEstimateRevisions === null ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $this->mEstimateRevisions = $dbr->estimateRowCount( 'revision', '*',
-                               array( 'rev_page' => $this->getArticleId() ), __METHOD__ );
+                               array( 'rev_page' => $this->getArticleID() ), __METHOD__ );
                }
 
                return $this->mEstimateRevisions;
@@ -4040,7 +4060,7 @@ class Title {
                $dbr = wfGetDB( DB_SLAVE );
                return (int)$dbr->selectField( 'revision', 'count(*)',
                        array(
-                               'rev_page' => $this->getArticleId(),
+                               'rev_page' => $this->getArticleID(),
                                'rev_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ),
                                'rev_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $new->getTimestamp() ) )
                        ),
@@ -4114,7 +4134,7 @@ class Title {
         * @return Bool
         */
        public function exists() {
-               return $this->getArticleId() != 0;
+               return $this->getArticleID() != 0;
        }
 
        /**
@@ -4311,9 +4331,10 @@ class Title {
                $dbr = wfGetDB( DB_SLAVE );
                $this->mNotificationTimestamp[$uid] = $dbr->selectField( 'watchlist',
                        'wl_notificationtimestamp',
-                       array( 'wl_namespace' => $this->getNamespace(),
+                       array(
+                               'wl_user' => $user->getId(),
+                               'wl_namespace' => $this->getNamespace(),
                                'wl_title' => $this->getDBkey(),
-                               'wl_user' => $user->getId()
                        ),
                        __METHOD__
                );
@@ -4468,14 +4489,14 @@ class Title {
         * $wgLang (such as special pages, which are in the user language).
         *
         * @since 1.18
-        * @return object Language
+        * @return Language
         */
        public function getPageLanguage() {
                global $wgLang;
                if ( $this->isSpecialPage() ) {
                        // special pages are in the user language
                        return $wgLang;
-               } elseif ( $this->isCssOrJsPage() ) {
+               } elseif ( $this->isCssOrJsPage() || $this->isCssJsSubpage() ) {
                        // css/js should always be LTR and is, in fact, English
                        return wfGetLangObj( 'en' );
                } elseif ( $this->getNamespace() == NS_MEDIAWIKI ) {