1<?php
2
3namespace Vector\HTMLForm\Fields;
4
5use Vector\Constants;
6use Wikimedia\Assert\Assert;
7
8/**
9 * The field on Special:Preferences (and Special:GlobalPreferences) that allows the user to
10 * enable/disable the legacy version of the Vector skin. Per
11 * https://phabricator.wikimedia.org/T242381, the field is a checkbox, that, when checked, enables
12 * the legacy version of the Vector skin.
13 *
14 * `HTMLLegacySkinVersionField` adapts the boolean storage type of a checkbox field to the string
15 * storage type of the Vector skin version preference (e.g. see `Constants::SKIN_VERSION_LEGACY`).
16 *
17 * However, we cannot extend `HTMLCheckField` to inherit the behavior of a checkbox field.
18 * `HTMLCheckField::loadDataFromRequest` returns boolean values. Returning non-boolean values in
19 * `HTMLLegacySkinVersionField::loadDataFromRequest` would violate Liskov's Substitution Principle.
20 * Like `HTMLExpiryField`, `HTMLLegacySkinVersionField` proxies to a private instance of
21 * `HTMLCheckField`, adapting parameter and return values where necessary.
22 *
23 * @package Vector\HTMLForm\Fields
24 * @internal
25 */
26final class HTMLLegacySkinVersionField extends \HTMLFormField {
27
28	/**
29	 * @var \HTMLCheckField
30	 */
31	private $checkField;
32
33	/**
34	 * @inheritDoc
35	 */
36	public function __construct( $params ) {
37		Assert::precondition(
38			is_bool( $params['default'] ),
39			'The "default" param must be a boolean.'
40		);
41
42		parent::__construct( $params );
43
44		$this->checkField = new \HTMLCheckField( $params );
45	}
46
47	// BEGIN ADAPTER
48
49	/** @inheritDoc */
50	public function getInputHTML( $value ) {
51		return $this->checkField->getInputHTML( $value === Constants::SKIN_VERSION_LEGACY );
52	}
53
54	/** @inheritDoc */
55	public function getInputOOUI( $value ) {
56		return $this->checkField->getInputOOUI( (string)( $value === Constants::SKIN_VERSION_LEGACY ) );
57	}
58
59	/**
60	 * @inheritDoc
61	 *
62	 * @return string If the checkbox is checked, then `Constants::SKIN_VERSION_LEGACY`;
63	 *  `Constants::SKIN_VERSION_LATEST` otherwise
64	 */
65	public function loadDataFromRequest( $request ) {
66		return $this->checkField->loadDataFromRequest( $request )
67			? Constants::SKIN_VERSION_LEGACY
68			: Constants::SKIN_VERSION_LATEST;
69	}
70
71	// END ADAPTER
72
73	/** @inheritDoc */
74	public function getLabel() {
75		return $this->checkField->getLabel();
76	}
77
78	// Note well that we can't invoke the following methods of `HTMLCheckField` directly because
79	// they're protected and `HTMLSkinVectorField` doesn't extend `HTMLCheckField`.
80
81	/** @inheritDoc */
82	protected function getLabelAlignOOUI() {
83		// See \HTMLCheckField::getLabelAlignOOUI
84		return 'inline';
85	}
86
87	/** @inheritDoc */
88	protected function needsLabel() {
89		// See \HTMLCheckField::needsLabel
90		return false;
91	}
92}
93