Merge "Add and use Title::getOtherPage()"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 25 Dec 2014 15:22:36 +0000 (15:22 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 25 Dec 2014 15:22:36 +0000 (15:22 +0000)
1  2 
includes/Title.php
includes/page/WikiPage.php

diff --combined includes/Title.php
@@@ -747,7 -747,7 +747,7 @@@ class Title 
         * @param string $title The DB key form the title
         * @param string $fragment The link fragment (after the "#")
         * @param string $interwiki The interwiki prefix
 -       * @param boolean $canoncialNamespace If true, use the canonical name for
 +       * @param bool $canoncialNamespace If true, use the canonical name for
         *   $ns instead of the localized version.
         * @return string The prefixed form of the title
         */
         * Is this in a namespace that allows actual pages?
         *
         * @return bool
 -       * @internal note -- uses hardcoded namespace index instead of constants
         */
        public function canExist() {
                return $this->mNamespace >= NS_MAIN;
                }
  
                $result = true;
 -              wfRunHooks( 'TitleIsMovable', array( $this, &$result ) );
 +              Hooks::run( 'TitleIsMovable', array( $this, &$result ) );
                return $result;
        }
  
                #   It's called here again to make sure hook functions can force this
                #   method to return true even outside the MediaWiki namespace.
  
 -              wfRunHooks( 'TitleIsCssOrJsPage', array( $this, &$isCssOrJsPage ), '1.25' );
 +              Hooks::run( 'TitleIsCssOrJsPage', array( $this, &$isCssOrJsPage ), '1.25' );
  
                return $isCssOrJsPage;
        }
                return Title::makeTitle( $subjectNS, $this->getDBkey() );
        }
  
