13use InvalidArgumentException;
17use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
196 use ProtectedHookAccessorTrait;
200'api' => HTMLApiField::class,
201'text' => HTMLTextField::class,
202'textwithbutton' => HTMLTextFieldWithButton::class,
203'textarea' => HTMLTextAreaField::class,
204'select' => HTMLSelectField::class,
205'combobox' => HTMLComboboxField::class,
206'radio' => HTMLRadioField::class,
207'multiselect' => HTMLMultiSelectField::class,
208'limitselect' => HTMLSelectLimitField::class,
209'check' => HTMLCheckField::class,
210'toggle' => HTMLCheckField::class,
211'int' => HTMLIntField::class,
212'file' => HTMLFileField::class,
213'float' => HTMLFloatField::class,
214'info' => HTMLInfoField::class,
215'selectorother' => HTMLSelectOrOtherField::class,
216'selectandother' => HTMLSelectAndOtherField::class,
217'namespaceselect' => HTMLSelectNamespace::class,
218'namespaceselectwithbutton' => HTMLSelectNamespaceWithButton::class,
219'tagfilter' => HTMLTagFilter::class,
220'sizefilter' => HTMLSizeFilterField::class,
221'submit' => HTMLSubmitField::class,
222'hidden' => HTMLHiddenField::class,
223'edittools' => HTMLEditTools::class,
224'checkmatrix' => HTMLCheckMatrix::class,
225'cloner' => HTMLFormFieldCloner::class,
226'autocompleteselect' => HTMLAutoCompleteSelectField::class,
227'language' => HTMLSelectLanguageField::class,
228'date' => HTMLDateTimeField::class,
229'time' => HTMLDateTimeField::class,
230'datetime' => HTMLDateTimeField::class,
231'expiry' => HTMLExpiryField::class,
232'timezone' => HTMLTimezoneField::class,
233// HTMLTextField will output the correct type="" attribute automagically. 234// There are about four zillion other HTML5 input types, like range, but 235// we don't use those at the moment, so no point in adding all of them. 236'email' => HTMLTextField::class,
237'password' => HTMLTextField::class,
238'url' => HTMLTextField::class,
239'title' => HTMLTitleTextField::class,
240'user' => HTMLUserTextField::class,
241'tagmultiselect' => HTMLTagMultiselectField::class,
242'orderedmultiselect' => HTMLOrderedMultiselectField::class,
243'usersmultiselect' => HTMLUsersMultiselectField::class,
244'titlesmultiselect' => HTMLTitlesMultiselectField::class,
245'namespacesmultiselect' => HTMLNamespacesMultiselectField::class,
414'vform',
// deprecated since 1.45 423private $hiddenTitleAddedToForm =
false;
443returnnewCodexHTMLForm( $descriptor, $context, $messagePrefix );
445wfDeprecatedMsg(
"'vform' HTMLForm display format is deprecated",
'1.45' );
446returnnewVFormHTMLForm( $descriptor, $context, $messagePrefix );
448returnnewOOUIHTMLForm( $descriptor, $context, $messagePrefix );
450 $form =
newself( $descriptor, $context, $messagePrefix );
471 $this->mMessagePrefix = $messagePrefix;
485 $loadedDescriptor = [];
487foreach ( $descriptor as $fieldname => $info ) {
488 $section = $info[
'section'] ??
'';
490if ( isset( $info[
'type'] ) && $info[
'type'] ===
'file' ) {
491 $this->mUseMultipart =
true;
494 $field = static::loadInputFromParameters( $fieldname, $info, $this );
496 $setSection =& $loadedDescriptor;
498foreach ( explode(
'/', $section ) as $newName ) {
499 $setSection[$newName] ??= [];
500 $setSection =& $setSection[$newName];
504 $setSection[$fieldname] = $field;
505 $this->mFlatFields[$fieldname] = $field;
508 $this->mFieldTree = array_merge_recursive( $this->mFieldTree, $loadedDescriptor );
518return isset( $this->mFlatFields[$fieldname] );
527if ( !$this->
hasField( $fieldname ) ) {
528thrownew DomainException( __METHOD__ .
': no field named ' . $fieldname );
530return $this->mFlatFields[$fieldname];
544 in_array( $format, $this->availableSubclassDisplayFormats,
true ) ||
545 in_array( $this->displayFormat, $this->availableSubclassDisplayFormats,
true )
547thrownew LogicException(
'Cannot change display format after creation, ' .
548'use HTMLForm::factory() instead' );
551if ( !in_array( $format, $this->availableDisplayFormats,
true ) ) {
552thrownew InvalidArgumentException(
'Display format must be one of ' .
555 $this->availableDisplayFormats,
556 $this->availableSubclassDisplayFormats
562 $this->displayFormat = $format;
593if ( isset( $descriptor[
'class'] ) ) {
594 $class = $descriptor[
'class'];
595 } elseif ( isset( $descriptor[
'type'] ) ) {
596 $class = static::$typeMappings[$descriptor[
'type']];
597 $descriptor[
'class'] = $class;
603thrownew InvalidArgumentException(
"Descriptor with no class for $fieldname: " 604 . print_r( $descriptor,
true ) );
625 $class = static::getClassFromDescriptor( $fieldname, $descriptor );
627 $descriptor[
'fieldname'] = $fieldname;
629 $descriptor[
'parent'] = $parent;
632 # @todo This will throw a fatal error whenever someone try to use 633 # 'class' to feed a CSS class instead of 'cssclass'. Would be 634 # great to avoid the fatal error and show a nice error. 635returnnew $class( $descriptor );
647 # Load data from the request. 649 $this->mFormIdentifier ===
null ||
650 $this->
getRequest()->getVal(
'wpFormIdentifier' ) === $this->mFormIdentifier ||
651 ( $this->mSingleForm && $this->
getMethod() ===
'get' )
655 $this->mFieldData = [];
668if ( $this->mFormIdentifier ===
null ) {
676 $tokenOkay =
true;
// no session check needed 677 } elseif ( $this->
getRequest()->wasPosted() ) {
678 $editToken = $this->
getRequest()->getVal(
'wpEditToken' );
679if ( $this->
getUser()->isRegistered() || $editToken !==
null ) {
680// Session tokens for logged-out users have no security value. 681// However, if the user gave one, check it in order to give a nice 682// "session expired" error instead of "permission denied" or such. 684 CsrfTokenSet::DEFAULT_FIELD_NAME, $this->mTokenSalt
691if ( $tokenOkay && $identOkay ) {
692 $this->mWasSubmitted =
true;
710if ( $result ===
true || ( $result instanceof
Status && $result->
isGood() ) ) {
747 $hoistedErrors = Status::newGood();
748if ( $this->mValidationErrorMessage ) {
749foreach ( $this->mValidationErrorMessage as $error ) {
750 $hoistedErrors->fatal( ...$error );
753 $hoistedErrors->fatal(
'htmlform-invalid-input' );
756 $this->mWasSubmitted =
true;
758 # Check for cancelled submission 759foreach ( $this->mFlatFields as $fieldname => $field ) {
760if ( !array_key_exists( $fieldname, $this->mFieldData ) ) {
763if ( $field->cancelSubmit( $this->mFieldData[$fieldname], $this->mFieldData ) ) {
764 $this->mWasSubmitted =
false;
769 # Check for validation 770 $hasNonDefault =
false;
771foreach ( $this->mFlatFields as $fieldname => $field ) {
772if ( !array_key_exists( $fieldname, $this->mFieldData ) ) {
775 $hasNonDefault = $hasNonDefault || $this->mFieldData[$fieldname] !== $field->getDefault();
776if ( $field->isDisabled( $this->mFieldData ) ) {
779 $res = $field->validate( $this->mFieldData[$fieldname], $this->mFieldData );
782if ( $res !==
false && !$field->canDisplayErrors() ) {
783if ( is_string( $res ) ) {
784 $hoistedErrors->fatal(
'rawmessage', $res );
786 $hoistedErrors->fatal( $res );
793// Treat as not submitted if got nothing from the user on GET forms. 794if ( !$hasNonDefault && $this->
getMethod() ===
'get' &&
795 ( $this->mFormIdentifier ===
null ||
796 $this->
getRequest()->getCheck(
'wpFormIdentifier' ) )
798 $this->mWasSubmitted =
false;
801return $hoistedErrors;
805if ( !is_callable( $callback ) ) {
806thrownew LogicException(
'HTMLForm: no submit callback provided. Use ' .
807'setSubmitCallback() to set one.' );
812 $res = $callback( $data, $this );
813if ( $res ===
false ) {
814 $this->mWasSubmitted =
false;
816// DWIM - callbacks are not supposed to return a StatusValue but it's easy to mix up. 817 $res = Status::wrap( $res );
849 $this->mSubmitCallback = $cb;
864 $this->mValidationErrorMessage = $msg;
892 $this->mPre .= $html;
917if ( $section ===
null ) {
918 $this->mHeader .= $html;
920 $this->mSectionHeaders[$section] ??=
'';
921 $this->mSectionHeaders[$section] .= $html;
937if ( $section ===
null ) {
938 $this->mHeader = $html;
940 $this->mSectionHeaders[$section] = $html;
955return $section ? $this->mSectionHeaders[$section] ??
'' :
$this->mHeader;
968if ( $section ===
null ) {
969 $this->mFooter .= $html;
971 $this->mSectionFooters[$section] ??=
'';
972 $this->mSectionFooters[$section] .= $html;
988if ( $section ===
null ) {
989 $this->mFooter = $html;
991 $this->mSectionFooters[$section] = $html;
1005return $section ? $this->mSectionFooters[$section] ??
'' :
$this->mFooter;
1017 $this->mPost .= $html;
1031 $this->mPost = $html;
1057throw new \InvalidArgumentException(
1058"Non-Codex HTMLForms do not support additional section information." 1062 $this->mSections = $sections;
1078if ( !is_array( $value ) ) {
1079// Per WebRequest::getVal: Array values are discarded for security reasons. 1080 $attribs += [
'name' => $name ];
1081 $this->mHiddenFields[] = [ $value, $attribs ];
1099foreach ( $fields as $name => $value ) {
1100if ( is_array( $value ) ) {
1101// Per WebRequest::getVal: Array values are discarded for security reasons. 1104 $this->mHiddenFields[] = [ $value, [
'name' => $name ] ];
1134if ( !is_array( $data ) ) {
1135 $args = func_get_args();
1136if ( count( $args ) < 2 || count( $args ) > 4 ) {
1137thrownew InvalidArgumentException(
1138'Incorrect number of arguments for deprecated calling style' 1144'id' => $args[2] ??
null,
1145'attribs' => $args[3] ??
null,
1148if ( !isset( $data[
'name'] ) ) {
1149thrownew InvalidArgumentException(
'A name is required' );
1151if ( !isset( $data[
'value'] ) ) {
1152thrownew InvalidArgumentException(
'A value is required' );
1155 $this->mButtons[] = $data + [
1175 $this->mTokenSalt = $salt;
1201privatefunction getHiddenTitle(): string {
1202if ( $this->hiddenTitleAddedToForm ) {
1210 $html .= Html::hidden(
'title', $this->
getTitle()->getPrefixedText() ) .
"\n";
1212 $this->hiddenTitleAddedToForm =
true;
1227 # For good measure (it is the default) 1228 $this->getOutput()->getMetadata()->setPreventClickjacking(
true );
1229 $this->getOutput()->addModules(
'mediawiki.htmlform' );
1230 $this->getOutput()->addModuleStyles( [
1231'mediawiki.htmlform.styles',
1232// Html::errorBox and Html::warningBox used by HtmlFormField and HtmlForm::getErrorsOrWarnings 1233'mediawiki.codex.messagebox.styles' 1236if ( $this->mCollapsible ) {
1237// Preload jquery.makeCollapsible for mediawiki.htmlform 1238 $this->getOutput()->addModules(
'jquery.makeCollapsible' );
1241 $headerHtml = $this->getHeaderHtml();
1242 $footerHtml = $this->getFooterHtml();
1243 $html = $this->getErrorsOrWarnings( $submitResult,
'error' )
1244 . $this->getErrorsOrWarnings( $submitResult,
'warning' )
1246 . $this->getHiddenTitle()
1248 . $this->getHiddenFields()
1249 . $this->getButtons()
1252return $this->mPre . $this->wrapForm( $html ) . $this->mPost;
1263 $this->mCollapsible =
true;
1264 $this->mCollapsed = $collapsedByDefault;
1274 # Use multipart/form-data 1275 $encType = $this->mUseMultipart
1276 ?
'multipart/form-data' 1277 :
'application/x-www-form-urlencoded';
1280'class' =>
'mw-htmlform',
1281'action' => $this->getAction(),
1282'method' => $this->getMethod(),
1283'enctype' => $encType,
1286 $attribs[
'id'] = $this->mId;
1288if ( is_string( $this->mAutocomplete ) ) {
1289 $attribs[
'autocomplete'] = $this->mAutocomplete;
1291if ( $this->mName ) {
1292 $attribs[
'name'] = $this->mName;
1294if ( $this->needsJSForHtml5FormValidation() ) {
1295 $attribs[
'novalidate'] =
true;
1308 # Include a <fieldset> wrapper for style, if requested. 1309if ( $this->mWrapperLegend !==
false ) {
1310 $legend = is_string( $this->mWrapperLegend ) ? $this->mWrapperLegend :
false;
1311 $html = Html::rawElement(
1313 $this->mWrapperAttributes,
1314 ( $legend ?
Html::element(
'legend', [], $legend ) :
'' ) . $html
1318return Html::rawElement(
1320 $this->getFormAttributes(),
1332// add the title as a hidden file if it hasn't been added yet and if it is necessary 1333// added for backward compatibility with the previous version of this public method 1334 $html .= $this->getHiddenTitle();
1336if ( $this->mFormIdentifier !==
null ) {
1337 $html .= Html::hidden(
1339 $this->mFormIdentifier
1342if ( $this->getMethod() ===
'post' ) {
1343 $html .= Html::hidden(
1345 $this->getUser()->getEditToken( $this->mTokenSalt ),
1346 [
'id' =>
'wpEditToken' ]
1350foreach ( $this->mHiddenFields as [ $value, $attribs ] ) {
1351 $html .= Html::hidden( $attribs[
'name'], $value, $attribs ) .
"\n";
1365if ( $this->mShowSubmit ) {
1368if ( $this->mSubmitID !==
null ) {
1369 $attribs[
'id'] = $this->mSubmitID;
1372if ( $this->mSubmitName !==
null ) {
1373 $attribs[
'name'] = $this->mSubmitName;
1376if ( $this->mSubmitTooltip !==
null ) {
1377 $attribs += Linker::tooltipAndAccesskeyAttribs( $this->mSubmitTooltip );
1380 $attribs[
'class'] = [
'mw-htmlform-submit' ];
1382 $buttons .= Html::submitButton( $this->getSubmitText(), $attribs ) .
"\n";
1385if ( $this->mShowCancel ) {
1386 $target = $this->getCancelTargetURL();
1392 $this->msg(
'cancel' )->text()
1396foreach ( $this->mButtons as $button ) {
1399'name' => $button[
'name'],
1400'value' => $button[
'value']
1403if ( isset( $button[
'label-message'] ) ) {
1404 $label = $this->getMessage( $button[
'label-message'] )->parse();
1405 } elseif ( isset( $button[
'label'] ) ) {
1406 $label = htmlspecialchars( $button[
'label'] );
1407 } elseif ( isset( $button[
'label-raw'] ) ) {
1408 $label = $button[
'label-raw'];
1410 $label = htmlspecialchars( $button[
'value'] );
1413// @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset Always set in self::addButton 1414if ( $button[
'attribs'] ) {
1415// @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset Always set in self::addButton 1416 $attrs += $button[
'attribs'];
1419if ( isset( $button[
'id'] ) ) {
1420 $attrs[
'id'] = $button[
'id'];
1423 $buttons .= Html::rawElement(
'button', $attrs, $label ) .
"\n";
1430return Html::rawElement(
'span',
1431 [
'class' =>
'mw-htmlform-submit-buttons' ],
"\n$buttons" ) .
"\n";
1440return $this->displaySection( $this->mFieldTree, $this->mTableId );
1453if ( !in_array( $elementsType, [
'error',
'warning' ],
true ) ) {
1454thrownew DomainException( $elementsType .
' is not a valid type.' );
1457if ( $elements instanceof
Status ) {
1458 [ $errorStatus, $warningStatus ] = $elements->splitByErrorType();
1459 $status = $elementsType ===
'error' ? $errorStatus : $warningStatus;
1460if ( $status->isGood() ) {
1463 $elementstr = $status
1465 ->setContext( $this )
1466 ->setInterfaceMessageFlag(
true )
1469 } elseif ( $elementsType ===
'error' ) {
1470if ( is_array( $elements ) ) {
1471 $elementstr = $this->formatErrors( $elements );
1472 } elseif ( $elements && $elements !==
true ) {
1473 $elementstr = (string)$elements;
1477if ( !$elementstr ) {
1479 } elseif ( $elementsType ===
'error' ) {
1480return Html::errorBox( $elementstr );
1481 }
else {
// $elementsType can only be 'warning' 1482return Html::warningBox( $elementstr );
1496foreach ( $errors as $error ) {
1497 $errorstr .= Html::rawElement(
1500 $this->getMessage( $error )->parse()
1504return Html::rawElement(
'ul', [], $errorstr );
1515 $this->mSubmitText = $t;
1527 $this->mSubmitFlags = [
'destructive',
'primary' ];
1541if ( !$msg instanceof
Message ) {
1542 $msg = $this->msg( $msg );
1544 $this->setSubmitText( $msg->text() );
1554return $this->mSubmitText ?: $this->msg(
'htmlform-submit' )->text();
1563 $this->mSubmitName = $name;
1574 $this->mSubmitTooltip = $name;
1588 $this->mSubmitID = $t;
1612 $this->mFormIdentifier = $ident;
1613 $this->mSingleForm = $single;
1629 $this->mShowSubmit = !$suppressSubmit;
1641 $this->mShowCancel = $show;
1653 $target = TitleValue::castPageToLinkTarget( $target );
1656 $this->mCancelTarget = $target;
1665if ( is_string( $this->mCancelTarget ) ) {
1666return $this->mCancelTarget;
1668// TODO: use a service to get the local URL for a LinkTarget, see T282283 1669 $target = Title::castFromLinkTarget( $this->mCancelTarget ) ?: Title::newMainPage();
1670return $target->getLocalURL();
1684 $this->mTableId = $id;
1705 $this->mName = $name;
1722 $this->mWrapperLegend = $legend;
1735 $this->mWrapperAttributes = $attributes;
1750if ( !$msg instanceof
Message ) {
1751 $msg = $this->msg( $msg );
1753 $this->setWrapperLegend( $msg->text() );
1768 $this->mMessagePrefix = $p;
1781// TODO: make mTitle a PageReference when we have a better way to get URLs, see T282283. 1782 $this->mTitle = Title::castFromPageReference( $t );
1791return $this->mTitle ?: $this->getContext()->getTitle();
1802 $this->mMethod = strtolower( $method );
1811return $this->mMethod;
1825return Html::rawElement(
1852 $fieldsetIDPrefix =
'',
1853 &$hasUserVisibleFields =
false 1855if ( $this->mFieldData ===
null ) {
1856thrownew LogicException(
'HTMLForm::displaySection() called on uninitialized field data. ' 1857 .
'You probably called displayForm() without calling prepareForm() first.' );
1861 $subsectionHtml =
'';
1864foreach ( $fields as $key => $value ) {
1866 $v = array_key_exists( $key, $this->mFieldData )
1867 ? $this->mFieldData[$key]
1868 : $value->getDefault();
1870 $retval = $this->formatField( $value, $v ??
'' );
1872// check, if the form field should be added to 1874if ( $value->hasVisibleOutput() ) {
1877 $labelValue = trim( $value->getLabel() );
1878if ( $labelValue !==
"\u{00A0}" && $labelValue !==
' ' && $labelValue !==
'' ) {
1882 $hasUserVisibleFields =
true;
1884 } elseif ( is_array( $value ) ) {
1885 $subsectionHasVisibleFields =
false;
1887 $this->displaySection( $value,
1889"$fieldsetIDPrefix$key-",
1890 $subsectionHasVisibleFields );
1892if ( $subsectionHasVisibleFields ===
true ) {
1893// Display the section with various niceties. 1894 $hasUserVisibleFields =
true;
1896 $legend = $this->getLegend( $key );
1898 $headerHtml = $this->getHeaderHtml( $key );
1899 $footerHtml = $this->getFooterHtml( $key );
1900 $section = $headerHtml .
1905if ( $fieldsetIDPrefix ) {
1906 $attributes[
'id'] = Sanitizer::escapeIdForAttribute(
"$fieldsetIDPrefix$key" );
1908 $subsectionHtml .= $this->wrapFieldSetSection(
1909 $legend, $section, $attributes, $fields === $this->mFieldTree
1912// Just return the inputs, nothing fancy. 1913 $subsectionHtml .= $section;
1918 $html = $this->formatSection( $html, $sectionName, $hasLabel );
1920if ( $subsectionHtml ) {
1921if ( $this->mSubSectionBeforeFields ) {
1922return $subsectionHtml .
"\n" . $html;
1924return $html .
"\n" . $subsectionHtml;
1940 $displayFormat = $this->getDisplayFormat();
1941switch ( $displayFormat ) {
1945return $field->
getDiv( $value );
1947return $field->
getRaw( $value );
1951thrownew LogicException(
'Not implemented' );
1963protectedfunctionformatSection( array $fieldsHtml, $sectionName, $anyFieldHasLabel ) {
1964if ( !$fieldsHtml ) {
1965// Do not generate any wrappers for empty sections. Sections may be empty if they only have 1966// subsections, but no fields. A legend will still be added in wrapFieldSetSection(). 1970 $displayFormat = $this->getDisplayFormat();
1971 $html = implode(
'', $fieldsHtml );
1973if ( $displayFormat ===
'raw' ) {
1977// Avoid strange spacing when no labels exist 1978 $attribs = $anyFieldHasLabel ? [] : [
'class' =>
'mw-htmlform-nolabel' ];
1980if ( $sectionName ) {
1981 $attribs[
'id'] = Sanitizer::escapeIdForAttribute( $sectionName );
1984if ( $displayFormat ===
'table' ) {
1985return Html::rawElement(
'table',
1987 Html::rawElement(
'tbody', [],
"\n$html\n" ) ) .
"\n";
1988 } elseif ( $displayFormat ===
'inline' ) {
1989return Html::rawElement(
'span', $attribs,
"\n$html\n" );
1991return Html::rawElement(
'div', $attribs,
"\n$html\n" );
1999 $this->prepareForm();
2007 $request = $this->getRequest();
2009foreach ( $this->mFlatFields as $fieldname => $field ) {
2010if ( $field->skipLoadData( $request ) ) {
2013if ( $field->mParams[
'disabled'] ??
false ) {
2014 $fieldData[$fieldname] = $field->getDefault();
2016 $fieldData[$fieldname] = $field->loadDataFromRequest( $request );
2020// Reset to default for fields that are supposed to be disabled. 2021// FIXME: Handle dependency chains, fields that a field checks on may need a reset too. 2022foreach ( $fieldData as $name => &$value ) {
2023 $field = $this->mFlatFields[$name];
2024if ( $field->isDisabled( $fieldData ) ) {
2025 $value = $field->getDefault();
2030foreach ( $fieldData as $name => &$value ) {
2031 $field = $this->mFlatFields[$name];
2032 $value = $field->filter( $value, $fieldData );
2035 $this->mFieldData = $fieldData;
2062return $this->msg( $this->mMessagePrefix ?
"{$this->mMessagePrefix}-$key" : $key )->text();
2076 $this->mAction = $action;
2089// If an action is already provided, return it 2090if ( $this->mAction !==
false ) {
2091return $this->mAction;
2095// Check whether we are in GET mode and the ArticlePath contains a "?" 2096// meaning that getLocalURL() would return something like "index.php?title=...". 2097// As browser remove the query string before submitting GET forms, 2098// it means that the title would be lost. In such case use script path instead 2099// and put title in a hidden field (see getHiddenFields()). 2100if ( str_contains( $articlePath,
'?' ) && $this->getMethod() ===
'get' ) {
2104return $this->getTitle()->getLocalURL();
2118 $this->mAutocomplete = $autocomplete;
2143foreach ( $this->mFlatFields as $field ) {
2144if ( $field->needsJSForHtml5FormValidation() ) {
2153class_alias( HTMLForm::class,
'HTMLForm' );
wfDeprecatedMsg( $msg, $version=false, $component=false, $callerOffset=2)
Log a deprecation warning with arbitrary message text.
if(!defined('MW_SETUP_CALLBACK'))
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
getCsrfTokenSet()
Get a repository to obtain and match CSRF tokens.
setContext(IContextSource $context)
Text field for selecting a value from a large list of possible values, with auto-completion and optio...
A checkbox matrix Operates similarly to HTMLMultiSelectField, but instead of using an array of option...
A field that will contain a date and/or time.
Expiry Field that allows the user to specify a precise date or a relative date string.
A field that will contain a numeric value.
A container for HTMLFormFields that allows for multiple copies of the set of fields to be displayed t...
An information field (text blob), not a proper input.
A field that must contain a number.
Implements a tag multiselect input field for namespaces.
Implements a tag multiselect input field with a searchable dropdown containing valid tags.
Double field with a dropdown list constructed from a system message in the format.
A limit dropdown, which accepts any valid number.
Creates a Html::namespaceSelector input field with a button assigned to the input field.
Wrapper for Html::namespaceSelector to use in HTMLForm.
Select dropdown field, with an additional "other" textbox.
A size filter field for use on query-type special pages.
Add a submit button inline in the form (as opposed to HTMLForm::addButton(), which will add it at the...
Wrapper for ChangeTags::buildTagFilterSelector to use in HTMLForm.
Implements a tag multiselect input field for arbitrary values.
Creates a text input field with a button assigned to the input field.
Dropdown widget that allows the user to select a timezone, either by choosing a geographic zone,...
Implements a text input field for page titles.
Implements a tag multiselect input field for titles.
Implements a text input field for user names.
Implements a tag multiselect input field for user names.
The parent class to generate form fields.
getDiv( $value)
Get the complete div for the input, including help text, labels, and whatever.
getTableRow( $value)
Get the complete table row for the input, including help text, labels, and whatever.
getRaw( $value)
Get the complete raw fields for the input, including help text, labels, and whatever.
getInline( $value)
Get the complete field as an inline element.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
wrapForm( $html)
Wrap the form innards in an actual "<form>" element.
displayForm( $submitResult)
Display the form (sending to the context's OutputPage object), with an appropriate error message or s...
setHeaderHtml( $html, $section=null)
Set header HTML, inside the form.
needsJSForHtml5FormValidation()
Whether this form, with its current fields, requires the user agent to have JavaScript enabled for th...
setWrapperLegendMsg( $msg)
Prompt the whole form to be wrapped in a "<fieldset>", with this message as its "<legend>" element.
showCancel( $show=true)
Show a cancel button (or prevent it).
setMessagePrefix( $p)
Set the prefix for various default messages.
string null $mFormIdentifier
array[] $mSections
Additional information about form sections.
wrapFieldSetSection( $legend, $section, $attributes, $isRoot)
Wraps the given $section into a user-visible fieldset.
string false $mWrapperLegend
callable null $mSubmitCallback
getHeaderHtml( $section=null)
Get header HTML.
bool $mCollapsed
Whether the form is collapsed by default.
string[] $mSectionFooters
setFormIdentifier(string $ident, bool $single=false)
Set an internal identifier for this form.
trySubmit()
Validate all the fields, and call the submission callback function if everything is kosher.
string[] $mSectionHeaders
array $mWrapperAttributes
array $availableSubclassDisplayFormats
Available formats in which to display the form.
setAction( $action)
Set the value for the action attribute of the form.
setPreHtml( $html)
Set the introductory message HTML, overwriting any existing message.
setTokenSalt( $salt)
Set the salt for the edit token.
setFooterHtml( $html, $section=null)
Set footer HTML, inside the form.
suppressDefaultSubmit( $suppressSubmit=true)
Stop a default submit button being shown for this form.
loadFieldData()
Load data of form fields from the request.
tryAuthorizedSubmit()
Try submitting, with edit token check first.
wasSubmitted()
Test whether the form was considered to have been submitted or not, i.e.
getFormAttributes()
Get HTML attributes for the <form> tag.
static getClassFromDescriptor( $fieldname, &$descriptor)
Get the HTMLFormField subclass for this descriptor.
getMessage( $value)
Turns a *-message parameter (which could be a MessageSpecifier, or a message name,...
prepareForm()
Prepare form for submission.
LinkTarget string null $mCancelTarget
bool $mCollapsible
Whether the form can be collapsed.
addHiddenField( $name, $value, array $attribs=[])
Add a hidden field to the output Array values are discarded for security reasons (per WebRequest::get...
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setAutocomplete( $autocomplete)
Set the value for the autocomplete attribute of the form.
getBody()
Get the whole body of the form.
bool $mSubSectionBeforeFields
If true, sections that contain both fields and subsections will render their subsections before their...
string $displayFormat
Format in which to display form.
setWrapperAttributes( $attributes)
For internal use only.
string null $mAutocomplete
Form attribute autocomplete.
getDisplayFormat()
Getter for displayFormat.
formatSection(array $fieldsHtml, $sectionName, $anyFieldHasLabel)
Put a form section together from the individual fields' HTML, merging it and wrapping.
setDisplayFormat( $format)
Set format in which to display the form.
string array $mTokenSalt
Salt for the edit token.
getHTML( $submitResult)
Returns the raw HTML generated by the form.
addButton( $data)
Add a button to the form.
getHiddenFields()
Get the hidden fields that should go inside the form.
setTableId( $id)
Set the id of the <table> or outermost <div> element.
setWrapperLegend( $legend)
Prompt the whole form to be wrapped in a "<fieldset>", with this text as its "<legend>" element.
addFooterHtml( $html, $section=null)
Add footer HTML, inside the form.
showAlways()
Same as self::show with the difference, that the form will be added to the output,...
displaySection( $fields, $sectionName='', $fieldsetIDPrefix='', &$hasUserVisibleFields=false)
addFields( $descriptor)
Add fields to the form.
setSubmitText( $t)
Set the text for the submit button.
setPostHtml( $html)
Set HTML at the end of the display.
getFooterHtml( $section=null)
Get footer HTML.
setTitle( $t)
Set the title for form submission.
setSubmitCallback( $cb)
Set a callback to a function to do something with the form once it's been successfully validated.
getSubmitText()
Get the text for the submit button, either customised or a default.
addHiddenFields(array $fields)
Add an array of hidden fields to the output Array values are discarded for security reasons (per WebR...
show()
The here's-one-I-made-earlier option: do the submission if posted, or display the form with or withou...
formatField(HTMLFormField $field, $value)
Generate the HTML for an individual field in the current display format.
setSections( $sections)
Set an array of information about sections.
formatErrors( $errors)
Format a stack of error messages into a single HTML string.
setValidationErrorMessage( $msg)
Set a message to display on a validation error.
HTMLFormField[] $mFlatFields
setSubmitDestructive()
Identify that the submit button in the form has a destructive action.
string null $mSubmitTooltip
static loadInputFromParameters( $fieldname, $descriptor, ?HTMLForm $parent=null)
Initialise a new Object for the field.
getErrorsOrWarnings( $elements, $elementsType)
Returns a formatted list of errors or warnings from the given elements.
addPreHtml( $html)
Add HTML to introductory message.
setSubmitID( $t)
Set the id for the submit button.
array $availableDisplayFormats
Available formats in which to display the form.
getPostHtml()
Get HTML at the end of the display.
array[] $mValidationErrorMessage
getLegend( $key)
Get a string to go in the "<legend>" of a section fieldset.
setCancelTarget( $target)
Sets the target where the user is redirected to after clicking cancel.
addHeaderHtml( $html, $section=null)
Add HTML to the header, inside the form.
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
setCollapsibleOptions( $collapsedByDefault=false)
Enable collapsible mode, and set whether the form is collapsed by default.
getAction()
Get the value for the action attribute of the form.
setMethod( $method='post')
Set the method used to submit the form.
getPreHtml()
Get the introductory message HTML.
getButtons()
Get the submit and (potentially) reset buttons.
static string[] $typeMappings
A mapping of 'type' inputs onto standard HTMLFormField subclasses.
filterDataForSubmit( $data)
Overload this if you want to apply special filtration routines to the form as a whole,...
__construct( $descriptor, IContextSource $context, $messagePrefix='')
Build a new HTMLForm from an array of field attributes.
string false $mAction
Form action URL.
addPostHtml( $html)
Add HTML to the end of the display.
Compact stacked vertical format for forms, implemented using OOUI widgets.
Compact stacked vertical format for forms.
This class is a collection of static functions that serve two purposes:
Some internal bits split of from Skin.php.
A class containing constants representing the names of configuration variables.
const ArticlePath
Name constant for the ArticlePath setting, for use with Config::get()
const Script
Name constant for the Script setting, for use with Config::get()
The Message class deals with fetching and processing of interface message into a variety of formats.
static newFromSpecifier( $value)
Transform a MessageSpecifier or a primitive value used interchangeably with specifiers (a message key...
HTML sanitizer for MediaWiki.
Stores and matches CSRF tokens belonging to a given session user.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Represents the target of a wiki link.
Represents a title within MediaWiki.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Value object representing a message parameter that consists of a list of values.
Interface for objects which can provide a MediaWiki context on request.
Represents the target of a wiki link.
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
element(SerializerNode $parent, SerializerNode $node, $contents)