From faac3746a2573cf646c0dcb60a801f4f31e01654 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 21 Aug 2012 17:32:44 +0200 Subject: [PATCH] Updating of redirect target in Content objects Content::updateRedirect may be used to change the redirect target without knowing anything about the content's format. Change-Id: Ifaf8f2bdd9d1cbf984e2ef3c60d0282c984c18c1 --- includes/Content.php | 54 +++++++++++++++++++ includes/job/DoubleRedirectJob.php | 14 ++--- .../includes/JavascriptContentTest.php | 9 ++++ .../phpunit/includes/WikitextContentTest.php | 19 +++++++ 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/includes/Content.php b/includes/Content.php index 38d2e275b3..f795462d62 100644 --- a/includes/Content.php +++ b/includes/Content.php @@ -329,6 +329,18 @@ interface Content { */ public function isRedirect(); + /** + * If this Content object is a redirect, this method updates the redirect target. + * Otherwise, it does nothing. + * + * @since WD.1 + * + * @param Title $target the new redirect target + * + * @return Content a new Content object with the updated redirect (or $this if this Content object isn't a redirect) + */ + public function updateRedirect( Title $target ); + /** * Returns the section with the given ID. * @@ -684,6 +696,8 @@ abstract class AbstractContent implements Content { } /** + * @see Content::isRedirect() + * * @since WD.1 * * @return bool @@ -692,6 +706,19 @@ abstract class AbstractContent implements Content { return $this->getRedirectTarget() !== null; } + /** + * @see Content::updateRedirect() + * + * This default implementation always returns $this. + * + * @since WD.1 + * + * @return Content $this + */ + public function updateRedirect( Title $target ) { + return $this; + } + /** * @see Content::getSection() */ @@ -1108,6 +1135,33 @@ class WikitextContent extends TextContent { return null; } + /** + * @see Content::updateRedirect() + * + * This implementation replaces the first link on the page with the given new target + * if this Content object is a redirect. Otherwise, this method returns $this. + * + * @since WD.1 + * + * @param Title $target + * + * @return Content a new Content object with the updated redirect (or $this if this Content object isn't a redirect) + */ + public function updateRedirect( Title $target ) { + if ( !$this->isRedirect() ) { + return $this; + } + + # Fix the text + # Remember that redirect pages can have categories, templates, etc., + # so the regex has to be fairly general + $newText = preg_replace( '/ \[ \[ [^\]]* \] \] /x', + '[[' . $target->getFullText() . ']]', + $this->getNativeData(), 1 ); + + return new WikitextContent( $newText ); + } + /** * Returns true if this content is not a redirect, and this content's text * is countable according to the criteria defined by $wgArticleCountMethod. diff --git a/includes/job/DoubleRedirectJob.php b/includes/job/DoubleRedirectJob.php index 7acc4f28c4..11a4b984f2 100644 --- a/includes/job/DoubleRedirectJob.php +++ b/includes/job/DoubleRedirectJob.php @@ -127,14 +127,10 @@ class DoubleRedirectJob extends Job { $text = ContentHandler::getContentText( $content ); #FIXME: get rid of this! # Fix the text - # Remember that redirect pages can have categories, templates, etc., - # so the regex has to be fairly general - $newText = preg_replace( '/ \[ \[ [^\]]* \] \] /x', - '[[' . $newTitle->getFullText() . ']]', - $text, 1 ); #FIXME: need a way to do this via ContentHandler! - - if ( $newText === $text ) { - $this->setLastError( 'Text unchanged???' ); + $newContent = $content->updateRedirect( $newTitle ); + + if ( $newContent->equals( $content ) ) { + $this->setLastError( 'Content unchanged???' ); return false; } @@ -146,7 +142,7 @@ class DoubleRedirectJob extends Job { $reason = wfMessage( 'double-redirect-fixed-' . $this->reason, $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText() )->inContentLanguage()->text(); - $article->doEdit( $newText, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC, false, $this->getUser() ); + $article->doEditContent( $newContent, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC, false, $this->getUser() ); $wgUser = $oldUser; return true; diff --git a/tests/phpunit/includes/JavascriptContentTest.php b/tests/phpunit/includes/JavascriptContentTest.php index 84cde8cfbb..da03d62cf8 100644 --- a/tests/phpunit/includes/JavascriptContentTest.php +++ b/tests/phpunit/includes/JavascriptContentTest.php @@ -221,6 +221,15 @@ class JavascriptContentTest extends WikitextContentTest { $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word, since it's not wikitext" ); } + public function testUpdateRedirect( ) { + $target = Title::newFromText( "testUpdateRedirect_target" ); + + $content = $this->newContent( "#REDIRECT [[Someplace]]" ); + $newContent = $content->updateRedirect( $target ); + + $this->assertTrue( $content->equals( $newContent ), "content should be unchanged since it's not wikitext" ); + } + # ================================================================================================================= public function testGetModel() { diff --git a/tests/phpunit/includes/WikitextContentTest.php b/tests/phpunit/includes/WikitextContentTest.php index 602a9a2c75..449423b114 100644 --- a/tests/phpunit/includes/WikitextContentTest.php +++ b/tests/phpunit/includes/WikitextContentTest.php @@ -429,6 +429,25 @@ just a test" $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" ); } + public function testUpdateRedirect( ) { + $target = Title::newFromText( "testUpdateRedirect_target" ); + + // test with non-redirect page + $content = $this->newContent( "hello world." ); + $newContent = $content->updateRedirect( $target ); + + $this->assertTrue( $content->equals( $newContent ), "content should be unchanged" ); + + // test with actual redirect + $content = $this->newContent( "#REDIRECT [[Someplace]]" ); + $newContent = $content->updateRedirect( $target ); + + $this->assertFalse( $content->equals( $newContent ), "content should have changed" ); + $this->assertTrue( $newContent->isRedirect(), "new content should be a redirect" ); + + $this->assertEquals( $target->getFullText(), $newContent->getRedirectTarget()->getFullText() ); + } + # ================================================================================================================= public function testGetModel() { -- 2.20.1