+       /**
+        * Get the other title for this page, if this is a subject page
+        * get the talk page, if it is a subject page get the talk page
+        *
+        * @since 1.25
+        * @throws MWException
+        * @return Title
+        */
+       public function getOtherPage() {
+               if ( $this->isSpecialPage() ) {
+                       throw new MWException( 'Special pages cannot have other pages' );
+               }
+               if ( $this->isTalkPage() ) {
+                       return $this->getSubjectPage();
+               } else {
+                       return $this->getTalkPage();
+               }
+       }
        /**
         * Get the default namespace index, for when there is no namespace
         *
                # Finally, add the fragment.
                $url .= $this->getFragmentForURL();
  
 -              wfRunHooks( 'GetFullURL', array( &$this, &$url, $query ) );
 +              Hooks::run( 'GetFullURL', array( &$this, &$url, $query ) );
                return $url;
        }
  
                        $dbkey = wfUrlencode( $this->getPrefixedDBkey() );
                        if ( $query == '' ) {
                                $url = str_replace( '$1', $dbkey, $wgArticlePath );
 -                              wfRunHooks( 'GetLocalURL::Article', array( &$this, &$url ) );
 +                              Hooks::run( 'GetLocalURL::Article', array( &$this, &$url ) );
                        } else {
                                global $wgVariantArticlePath, $wgActionPaths, $wgContLang;
                                $url = false;
                                }
                        }
  
 -                      wfRunHooks( 'GetLocalURL::Internal', array( &$this, &$url, $query ) );
 +                      Hooks::run( 'GetLocalURL::Internal', array( &$this, &$url, $query ) );
  
                        // @todo FIXME: This causes breakage in various places when we
                        // actually expected a local URL and end up with dupe prefixes.
                                $url = $wgServer . $url;
                        }
                }
 -              wfRunHooks( 'GetLocalURL', array( &$this, &$url, $query ) );
 +              Hooks::run( 'GetLocalURL', array( &$this, &$url, $query ) );
                return $url;
        }
  
                $query = self::fixUrlQueryArgs( $query, $query2 );
                $server = $wgInternalServer !== false ? $wgInternalServer : $wgServer;
                $url = wfExpandUrl( $server . $this->getLocalURL( $query ), PROTO_HTTP );
 -              wfRunHooks( 'GetInternalURL', array( &$this, &$url, $query ) );
 +              Hooks::run( 'GetInternalURL', array( &$this, &$url, $query ) );
                return $url;
        }
  
        public function getCanonicalURL( $query = '', $query2 = false ) {
                $query = self::fixUrlQueryArgs( $query, $query2 );
                $url = wfExpandUrl( $this->getLocalURL( $query ) . $this->getFragmentForURL(), PROTO_CANONICAL );
 -              wfRunHooks( 'GetCanonicalURL', array( &$this, &$url, $query ) );
 +              Hooks::run( 'GetCanonicalURL', array( &$this, &$url, $query ) );
                return $url;
        }
  
        private function checkQuickPermissions( $action, $user, $errors,
                $doExpensiveQueries, $short
        ) {
 -              if ( !wfRunHooks( 'TitleQuickPermissions',
 +              if ( !Hooks::run( 'TitleQuickPermissions',
                        array( $this, $user, $action, &$errors, $doExpensiveQueries, $short ) )
                ) {
                        return $errors;
        private function checkPermissionHooks( $action, $user, $errors, $doExpensiveQueries, $short ) {
                // Use getUserPermissionsErrors instead
                $result = '';
 -              if ( !wfRunHooks( 'userCan', array( &$this, &$user, $action, &$result ) ) ) {
 +              if ( !Hooks::run( 'userCan', array( &$this, &$user, $action, &$result ) ) ) {
                        return $result ? array() : array( array( 'badaccess-group0' ) );
                }
                // Check getUserPermissionsErrors hook
 -              if ( !wfRunHooks( 'getUserPermissionsErrors', array( &$this, &$user, $action, &$result ) ) ) {
 +              if ( !Hooks::run( 'getUserPermissionsErrors', array( &$this, &$user, $action, &$result ) ) ) {
                        $errors = $this->resultToError( $errors, $result );
                }
                // Check getUserPermissionsErrorsExpensive hook
                if (
                        $doExpensiveQueries
                        && !( $short && count( $errors ) > 0 )
 -                      && !wfRunHooks( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) )
 +                      && !Hooks::run( 'getUserPermissionsErrorsExpensive', array( &$this, &$user, $action, &$result ) )
                ) {
                        $errors = $this->resultToError( $errors, $result );
                }
  
                if ( !$whitelisted ) {
                        # If the title is not whitelisted, give extensions a chance to do so...
 -                      wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
 +                      Hooks::run( 'TitleReadWhitelist', array( $this, $user, &$whitelisted ) );
                        if ( !$whitelisted ) {
                                $errors[] = $this->missingPermissionError( $action, $short );
                        }
                        $types = array_diff( $types, array( 'upload' ) );
                }
  
 -              wfRunHooks( 'TitleGetRestrictionTypes', array( $this, &$types ) );
 +              Hooks::run( 'TitleGetRestrictionTypes', array( $this, &$types ) );
  
                wfDebug( __METHOD__ . ': applicable restrictions to [[' .
                        $this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
         * Accessor/initialisation for mRestrictions
         *
         * @param string $action Action that permission needs to be checked for
 -       * @return array Restriction levels needed to take the action. All levels
 -       *     are required.
 +       * @return array Restriction levels needed to take the action. All levels are
 +       *     required. Note that restriction levels are normally user rights, but 'sysop'
 +       *     and 'autoconfirmed' are also allowed for backwards compatibility. These should
 +       *     be mapped to 'editprotected' and 'editsemiprotected' respectively.
         */
        public function getRestrictions( $action ) {
                if ( !$this->mRestrictionsLoaded ) {
                        $urls[] = $this->getInternalUrl( 'action=raw&ctype=text/css' );
                }
  
 -              wfRunHooks( 'TitleSquidURLs', array( $this, &$urls ) );
 +              Hooks::run( 'TitleSquidURLs', array( $this, &$urls ) );
                return $urls;
        }
  
         */
        public function exists() {
                $exists = $this->getArticleID() != 0;
 -              wfRunHooks( 'TitleExists', array( $this, &$exists ) );
 +              Hooks::run( 'TitleExists', array( $this, &$exists ) );
                return $exists;
        }
  
                 * @param Title $title
                 * @param bool|null $isKnown
                 */
 -              wfRunHooks( 'TitleIsAlwaysKnown', array( $this, &$isKnown ) );
 +              Hooks::run( 'TitleIsAlwaysKnown', array( $this, &$isKnown ) );
  
                if ( !is_null( $isKnown ) ) {
                        return $isKnown;
                // on the Title object passed in, and should probably
                // tell the users to run updateCollations.php --force
                // in order to re-sort existing category relations.
 -              wfRunHooks( 'GetDefaultSortkey', array( $this, &$unprefixed ) );
 +              Hooks::run( 'GetDefaultSortkey', array( $this, &$unprefixed ) );
                if ( $prefix !== '' ) {
                        # Separate with a line feed, so the unprefixed part is only used as
                        # a tiebreaker when two pages have the exact same prefix.
                        }
                }
  
 -              wfRunHooks( 'TitleGetEditNotices', array( $this, $oldid, &$notices ) );
 +              Hooks::run( 'TitleGetEditNotices', array( $this, $oldid, &$notices ) );
                return $notices;
        }
  }
