From 8d4c81e306f5ae675c894fbeecce76fe8ce3037a Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Thu, 8 Jul 2010 10:49:36 +0000 Subject: [PATCH] Followup to r51583: actually use the rd_interwiki and rd_fragment fields, in the spirit of r33133: we now use the redirect table as a cache for redirect targets, no longer pulling the page text from ES for every logged-in redirect view. Old-style redirect table entries with NULL for fragment and interwiki are automatically updated when the redirect is visited or edited. --- includes/Article.php | 63 +++++++++++++++++++++++++++----------------- includes/Title.php | 16 +++++++---- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 3e6b01927e..8bd18edf0f 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -95,13 +95,16 @@ class Article { # Query the redirect table $dbr = wfGetDB( DB_SLAVE ); $row = $dbr->selectRow( 'redirect', - array( 'rd_namespace', 'rd_title' ), + array( 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki' ), array( 'rd_from' => $this->getID() ), __METHOD__ ); - if ( $row ) { - return $this->mRedirectTarget = Title::makeTitle( $row->rd_namespace, $row->rd_title ); + // rd_fragment and rd_interwiki were added later, populate them if empty + if ( $row && !is_null( $row->rd_fragment ) && !is_null( $row->rd_interwiki ) ) { + return $this->mRedirectTarget = Title::makeTitle( + $row->rd_namespace, $row->rd_title, + $row->rd_fragment, $row->rd_interwiki ); } # This page doesn't have an entry in the redirect table @@ -112,36 +115,44 @@ class Article { * Insert an entry for this page into the redirect table. * * Don't call this function directly unless you know what you're doing. - * @return Title object + * @return Title object or null if not a redirect */ public function insertRedirect() { - $retval = Title::newFromRedirect( $this->getContent() ); - + // recurse through to only get the final target + $retval = Title::newFromRedirectRecurse( $this->getContent() ); if ( !$retval ) { return null; } - + $this->insertRedirectEntry( $retval ); + return $retval; + } + + /** + * Insert or update the redirect table entry for this page to indicate + * it redirects to $rt . + * @param $rt Title redirect target + */ + public function insertRedirectEntry( $rt ) { $dbw = wfGetDB( DB_MASTER ); $dbw->replace( 'redirect', array( 'rd_from' ), array( 'rd_from' => $this->getID(), - 'rd_namespace' => $retval->getNamespace(), - 'rd_title' => $retval->getDBkey() + 'rd_namespace' => $rt->getNamespace(), + 'rd_title' => $rt->getDBkey(), + 'rd_fragment' => $rt->getFragment(), + 'rd_interwiki' => $rt->getInterwiki(), ), __METHOD__ ); - - return $retval; } /** - * Get the Title object this page redirects to + * Get the Title object or URL this page redirects to * * @return mixed false, Title of in-wiki target, or string with URL */ public function followRedirect() { - $text = $this->getContent(); - return $this->followRedirectText( $text ); + return $this->getRedirectURL( $this->getRedirectTarget() ); } /** @@ -149,11 +160,21 @@ class Article { * * @param $text string article content containing redirect info * @return mixed false, Title of in-wiki target, or string with URL + * @deprecated */ public function followRedirectText( $text ) { // recurse through to only get the final target - $rt = Title::newFromRedirectRecurse( $text ); - + return $this->getRedirectURL( Title::newFromRedirectRecurse( $text ) ); + } + + /** + * Get the Title object or URL to use for a redirect. We use Title + * objects for same-wiki, non-special redirects and URLs for everything + * else. + * @param $rt Title Redirect target + * @return mixed false, Title object of local target, or string with URL + */ + public function getRedirectURL( $rt ) { if ( $rt ) { if ( $rt->getInterwiki() != '' ) { if ( $rt->isLocal() ) { @@ -1768,7 +1789,7 @@ class Article { wfProfileIn( __METHOD__ ); $text = $revision->getText(); - $rt = Title::newFromRedirect( $text ); + $rt = Title::newFromRedirectRecurse( $text ); $conditions = array( 'page_id' => $this->getId() ); @@ -1821,13 +1842,7 @@ class Article { if ( $isRedirect || is_null( $lastRevIsRedirect ) || $lastRevIsRedirect !== $isRedirect ) { wfProfileIn( __METHOD__ ); if ( $isRedirect ) { - // This title is a redirect, Add/Update row in the redirect table - $set = array( /* SET */ - 'rd_namespace' => $redirectTitle->getNamespace(), - 'rd_title' => $redirectTitle->getDBkey(), - 'rd_from' => $this->getId(), - ); - $dbw->replace( 'redirect', array( 'rd_from' ), $set, __METHOD__ ); + $this->insertRedirectEntry( $redirectTitle ); } else { // This is not a redirect, remove row from redirect table $where = array( 'rd_from' => $this->getId() ); diff --git a/includes/Title.php b/includes/Title.php index 4c7cda9e03..b8daa792f1 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -255,11 +255,12 @@ class Title { * @param $ns \type{\int} the namespace of the article * @param $title \type{\string} the unprefixed database key form * @param $fragment \type{\string} The link fragment (after the "#") + * @param $interwiki \type{\string} The interwiki prefix * @return \type{Title} the new object */ - public static function &makeTitle( $ns, $title, $fragment = '' ) { + public static function &makeTitle( $ns, $title, $fragment = '', $interwiki = '' ) { $t = new Title(); - $t->mInterwiki = ''; + $t->mInterwiki = $interwiki; $t->mFragment = $fragment; $t->mNamespace = $ns = intval( $ns ); $t->mDbkeyform = str_replace( ' ', '_', $title ); @@ -277,11 +278,12 @@ class Title { * @param $ns \type{\int} the namespace of the article * @param $title \type{\string} the database key form * @param $fragment \type{\string} The link fragment (after the "#") + * @param $interwiki \type{\string} The interwiki prefix * @return \type{Title} the new object, or NULL on an error */ - public static function makeTitleSafe( $ns, $title, $fragment = '' ) { + public static function makeTitleSafe( $ns, $title, $fragment = '', $interwiki = '' ) { $t = new Title(); - $t->mDbkeyform = Title::makeName( $ns, $title, $fragment ); + $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki ); if ( $t->secureAndSplit() ) { return $t; } else { @@ -473,13 +475,17 @@ class Title { * @param $ns \type{\int} numerical representation of the namespace * @param $title \type{\string} the DB key form the title * @param $fragment \type{\string} The link fragment (after the "#") + * @param $interwiki \type{\string} The interwiki prefix * @return \type{\string} the prefixed form of the title */ - public static function makeName( $ns, $title, $fragment = '' ) { + public static function makeName( $ns, $title, $fragment = '', $interwiki = '' ) { global $wgContLang; $namespace = $wgContLang->getNsText( $ns ); $name = $namespace == '' ? $title : "$namespace:$title"; + if ( strval( $interwiki ) != '' ) { + $name = "$interwiki:$name"; + } if ( strval( $fragment ) != '' ) { $name .= '#' . $fragment; } -- 2.20.1