mediawiki-skins-Vector/includes/HTMLForm/Fields/HTMLLegacySkinVersionField.php
MusikAnimal 5207a15b91 HTMLLegacySkinVersionField: accept string 'default' value
After I628435a4a, we were asserting a boolean was given because we're
extending HTMLFormField which requires a boolean value. This was safe
because GlobalPrefs would provide a boolean, but that changed with
I594f6297.

We could rework GlobalPrefs once again to ensure only a boolean is
passed in, but since HTMLLegacySkinVersionField already has special
handling around the data types, it seems to make sense to contain the
type transformation in this class.

Simply removing the Assertion is enough to prevent T296068, however
depending on when the global preference was saved (such as since MW
1.38.0-wmf.9 but before wmf.10), it's possible either a bool or a string
was saved, hence we check for both to ensure correct display.

Bug: T296068
Change-Id: If10b948617d2bb8346475f207fe425fb768cb987
2021-11-23 00:57:25 -05:00

95 lines
2.8 KiB
PHP

<?php
namespace Vector\HTMLForm\Fields;
use Vector\Constants;
/**
* The field on Special:Preferences (and Special:GlobalPreferences) that allows the user to
* enable/disable the legacy version of the Vector skin. Per
* https://phabricator.wikimedia.org/T242381, the field is a checkbox, that, when checked, enables
* the legacy version of the Vector skin.
*
* `HTMLLegacySkinVersionField` adapts the boolean storage type of a checkbox field to the string
* storage type of the Vector skin version preference (e.g. see `Constants::SKIN_VERSION_LEGACY`).
*
* However, we cannot extend `HTMLCheckField` to inherit the behavior of a checkbox field.
* `HTMLCheckField::loadDataFromRequest` returns boolean values. Returning non-boolean values in
* `HTMLLegacySkinVersionField::loadDataFromRequest` would violate Liskov's Substitution Principle.
* Like `HTMLExpiryField`, `HTMLLegacySkinVersionField` proxies to a private instance of
* `HTMLCheckField`, adapting parameter and return values where necessary.
*
* @package Vector\HTMLForm\Fields
* @internal
*/
final class HTMLLegacySkinVersionField extends \HTMLFormField {
/**
* @var \HTMLCheckField
*/
private $checkField;
/**
* @inheritDoc
*/
public function __construct( $params ) {
/**
* HTMLCheckField must be given a boolean as the 'default' value.
* Since MW 1.38.0-wmf.9, we could be given a boolean or a string.
* @see T296068
*/
$params['default'] = $params['default'] === true ||
$params['default'] === Constants::SKIN_VERSION_LEGACY;
parent::__construct( $params );
$this->checkField = new \HTMLCheckField( $params );
}
// BEGIN ADAPTER
/** @inheritDoc */
public function getInputHTML( $value ) {
return $this->checkField->getInputHTML( $value === Constants::SKIN_VERSION_LEGACY );
}
/** @inheritDoc */
public function getInputOOUI( $value ) {
return $this->checkField->getInputOOUI( (string)( $value === Constants::SKIN_VERSION_LEGACY ) );
}
/**
* @inheritDoc
*
* @return string If the checkbox is checked, then `Constants::SKIN_VERSION_LEGACY`;
* `Constants::SKIN_VERSION_LATEST` otherwise
*/
public function loadDataFromRequest( $request ) {
return $this->checkField->loadDataFromRequest( $request )
? Constants::SKIN_VERSION_LEGACY
: Constants::SKIN_VERSION_LATEST;
}
// END ADAPTER
/** @inheritDoc */
public function getLabel() {
return $this->checkField->getLabel();
}
// Note well that we can't invoke the following methods of `HTMLCheckField` directly because
// they're protected and `HTMLSkinVectorField` doesn't extend `HTMLCheckField`.
/** @inheritDoc */
protected function getLabelAlignOOUI() {
// See \HTMLCheckField::getLabelAlignOOUI
return 'inline';
}
/** @inheritDoc */
protected function needsLabel() {
// See \HTMLCheckField::needsLabel
return false;
}
}