@@@ -50,7 -50,7 +50,7 @@@ class WikiPage implements Page, IDBAcce
        public $mLatest = false;             // !< Integer (false means "not loaded")
        /**@}}*/
  
 -      /** @var stdclass Map of cache fields (text, parser output, ect) for a proposed/new edit */
 +      /** @var stdClass Map of cache fields (text, parser output, ect) for a proposed/new edit */
        public $mPreparedEdit = false;
  
        /**
        protected function pageData( $dbr, $conditions, $options = array() ) {
                $fields = self::selectFields();
  
 -              wfRunHooks( 'ArticlePageDataBefore', array( &$this, &$fields ) );
 +              Hooks::run( 'ArticlePageDataBefore', array( &$this, &$fields ) );
  
                $row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__, $options );
  
 -              wfRunHooks( 'ArticlePageDataAfter', array( &$this, &$row ) );
 +              Hooks::run( 'ArticlePageDataAfter', array( &$this, &$row ) );
  
                return $row;
        }
         * @param string|int $from One of the following:
         *        - "fromdb" or WikiPage::READ_NORMAL if the data comes from a slave DB
         *        - "fromdbmaster" or WikiPage::READ_LATEST if the data comes from the master DB
 -       *        - "forupdate"  or WikiPage::READ_LOCKING if the data comes from from
 +       *        - "forupdate"  or WikiPage::READ_LOCKING if the data comes from
         *          the master DB using SELECT FOR UPDATE
         */
        public function loadFromRow( $data, $from ) {
                                $source = $this->mTitle->getFullURL( 'redirect=no' );
                                return $rt->getFullURL( array( 'rdfrom' => $source ) );
                        } else {
 -                              // External pages pages without "local" bit set are not valid
 +                              // External pages without "local" bit set are not valid
                                // redirect targets
                                return false;
                        }
        public function doPurge() {
                global $wgUseSquid;
  
 -              if ( !wfRunHooks( 'ArticlePurge', array( &$this ) ) ) {
 +              if ( !Hooks::run( 'ArticlePurge', array( &$this ) ) ) {
                        return false;
                }
  
                $hook_args = array( &$this, &$user, &$content, &$summary,
                                                        $flags & EDIT_MINOR, null, null, &$flags, &$status );
  
 -              if ( !wfRunHooks( 'PageContentSave', $hook_args )
 +              if ( !Hooks::run( 'PageContentSave', $hook_args )
                        || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args ) ) {
  
                        wfDebug( __METHOD__ . ": ArticleSave or ArticleSaveContent hook aborted save!\n" );
                        $summary = $handler->getAutosummary( $old_content, $content, $flags );
                }
  
 -              $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat, true );
 +              $editInfo = $this->prepareContentForEdit( $content, null, $user, $serialFormat );
                $serialized = $editInfo->pst;
  
                /**
                                                return $status;
                                        }
  
 -                                      wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
 +                                      Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
                                        // Update recentchanges
                                        if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
                                                // Mark as patrolled if the user can do so
                                // Update the page record with revision data
                                $this->updateRevisionOn( $dbw, $revision, 0 );
  
 -                              wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
 +                              Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
  
                                // Update recentchanges
                                if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
                                                                $flags & EDIT_MINOR, null, null, &$flags, $revision );
  
                        ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
 -                      wfRunHooks( 'PageContentInsertComplete', $hook_args );
 +                      Hooks::run( 'PageContentInsertComplete', $hook_args );
                }
  
                // Do updates right now unless deferral was requested
                                                        $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
  
                ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
 -              wfRunHooks( 'PageContentSaveComplete', $hook_args );
 +              Hooks::run( 'PageContentSaveComplete', $hook_args );
  
                // Promote user to any groups they meet the criteria for
                $dbw->onTransactionIdle( function () use ( $user ) {
  
        /**
         * Prepare text which is about to be saved.
 -       * Returns a stdclass with source, pst and output members
 +       * Returns a stdClass with source, pst and output members
         *
         * @deprecated since 1.21: use prepareContentForEdit instead.
         * @return object
  
        /**
         * Prepare content which is about to be saved.
 -       * Returns a stdclass with source, pst and output members
 +       * Returns a stdClass with source, pst and output members
         *
         * @param Content $content
         * @param int|null $revid
         * @since 1.21
         */
        public function prepareContentForEdit(
 -              Content $content, $revid = null, User $user = null, $serialFormat = null, $useCache = false
 +              Content $content, $revid = null, User $user = null, $serialFormat = null, $useCache = true
        ) {
                global $wgContLang, $wgUser;
  
                        : false;
  
                $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
 -              wfRunHooks( 'ArticlePrepareTextForEdit', array( $this, $popts ) );
 +              Hooks::run( 'ArticlePrepareTextForEdit', array( $this, $popts ) );
  
                $edit = (object)array();
                if ( $cachedEdit ) {
                        DataUpdate::runUpdates( $updates );
                }
  
 -              wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
 +              Hooks::run( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
  
 -              if ( wfRunHooks( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
 +              if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
                        if ( 0 == mt_rand( 0, 99 ) ) {
                                // Flush old entries from the `recentchanges` table; we do this on
                                // random requests so as to avoid an increase in writes for no good reason
                                wfDebug( __METHOD__ . ": invalid username\n" );
                        } else {
                                // Allow extensions to prevent user notification when a new message is added to their talk page
 -                              if ( wfRunHooks( 'ArticleEditUpdateNewTalk', array( &$this, $recipient ) ) ) {
 +                              if ( Hooks::run( 'ArticleEditUpdateNewTalk', array( &$this, $recipient ) ) ) {
                                        if ( User::isIP( $shortTitle ) ) {
                                                // An anonymous user
                                                $recipient->setNewtalk( true, $revision );
                $revision->insertOn( $dbw );
                $this->updateRevisionOn( $dbw, $revision );
  
 -              wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
 +              Hooks::run( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );
  
                wfProfileOut( __METHOD__ );
        }
                $logRelationsField = null;
  
                if ( $id ) { // Protection of existing page
 -                      if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
 +                      if ( !Hooks::run( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
                                return Status::newGood();
                        }
  
                                __METHOD__
                        );
  
 -                      wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $user ) );
 -                      wfRunHooks( 'ArticleProtectComplete', array( &$this, &$user, $limit, $reason ) );
 +                      Hooks::run( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $user ) );
 +                      Hooks::run( 'ArticleProtectComplete', array( &$this, &$user, $limit, $reason ) );
                } else { // Protection of non-existing page (also known as "title protection")
                        // Cascade protection is meaningless in this case
                        $cascade = false;
                }
  
                $user = is_null( $user ) ? $wgUser : $user;
 -              if ( !wfRunHooks( 'ArticleDelete', array( &$this, &$user, &$reason, &$error, &$status ) ) ) {
 +              if ( !Hooks::run( 'ArticleDelete', array( &$this, &$user, &$reason, &$error, &$status ) ) ) {
                        if ( $status->isOK() ) {
                                // Hook aborted but didn't set a fatal status
                                $status->fatal( 'delete-hook-aborted' );
  
                $this->doDeleteUpdates( $id, $content );
  
 -              wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) );
 +              Hooks::run( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) );
                $status->value = $logid;
                return $status;
        }
  
                $revId = $status->value['revision']->getId();
  
 -              wfRunHooks( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
 +              Hooks::run( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
  
                $resultDetails = array(
                        'summary' => $summary,
         */
        public static function onArticleCreate( $title ) {
                // Update existence markers on article/talk tabs...
-               if ( $title->isTalkPage() ) {
-                       $other = $title->getSubjectPage();
-               } else {
-                       $other = $title->getTalkPage();
-               }
+               $other = $title->getOtherPage();
  
                $other->invalidateCache();
                $other->purgeSquid();
         */
        public static function onArticleDelete( $title ) {
                // Update existence markers on article/talk tabs...
-               if ( $title->isTalkPage() ) {
-                       $other = $title->getSubjectPage();
-               } else {
-                       $other = $title->getTalkPage();
-               }
+               $other = $title->getOtherPage();
  
                $other->invalidateCache();
                $other->purgeSquid();
  
                                foreach ( $added as $catName ) {
                                        $cat = Category::newFromName( $catName );
 -                                      wfRunHooks( 'CategoryAfterPageAdded', array( $cat, $that ) );
 +                                      Hooks::run( 'CategoryAfterPageAdded', array( $cat, $that ) );
                                }
  
                                foreach ( $deleted as $catName ) {
                                        $cat = Category::newFromName( $catName );
 -                                      wfRunHooks( 'CategoryAfterPageRemoved', array( $cat, $that ) );
 +                                      Hooks::run( 'CategoryAfterPageRemoved', array( $cat, $that ) );
                                }
                        }
                );
                        $updates = $content->getDeletionUpdates( $this );
                }
  
 -              wfRunHooks( 'WikiPageDeletionUpdates', array( $this, $content, &$updates ) );
 +              Hooks::run( 'WikiPageDeletionUpdates', array( $this, $content, &$updates ) );
                return $updates;
        }
  }