Skip to content

Commit

Permalink
Refactor SpecialWhatLinksHere to use FormSpecialPage
Browse files Browse the repository at this point in the history
Use cases of HTMLForm should not supply user inputs as the default
value, espacially values that can't pass validations.

Bug: T41126
Change-Id: Ia50b06e12fbe5d47165a73245e695ba75fa4faec
  • Loading branch information
Func86 committed Jan 11, 2023
1 parent 7775d3f commit 4727ed1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 52 deletions.
2 changes: 1 addition & 1 deletion includes/htmlform/HTMLForm.php
Expand Up @@ -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;
}
Expand Down
118 changes: 67 additions & 51 deletions includes/specials/SpecialWhatLinksHere.php
Expand Up @@ -35,7 +35,7 @@
*
* @ingroup SpecialPage
*/
class SpecialWhatLinksHere extends IncludableSpecialPage {
class SpecialWhatLinksHere extends FormSpecialPage {
/** @var FormOptions */
protected $opts;

Expand Down Expand Up @@ -84,6 +84,7 @@ public function __construct(
LinksMigration $linksMigration
) {
parent::__construct( 'Whatlinkshere' );
$this->mIncludable = true;
$this->loadBalancer = $loadBalancer;
$this->linkBatchFactory = $linkBatchFactory;
$this->contentHandlerFactory = $contentHandlerFactory;
Expand All @@ -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', '' );
Expand All @@ -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 );

Expand Down Expand Up @@ -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 ) ) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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
Expand All @@ -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';
}

/**
Expand Down

0 comments on commit 4727ed1

Please sign in to comment.