MediaWiki master
HTMLRadioField.php
Go to the documentation of this file.
1<?php
2
4
8use Xml;
9
32 public function __construct( $params ) {
33 parent::__construct( $params );
34
35 if ( isset( $params['flatlist'] ) ) {
36 $this->mClass .= ' mw-htmlform-flatlist';
37 }
38 }
39
40 public function validate( $value, $alldata ) {
41 $p = parent::validate( $value, $alldata );
42
43 if ( $p !== true ) {
44 return $p;
45 }
46
47 if ( !is_string( $value ) && !is_int( $value ) ) {
48 return $this->msg( 'htmlform-required' );
49 }
50
51 $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
52
53 if ( in_array( strval( $value ), $validOptions, true ) ) {
54 return true;
55 } else {
56 return $this->msg( 'htmlform-select-badoption' );
57 }
58 }
59
68 public function getInputHTML( $value ) {
69 if (
70 isset( $this->mParams['option-descriptions'] ) ||
71 isset( $this->mParams['option-descriptions-messages'] ) ) {
72 throw new \InvalidArgumentException(
73 "Non-Codex HTMLForms do not support the 'option-descriptions' parameter for radio buttons"
74 );
75 }
76
77 $html = $this->formatOptions( $this->getOptions(), strval( $value ) );
78
79 return $html;
80 }
81
82 public function getInputOOUI( $value ) {
83 if (
84 isset( $this->mParams['option-descriptions'] ) ||
85 isset( $this->mParams['option-descriptions-messages'] ) ) {
86 throw new \InvalidArgumentException(
87 "Non-Codex HTMLForms do not support the 'option-descriptions' parameter for radio buttons"
88 );
89 }
90
91 $options = [];
92 foreach ( $this->getOptions() as $label => $data ) {
93 if ( is_int( $label ) ) {
94 $label = strval( $label );
95 }
96 $options[] = [
97 'data' => $data,
98 // @phan-suppress-next-line SecurityCheck-XSS Labels are raw when not from message
99 'label' => $this->mOptionsLabelsNotFromMessage ? new \OOUI\HtmlSnippet( $label ) : $label,
100 ];
101 }
102
103 return new \OOUI\RadioSelectInputWidget( [
104 'name' => $this->mName,
105 'id' => $this->mID,
106 'value' => $value,
107 'options' => $options,
108 ] + \OOUI\Element::configFromHtmlAttributes(
109 $this->getAttributes( [ 'disabled', 'tabindex' ] )
110 ) );
111 }
112
113 public function getInputCodex( $value, $hasErrors ) {
114 $optionDescriptions = $this->getOptionDescriptions();
115 $html = '';
116
117 // Iterate over an array of options and return the HTML markup.
118 foreach ( $this->getOptions() as $label => $radioValue ) {
119 $description = $optionDescriptions[$radioValue] ?? '';
120 $descriptionID = Sanitizer::escapeIdForAttribute(
121 $this->mID . "-$radioValue-description"
122 );
123
124 // Attributes for the radio input.
125 $radioInputClasses = [ 'cdx-radio__input' ];
126 $radioInputAttribs = [
127 'id' => Sanitizer::escapeIdForAttribute( $this->mID . "-$radioValue" ),
128 'type' => 'radio',
129 'name' => $this->mName,
130 'class' => $radioInputClasses,
131 'value' => $radioValue
132 ];
133 $radioInputAttribs += $this->getAttributes( [ 'disabled', 'tabindex' ] );
134 if ( $description ) {
135 $radioInputAttribs['aria-describedby'] = $descriptionID;
136 }
137
138 // Set the selected value as "checked".
139 if ( $radioValue === $value ) {
140 $radioInputAttribs['checked'] = true;
141 }
142
143 // Attributes for the radio icon.
144 $radioIconClasses = [ 'cdx-radio__icon' ];
145 $radioIconAttribs = [
146 'class' => $radioIconClasses,
147 ];
148
149 // Attributes for the radio label.
150 $radioLabelClasses = [ 'cdx-label__label' ];
151 $radioLabelAttribs = [
152 'class' => $radioLabelClasses,
153 'for' => $radioInputAttribs['id']
154 ];
155
156 // HTML markup for radio input, radio icon, and radio label elements.
157 $radioInput = Html::element( 'input', $radioInputAttribs );
158 $radioIcon = Html::element( 'span', $radioIconAttribs );
159 $radioLabel = $this->mOptionsLabelsNotFromMessage
160 ? Html::rawElement( 'label', $radioLabelAttribs, $label )
161 : Html::element( 'label', $radioLabelAttribs, $label );
162
163 $radioDescription = '';
164 if ( isset( $optionDescriptions[$radioValue] ) ) {
165 $radioDescription = Html::rawElement(
166 'span',
167 [ 'id' => $descriptionID, 'class' => 'cdx-label__description' ],
168 $optionDescriptions[$radioValue]
169 );
170 }
171 $radioLabelWrapper = Html::rawElement(
172 'div',
173 [ 'class' => 'cdx-radio__label cdx-label' ],
174 $radioLabel . $radioDescription
175 );
176
177 // HTML markup for CSS-only Codex Radio.
178 $radio = Html::rawElement(
179 'span',
180 [ 'class' => 'cdx-radio' ],
181 $radioInput . $radioIcon . $radioLabelWrapper
182 );
183
184 // Append the Codex Radio HTML markup to the initialized empty string variable.
185 $html .= $radio;
186 }
187
188 return $html;
189 }
190
191 public function formatOptions( $options, $value ) {
192 $html = '';
193
194 $attribs = $this->getAttributes( [ 'disabled', 'tabindex' ] );
195 $elementFunc = [ Html::class, $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' ];
196
197 # @todo Should this produce an unordered list perhaps?
198 foreach ( $options as $label => $info ) {
199 if ( is_array( $info ) ) {
200 $html .= Html::rawElement( 'h1', [], $label ) . "\n";
201 $html .= $this->formatOptions( $info, $value );
202 } else {
203 $id = Sanitizer::escapeIdForAttribute( $this->mID . "-$info" );
204 $classes = [ 'mw-htmlform-flatlist-item' ];
205 $radio = Xml::radio(
206 $this->mName, $info, $info === $value, $attribs + [ 'id' => $id ]
207 );
208 $radio .= "\u{00A0}" . call_user_func( $elementFunc, 'label', [ 'for' => $id ], $label );
209
210 $html .= ' ' . Html::rawElement(
211 'div',
212 [ 'class' => $classes ],
213 $radio
214 );
215 }
216 }
217
218 return $html;
219 }
220
227 protected function getOptionDescriptions() {
228 if ( array_key_exists( 'option-descriptions-messages', $this->mParams ) ) {
229 $needsParse = $this->mParams['option-descriptions-messages-parse'] ?? false;
230 $optionDescriptions = [];
231 foreach ( $this->mParams['option-descriptions-messages'] as $value => $msgKey ) {
232 $msg = $this->msg( $msgKey );
233 $optionDescriptions[$value] = $needsParse ? $msg->parse() : $msg->escaped();
234 }
235 return $optionDescriptions;
236 } elseif ( array_key_exists( 'option-descriptions', $this->mParams ) ) {
237 return $this->mParams['option-descriptions'];
238 }
239 }
240
241 protected function needsLabel() {
242 return false;
243 }
244}
245
247class_alias( HTMLRadioField::class, 'HTMLRadioField' );
array $params
The job parameters.
needsLabel()
Should this field have a label, or is there no input element with the appropriate id for the label to...
getInputHTML( $value)
This returns a block of all the radio options, in one cell.
getOptionDescriptions()
Fetch the array of option descriptions from the field's parameters.
getInputCodex( $value, $hasErrors)
Same as getInputHTML, but for Codex.
getInputOOUI( $value)
Same as getInputHTML, but returns an OOUI object.
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.
The parent class to generate form fields.
static flattenOptions( $options)
flatten an array of options to a single array, for instance, a set of "<options>" inside "<optgroups>...
getOptions()
Fetch the array of options from the field's parameters.
getAttributes(array $list)
Returns the given attributes from the parameters.
msg( $key,... $params)
Get a translated interface message.
This class is a collection of static functions that serve two purposes:
Definition Html.php:56
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:46
Module of static functions for generating XML.
Definition Xml.php:33
element(SerializerNode $parent, SerializerNode $node, $contents)