Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 131 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
CodexHTMLForm | |
0.00% |
0 / 130 |
|
0.00% |
0 / 9 |
756 | |
0.00% |
0 / 1 |
loadInputFromParameters | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getHTML | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
formatField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFormAttributes | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
wrapForm | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
wrapFieldSetSection | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getLegend | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
42 | |||
formatSection | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
getButtons | |
0.00% |
0 / 69 |
|
0.00% |
0 / 1 |
156 |
1 | <?php |
2 | |
3 | /** |
4 | * HTML form generation using Codex components. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; if not, write to the Free Software Foundation, Inc., |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 | * http://www.gnu.org/copyleft/gpl.html |
20 | * |
21 | * @file |
22 | */ |
23 | |
24 | namespace MediaWiki\HTMLForm; |
25 | |
26 | use MediaWiki\Html\Html; |
27 | use MediaWiki\HTMLForm\Field\HTMLButtonField; |
28 | use MediaWiki\Linker\Linker; |
29 | use MediaWiki\Parser\Sanitizer; |
30 | |
31 | /** |
32 | * Codex based HTML form |
33 | * |
34 | * @since 1.41 |
35 | */ |
36 | class CodexHTMLForm extends HTMLForm { |
37 | |
38 | /** @inheritDoc */ |
39 | protected $displayFormat = 'codex'; |
40 | |
41 | public static function loadInputFromParameters( $fieldname, $descriptor, |
42 | HTMLForm $parent = null |
43 | ) { |
44 | $field = parent::loadInputFromParameters( $fieldname, $descriptor, $parent ); |
45 | $field->setShowEmptyLabel( false ); |
46 | return $field; |
47 | } |
48 | |
49 | public function getHTML( $submitResult ) { |
50 | $this->getOutput()->addModuleStyles( [ |
51 | 'mediawiki.htmlform.codex.styles', |
52 | ] ); |
53 | |
54 | return parent::getHTML( $submitResult ); |
55 | } |
56 | |
57 | /** |
58 | * @inheritDoc |
59 | */ |
60 | protected function formatField( HTMLFormField $field, $value ) { |
61 | return $field->getCodex( $value ); |
62 | } |
63 | |
64 | protected function getFormAttributes() { |
65 | $attribs = parent::getFormAttributes(); |
66 | $attribs['class'] = [ 'mw-htmlform', 'mw-htmlform-codex' ]; |
67 | return $attribs; |
68 | } |
69 | |
70 | public function wrapForm( $html ) { |
71 | return Html::rawElement( 'form', $this->getFormAttributes(), $html ); |
72 | } |
73 | |
74 | protected function wrapFieldSetSection( $legend, $section, $attributes, $isRoot ) { |
75 | $attributes['class'] = 'cdx-field'; |
76 | $legendElement = Html::rawElement( 'legend', [ 'class' => [ 'cdx-label' ] ], $legend ); |
77 | return Html::rawElement( 'fieldset', $attributes, "$legendElement\n$section" ) . "\n"; |
78 | } |
79 | |
80 | /** |
81 | * Note that this method returns HTML, while the parent method specifies that it should return |
82 | * a plain string. This method is only used to get the `$legend` argument of the |
83 | * wrapFieldSetSection() call, so we can be reasonably sure that returning HTML here is okay. |
84 | * |
85 | * @inheritDoc |
86 | */ |
87 | public function getLegend( $key ) { |
88 | $legendText = $this->msg( |
89 | $this->mMessagePrefix ? "{$this->mMessagePrefix}-$key" : $key |
90 | )->text(); |
91 | $legendTextMarkup = Html::element( |
92 | 'span', |
93 | [ 'class' => [ 'cdx-label__label__text' ] ], |
94 | $legendText |
95 | ); |
96 | |
97 | $isOptional = $this->mSections[$key]['optional'] ?? false; |
98 | $optionalFlagMarkup = ''; |
99 | if ( $isOptional ) { |
100 | $optionalFlagMarkup = Html::element( |
101 | 'span', |
102 | [ 'class' => [ 'cdx-label__label__optional-flag' ] ], |
103 | $this->msg( 'word-separator' )->text() . $this->msg( 'htmlform-optional-flag' )->text() |
104 | ); |
105 | } |
106 | |
107 | $descriptionMarkup = ''; |
108 | if ( isset( $this->mSections[$key]['description-message'] ) ) { |
109 | $needsParse = $this->mSections[ $key ][ 'description-message-parse' ] ?? false; |
110 | $descriptionMessage = $this->msg( $this->mSections[ $key ][ 'description-message' ] ); |
111 | $descriptionMarkup = Html::rawElement( |
112 | 'span', |
113 | [ 'class' => [ 'cdx-label__description' ] ], |
114 | $needsParse ? $descriptionMessage->parse() : $descriptionMessage->escaped() |
115 | ); |
116 | } elseif ( isset( $this->mSections[$key]['description'] ) ) { |
117 | $descriptionMarkup = Html::element( |
118 | 'span', |
119 | [ 'class' => [ 'cdx-label__description' ] ], |
120 | $this->mSections[ $key ][ 'description' ] |
121 | ); |
122 | } |
123 | |
124 | return Html::rawElement( |
125 | 'span', |
126 | [ 'class' => [ 'cdx-label__label' ] ], |
127 | $legendTextMarkup . $optionalFlagMarkup |
128 | ) . $descriptionMarkup; |
129 | } |
130 | |
131 | protected function formatSection( array $fieldsHtml, $sectionName, $anyFieldHasLabel ) { |
132 | if ( !$fieldsHtml ) { |
133 | // Do not generate any wrappers for empty sections. Sections may be empty if they only |
134 | // have subsections, but no fields. A legend will still be added in |
135 | // wrapFieldSetSection(). |
136 | return ''; |
137 | } |
138 | |
139 | $html = implode( '', $fieldsHtml ); |
140 | |
141 | if ( $sectionName ) { |
142 | $attribs = [ |
143 | 'id' => Sanitizer::escapeIdForAttribute( $sectionName ), |
144 | 'class' => [ 'cdx-field__control' ] |
145 | ]; |
146 | |
147 | return Html::rawElement( 'div', $attribs, $html ); |
148 | } |
149 | |
150 | return $html; |
151 | } |
152 | |
153 | /** |
154 | * Get the submit and cancel buttons. |
155 | * @stable to override |
156 | * @return string HTML. |
157 | */ |
158 | public function getButtons() { |
159 | $buttons = []; |
160 | |
161 | if ( $this->mShowSubmit ) { |
162 | $value = $this->getSubmitText(); |
163 | // Define flag classes for the submit button |
164 | $submitFlags = $this->mSubmitFlags; |
165 | $submitClasses = [ 'mw-htmlform-submit', 'cdx-button' ]; |
166 | $submitButtonLabel = $this->getSubmitText(); |
167 | $submitID = $this->mSubmitID; |
168 | $submitName = $this->mSubmitName; |
169 | $submitTooltip = []; |
170 | |
171 | if ( isset( $this->mSubmitTooltip ) ) { |
172 | $submitTooltip += Linker::tooltipAndAccesskeyAttribs( $this->mSubmitTooltip ); |
173 | } |
174 | |
175 | $buttonAttribs = [ |
176 | 'value' => $value, |
177 | 'type' => 'submit', |
178 | 'name' => $submitName, |
179 | 'id' => $submitID, |
180 | 'class' => $submitClasses, |
181 | 'formnovalidate' => false, |
182 | ] + $submitTooltip; |
183 | |
184 | $button = HTMLButtonField::buildCodexComponent( |
185 | $submitFlags, |
186 | $submitButtonLabel, |
187 | $buttonAttribs |
188 | ); |
189 | $buttons[] = $button; |
190 | } |
191 | |
192 | // The reset button is unused and will be removed from HTMLForm (T361032). |
193 | |
194 | if ( $this->mShowCancel ) { |
195 | $target = $this->getCancelTargetURL(); |
196 | $buttonClasses = [ |
197 | 'cdx-button', |
198 | 'cdx-button--fake-button', |
199 | 'cdx-button--fake-button--enabled', |
200 | ]; |
201 | $attr = [ |
202 | 'href' => $target, |
203 | 'class' => $buttonClasses, |
204 | 'role' => 'button', |
205 | ]; |
206 | $cancelButton = Html::element( |
207 | 'a', $attr, $this->msg( 'cancel' )->text() |
208 | ); |
209 | $buttons[] = $cancelButton; |
210 | } |
211 | |
212 | foreach ( $this->mButtons as $button ) { |
213 | $attrs = [ |
214 | 'type' => 'submit', |
215 | 'name' => $button['name'], |
216 | 'value' => $button['value'] |
217 | ]; |
218 | |
219 | if ( isset( $button['label-message'] ) ) { |
220 | $label = $this->getMessage( $button['label-message'] )->parse(); |
221 | } elseif ( isset( $button['label'] ) ) { |
222 | $label = htmlspecialchars( $button['label'] ); |
223 | } elseif ( isset( $button['label-raw'] ) ) { |
224 | $label = $button['label-raw']; |
225 | } else { |
226 | $label = htmlspecialchars( $button['value'] ); |
227 | } |
228 | |
229 | // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset Always set in self::addButton |
230 | if ( $button['attribs'] ) { |
231 | // @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset Always set in self::addButton |
232 | $attrs += $button['attribs']; |
233 | } |
234 | |
235 | if ( isset( $button['id'] ) ) { |
236 | $attrs['id'] = $button['id']; |
237 | } |
238 | |
239 | if ( isset( $attrs['class'] ) ) { |
240 | // Ensure $attrs['class'] is always treated as an array whether it's initially set |
241 | // as an array or a string. |
242 | $attrs['class'] = (array)( $attrs['class'] ?? [] ); |
243 | } |
244 | |
245 | $attrs['class'][] = 'cdx-button'; |
246 | |
247 | $buttons[] = Html::rawElement( 'button', $attrs, $label ) . "\n"; |
248 | } |
249 | |
250 | if ( !$buttons ) { |
251 | return ''; |
252 | } |
253 | |
254 | return Html::rawElement( |
255 | 'div', |
256 | [ 'class' => 'mw-htmlform-submit-buttons' ], |
257 | implode( "\n", $buttons ) |
258 | ) . "\n"; |
259 | } |
260 | } |
261 | |
262 | /** @deprecated class alias since 1.42 */ |
263 | class_alias( CodexHTMLForm::class, 'CodexHTMLForm' ); |