diff --git a/includes/htmlform/HTMLForm.php b/includes/htmlform/HTMLForm.php index b68ecbfb60d0..d208b8a56603 100644 --- a/includes/htmlform/HTMLForm.php +++ b/includes/htmlform/HTMLForm.php @@ -427,7 +427,7 @@ public function addFields( $descriptor ) { $this->mFlatFields[$fieldname] = $field; } - $this->mFieldTree = array_merge( $this->mFieldTree, $loadedDescriptor ); + $this->mFieldTree = array_merge_recursive( $this->mFieldTree, $loadedDescriptor ); return $this; } diff --git a/includes/specials/SpecialWhatLinksHere.php b/includes/specials/SpecialWhatLinksHere.php index 082d4870670b..498718bfcfb4 100644 --- a/includes/specials/SpecialWhatLinksHere.php +++ b/includes/specials/SpecialWhatLinksHere.php @@ -35,7 +35,7 @@ * * @ingroup SpecialPage */ -class SpecialWhatLinksHere extends IncludableSpecialPage { +class SpecialWhatLinksHere extends FormSpecialPage { /** @var FormOptions */ protected $opts; @@ -84,6 +84,7 @@ public function __construct( LinksMigration $linksMigration ) { parent::__construct( 'Whatlinkshere' ); + $this->mIncludable = true; $this->loadBalancer = $loadBalancer; $this->linkBatchFactory = $linkBatchFactory; $this->contentHandlerFactory = $contentHandlerFactory; @@ -93,17 +94,24 @@ public function __construct( $this->linksMigration = $linksMigration; } - public function execute( $par ) { - $out = $this->getOutput(); - - $this->setHeaders(); - $this->outputHeader(); - $this->addHelpLink( 'Help:What links here' ); - $out->addModuleStyles( 'mediawiki.special' ); + /** + * Get a better-looking target title from the subpage syntax. + * @param string|null $par + */ + protected function setParameter( $par ) { + if ( $par ) { + // The only difference that subpage syntax can have is the underscore. + $par = str_replace( '_', ' ', $par ); + } + parent::setParameter( $par ); + } + /** + * We want the result displayed after the form, so we use this instead of onSubmit() + */ + public function onSuccess() { $opts = new FormOptions(); - $opts->add( 'target', '' ); $opts->add( 'namespace', '', FormOptions::INTNULL ); $opts->add( 'limit', $this->getConfig()->get( MainConfigNames::QueryPageDefaultLimit ) ); $opts->add( 'offset', '' ); @@ -118,25 +126,12 @@ public function execute( $par ) { $opts->fetchValuesFromRequest( $this->getRequest() ); $opts->validateIntBounds( 'limit', 0, 5000 ); - // Give precedence to subpage syntax - if ( $par !== null ) { - $opts->setValue( 'target', $par ); - } - // Bind to member variable $this->opts = $opts; - $this->target = Title::newFromText( $opts->getValue( 'target' ) ); - if ( !$this->target || !$this->target->canExist() ) { - if ( !$this->including() ) { - $out->addHTML( $this->whatlinkshereForm() ); - } - - return; - } - $this->getSkin()->setRelevantTitle( $this->target ); + $out = $this->getOutput(); $out->setPageTitle( $this->msg( 'whatlinkshere-title', $this->target->getPrefixedText() ) ); $out->addBacklinkSubtitle( $this->target ); @@ -350,8 +345,6 @@ private function showIndirectLinks( && ( $hideimages || !$ilRes->numRows() ) ) { if ( $level == 0 && !$this->including() ) { - $out->addHTML( $this->whatlinkshereForm() ); - if ( $hidelinks || $hidetrans || $hideredirs ) { $msgKey = 'nolinkshere-filter'; } elseif ( is_int( $namespace ) ) { @@ -474,8 +467,6 @@ private function showIndirectLinks( $lb->execute(); if ( $level == 0 && !$this->including() ) { - $out->addHTML( $this->whatlinkshereForm() ); - $link = $this->getLinkRenderer()->makeLink( $this->target, null, @@ -647,18 +638,14 @@ private function getPrevNext( $prevNamespace, $prevPageId, $nextNamespace, $next return $navBuilder->getHtml(); } - private function whatlinkshereForm() { - // We get nicer value from the title object - $this->opts->consumeValue( 'target' ); - $target = $this->target ? $this->target->getPrefixedText() : ''; - $this->opts->consumeValue( 'namespace' ); - $this->opts->consumeValue( 'invert' ); + protected function getFormFields() { + $this->addHelpLink( 'Help:What links here' ); + $this->getOutput()->addModuleStyles( 'mediawiki.special' ); $fields = [ 'target' => [ 'type' => 'title', 'name' => 'target', - 'default' => $target, 'id' => 'mw-whatlinkshere-target', 'label-message' => 'whatlinkshere-page', 'section' => 'whatlinkshere-target', @@ -686,13 +673,9 @@ private function whatlinkshereForm() { ]; $filters = [ 'hidetrans', 'hidelinks', 'hideredirs' ]; - if ( $this->target instanceof Title && - $this->target->getNamespace() == NS_FILE ) { - $filters[] = 'hideimages'; - } // Combined message keys: 'whatlinkshere-hideredirs', 'whatlinkshere-hidetrans', - // 'whatlinkshere-hidelinks', 'whatlinkshere-hideimages' + // 'whatlinkshere-hidelinks' // To be sure they will be found by grep foreach ( $filters as $filter ) { // Parameter only provided for backwards-compatibility with old translations @@ -706,18 +689,51 @@ private function whatlinkshereForm() { ]; } - $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() ) - ->setMethod( 'GET' ) - ->setTitle( $this->getPageTitle() ) - ->setWrapperLegendMsg( 'whatlinkshere' ) - ->setSubmitTextMsg( 'whatlinkshere-submit' ) - // Have a dummy callback for trySubmit() - // TODO: Refactor to fully utilize submit callback - ->setSubmitCallback( static function () { - return true; - } )->prepareForm(); - - return $form->getHTML( $form->trySubmit() ); + return $fields; + } + + protected function alterForm( HTMLForm $form ) { + // This parameter from the subpage syntax is only added after constructing the form, + // so we should add the dynamic field that depends on the user input here. + + // TODO: This looks not good. Ideally we can initialize it in onSubmit(). + // Maybe extend the hide-if feature to match prefixes on the client side. + $this->target = Title::newFromText( $this->getRequest()->getText( 'target' ) ); + if ( $this->target && $this->target->getNamespace() == NS_FILE ) { + $hide = $this->msg( 'hide' )->text(); + $msg = $this->msg( 'whatlinkshere-hideimages', $hide )->text(); + $form->addFields( [ + 'hideimages' => [ + 'type' => 'check', + 'name' => 'hideimages', + 'label' => $msg, + 'section' => 'whatlinkshere-filter', + ] + ] ); + } + + $form->setWrapperLegendMsg( 'whatlinkshere' ) + ->setSubmitTextMsg( 'whatlinkshere-submit' ); + } + + protected function getShowAlways() { + return true; + } + + protected function getSubpageField() { + return 'target'; + } + + public function onSubmit( array $data ) { + return true; + } + + public function requiresPost() { + return false; + } + + protected function getDisplayFormat() { + return 'ooui'; } /**