diff options
author | SomeRandomDeveloper <thisisnotmyname275@gmail.com> | 2024-11-12 20:55:39 +0100 |
---|---|---|
committer | SomeRandomDeveloper <thisisnotmyname275@gmail.com> | 2025-01-17 22:11:56 +0100 |
commit | 7dea105e52f286b163b599d4db2eb9f0629260ae (patch) | |
tree | 56bcbf7f44c5e01fea2cf472b3a8e04a1953e3d6 /includes/editpage | |
parent | 467c2d4f8065b016575963db3b65a5fc8aadf84e (diff) | |
download | mediawikicore-7dea105e52f286b163b599d4db2eb9f0629260ae.tar.gz mediawikicore-7dea105e52f286b163b599d4db2eb9f0629260ae.zip |
Add a warning when trying to create a double redirect
Shows a warning when trying to create a redirect that points to another
redirect.
Bug: T326056
Change-Id: Ieb51dde88ce6c23753f74191a85cd40f0bfbd864
Diffstat (limited to 'includes/editpage')
-rw-r--r-- | includes/editpage/Constraint/DoubleRedirectConstraint.php | 104 | ||||
-rw-r--r-- | includes/editpage/EditPage.php | 44 | ||||
-rw-r--r-- | includes/editpage/IEditObject.php | 3 |
3 files changed, 151 insertions, 0 deletions
diff --git a/includes/editpage/Constraint/DoubleRedirectConstraint.php b/includes/editpage/Constraint/DoubleRedirectConstraint.php new file mode 100644 index 000000000000..fd5ee1ab04cc --- /dev/null +++ b/includes/editpage/Constraint/DoubleRedirectConstraint.php @@ -0,0 +1,104 @@ +<?php +/** + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ + +namespace MediaWiki\EditPage\Constraint; + +use MediaWiki\Content\Content; +use MediaWiki\Linker\LinkTarget; +use MediaWiki\Page\RedirectLookup; +use MediaWiki\Title\Title; +use StatusValue; + +/** + * Verify the page does not redirect to another redirect unless + * - the user is okay with a double redirect, or + * - the page already redirected to another redirect before the edit + * + * @since 1.44 + * @internal + */ +class DoubleRedirectConstraint implements IEditConstraint { + + private bool $allowDoubleRedirects; + private Content $newContent; + private Content $originalContent; + private LinkTarget $title; + private string $result; + private RedirectLookup $redirectLookup; + + /** + * @param bool $allowDoubleRedirects + * @param Content $newContent + * @param Content $originalContent + * @param LinkTarget $title + */ + public function __construct( + bool $allowDoubleRedirects, + Content $newContent, + Content $originalContent, + LinkTarget $title, + RedirectLookup $redirectLookup + ) { + $this->allowDoubleRedirects = $allowDoubleRedirects; + $this->newContent = $newContent; + $this->originalContent = $originalContent; + $this->title = $title; + $this->redirectLookup = $redirectLookup; + } + + public function checkConstraint(): string { + if ( !$this->allowDoubleRedirects ) { + $newRedirectTarget = $this->newContent->getRedirectTarget(); + + if ( $newRedirectTarget !== null && $newRedirectTarget->isRedirect() && + !$newRedirectTarget->equals( $this->title ) ) { + + $currentTarget = $this->originalContent->getRedirectTarget(); + + // fail if there was no previous content or the previous content already contained a double redirect + if ( !$currentTarget || !$currentTarget->isRedirect() ) { + $this->result = self::CONSTRAINT_FAILED; + + return self::CONSTRAINT_FAILED; + } + } + } + $this->result = self::CONSTRAINT_PASSED; + + return self::CONSTRAINT_PASSED; + } + + public function getLegacyStatus(): StatusValue { + $statusValue = StatusValue::newGood(); + if ( $this->result === self::CONSTRAINT_FAILED ) { + $realRedirectTarget = $this->redirectLookup->getRedirectTarget( $this->newContent->getRedirectTarget() ); + $realTargetTitle = Title::castFromLinkTarget( $realRedirectTarget ); + + $statusValue->fatal( + 'edit-constraint-doubleredirect', + wfEscapeWikiText( $realTargetTitle->getPrefixedText() ) + ); + $statusValue->value = self::AS_DOUBLE_REDIRECT; + } + + return $statusValue; + } + +} diff --git a/includes/editpage/EditPage.php b/includes/editpage/EditPage.php index d492ce5a0b3c..b853e5d18067 100644 --- a/includes/editpage/EditPage.php +++ b/includes/editpage/EditPage.php @@ -45,6 +45,7 @@ use MediaWiki\EditPage\Constraint\BrokenRedirectConstraint; use MediaWiki\EditPage\Constraint\ChangeTagsConstraint; use MediaWiki\EditPage\Constraint\ContentModelChangeConstraint; use MediaWiki\EditPage\Constraint\DefaultTextConstraint; +use MediaWiki\EditPage\Constraint\DoubleRedirectConstraint; use MediaWiki\EditPage\Constraint\EditConstraintFactory; use MediaWiki\EditPage\Constraint\EditConstraintRunner; use MediaWiki\EditPage\Constraint\EditFilterMergedContentHookConstraint; @@ -269,6 +270,12 @@ class EditPage implements IEditObject { /** @var bool */ private $allowBrokenRedirects = false; + /** @var bool */ + private $doubleRedirect = false; + + /** @var bool */ + private $allowDoubleRedirects = false; + /** @var string */ private $autoSumm = ''; @@ -1327,6 +1334,7 @@ class EditPage implements IEditObject { $this->allowBlankArticle = $request->getBool( 'wpIgnoreBlankArticle' ); $this->allowSelfRedirect = $request->getBool( 'wpIgnoreSelfRedirect' ); $this->allowBrokenRedirects = $request->getBool( 'wpIgnoreBrokenRedirects' ); + $this->allowDoubleRedirects = $request->getBool( 'wpIgnoreDoubleRedirects' ); $changeTags = $request->getVal( 'wpChangeTags' ); if ( $changeTags === null || $changeTags === '' ) { @@ -1860,6 +1868,7 @@ class EditPage implements IEditObject { case self::AS_BLANK_ARTICLE: case self::AS_SELF_REDIRECT: case self::AS_BROKEN_REDIRECT: + case self::AS_DOUBLE_REDIRECT: case self::AS_REVISION_WAS_DELETED: return true; @@ -2498,6 +2507,15 @@ class EditPage implements IEditObject { ) ); $constraintRunner->addConstraint( + new DoubleRedirectConstraint( + $this->allowDoubleRedirects, + $content, + $this->getCurrentContent(), + $this->getTitle(), + $this->redirectLookup + ) + ); + $constraintRunner->addConstraint( // Same constraint is used to check size before and after merging the // edits, which use different failure codes $constraintFactory->newPageSizeConstraint( @@ -2619,6 +2637,8 @@ class EditPage implements IEditObject { $this->selfRedirect = true; } elseif ( $failed instanceof BrokenRedirectConstraint ) { $this->brokenRedirect = true; + } elseif ( $failed instanceof DoubleRedirectConstraint ) { + $this->doubleRedirect = true; } } @@ -3154,6 +3174,10 @@ class EditPage implements IEditObject { $out->addHTML( Html::hidden( 'wpIgnoreBrokenRedirects', true ) ); } + if ( $this->doubleRedirect ) { + $out->addHTML( Html::hidden( 'wpIgnoreDoubleRedirects', true ) ); + } + $autosumm = $this->autoSumm !== '' ? $this->autoSumm : md5( $this->summary ); $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) ); @@ -3374,6 +3398,26 @@ class EditPage implements IEditObject { ); } + if ( $this->doubleRedirect ) { + $editContent = $this->toEditContent( $this->textbox1 ); + $redirectTarget = $editContent->getRedirectTarget(); + + $doubleRedirectTarget = $this->redirectLookup->getRedirectTarget( $redirectTarget ); + $doubleRedirectTargetTitle = Title::castFromLinkTarget( $doubleRedirectTarget ); + + $suggestedRedirectContent = + $editContent->getContentHandler()->makeRedirectContent( $doubleRedirectTargetTitle ); + $suggestedRedirectCode = + Html::element( 'pre', [], $this->toEditText( $suggestedRedirectContent ) ); + + $out->wrapWikiMsg( "<div id='mw-doubleredirect'>\n$1\n</div>", [ + 'edit-constraint-doubleredirect', + $buttonLabel, + wfEscapeWikiText( $doubleRedirectTargetTitle->getPrefixedText() ), + $suggestedRedirectCode, + ] ); + } + if ( $this->hookError !== '' ) { $out->addWikiTextAsInterface( $this->hookError ); } diff --git a/includes/editpage/IEditObject.php b/includes/editpage/IEditObject.php index 102377fcacf2..873f69f810ad 100644 --- a/includes/editpage/IEditObject.php +++ b/includes/editpage/IEditObject.php @@ -120,4 +120,7 @@ interface IEditObject { /** Status: user tried to create a redirect to a nonexistent page and wpIgnoreBrokenRedirects is false */ public const AS_BROKEN_REDIRECT = 244; + + /** Status: user tried to create a redirect to another redirect and wpIgnoreDoubleRedirects is false */ + public const AS_DOUBLE_REDIRECT = 245; } |