Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like HTMLForm often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use HTMLForm, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 128 | class HTMLForm extends ContextSource { |
||
| 129 | // A mapping of 'type' inputs onto standard HTMLFormField subclasses |
||
| 130 | public static $typeMappings = [ |
||
| 131 | 'api' => 'HTMLApiField', |
||
| 132 | 'text' => 'HTMLTextField', |
||
| 133 | 'textwithbutton' => 'HTMLTextFieldWithButton', |
||
| 134 | 'textarea' => 'HTMLTextAreaField', |
||
| 135 | 'select' => 'HTMLSelectField', |
||
| 136 | 'combobox' => 'HTMLComboboxField', |
||
| 137 | 'radio' => 'HTMLRadioField', |
||
| 138 | 'multiselect' => 'HTMLMultiSelectField', |
||
| 139 | 'limitselect' => 'HTMLSelectLimitField', |
||
| 140 | 'check' => 'HTMLCheckField', |
||
| 141 | 'toggle' => 'HTMLCheckField', |
||
| 142 | 'int' => 'HTMLIntField', |
||
| 143 | 'float' => 'HTMLFloatField', |
||
| 144 | 'info' => 'HTMLInfoField', |
||
| 145 | 'selectorother' => 'HTMLSelectOrOtherField', |
||
| 146 | 'selectandother' => 'HTMLSelectAndOtherField', |
||
| 147 | 'namespaceselect' => 'HTMLSelectNamespace', |
||
| 148 | 'namespaceselectwithbutton' => 'HTMLSelectNamespaceWithButton', |
||
| 149 | 'tagfilter' => 'HTMLTagFilter', |
||
| 150 | 'submit' => 'HTMLSubmitField', |
||
| 151 | 'hidden' => 'HTMLHiddenField', |
||
| 152 | 'edittools' => 'HTMLEditTools', |
||
| 153 | 'checkmatrix' => 'HTMLCheckMatrix', |
||
| 154 | 'cloner' => 'HTMLFormFieldCloner', |
||
| 155 | 'autocompleteselect' => 'HTMLAutoCompleteSelectField', |
||
| 156 | // HTMLTextField will output the correct type="" attribute automagically. |
||
| 157 | // There are about four zillion other HTML5 input types, like range, but |
||
| 158 | // we don't use those at the moment, so no point in adding all of them. |
||
| 159 | 'email' => 'HTMLTextField', |
||
| 160 | 'password' => 'HTMLTextField', |
||
| 161 | 'url' => 'HTMLTextField', |
||
| 162 | 'title' => 'HTMLTitleTextField', |
||
| 163 | 'user' => 'HTMLUserTextField', |
||
| 164 | ]; |
||
| 165 | |||
| 166 | public $mFieldData; |
||
| 167 | |||
| 168 | protected $mMessagePrefix; |
||
| 169 | |||
| 170 | /** @var HTMLFormField[] */ |
||
| 171 | protected $mFlatFields; |
||
| 172 | |||
| 173 | protected $mFieldTree; |
||
| 174 | protected $mShowReset = false; |
||
| 175 | protected $mShowSubmit = true; |
||
| 176 | protected $mSubmitFlags = [ 'constructive', 'primary' ]; |
||
| 177 | protected $mShowCancel = false; |
||
| 178 | protected $mCancelTarget; |
||
| 179 | |||
| 180 | protected $mSubmitCallback; |
||
| 181 | protected $mValidationErrorMessage; |
||
| 182 | |||
| 183 | protected $mPre = ''; |
||
| 184 | protected $mHeader = ''; |
||
| 185 | protected $mFooter = ''; |
||
| 186 | protected $mSectionHeaders = []; |
||
| 187 | protected $mSectionFooters = []; |
||
| 188 | protected $mPost = ''; |
||
| 189 | protected $mId; |
||
| 190 | protected $mName; |
||
| 191 | protected $mTableId = ''; |
||
| 192 | |||
| 193 | protected $mSubmitID; |
||
| 194 | protected $mSubmitName; |
||
| 195 | protected $mSubmitText; |
||
| 196 | protected $mSubmitTooltip; |
||
| 197 | |||
| 198 | protected $mFormIdentifier; |
||
| 199 | protected $mTitle; |
||
| 200 | protected $mMethod = 'post'; |
||
| 201 | protected $mWasSubmitted = false; |
||
| 202 | |||
| 203 | /** |
||
| 204 | * Form action URL. false means we will use the URL to set Title |
||
| 205 | * @since 1.19 |
||
| 206 | * @var bool|string |
||
| 207 | */ |
||
| 208 | protected $mAction = false; |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Form attribute autocomplete. false does not set the attribute |
||
| 212 | * @since 1.27 |
||
| 213 | * @var bool|string |
||
| 214 | */ |
||
| 215 | protected $mAutocomplete = false; |
||
| 216 | |||
| 217 | protected $mUseMultipart = false; |
||
| 218 | protected $mHiddenFields = []; |
||
| 219 | protected $mButtons = []; |
||
| 220 | |||
| 221 | protected $mWrapperLegend = false; |
||
| 222 | |||
| 223 | /** |
||
| 224 | * Salt for the edit token. |
||
| 225 | * @var string|array |
||
| 226 | */ |
||
| 227 | protected $mTokenSalt = ''; |
||
| 228 | |||
| 229 | /** |
||
| 230 | * If true, sections that contain both fields and subsections will |
||
| 231 | * render their subsections before their fields. |
||
| 232 | * |
||
| 233 | * Subclasses may set this to false to render subsections after fields |
||
| 234 | * instead. |
||
| 235 | */ |
||
| 236 | protected $mSubSectionBeforeFields = true; |
||
| 237 | |||
| 238 | /** |
||
| 239 | * Format in which to display form. For viable options, |
||
| 240 | * @see $availableDisplayFormats |
||
| 241 | * @var string |
||
| 242 | */ |
||
| 243 | protected $displayFormat = 'table'; |
||
| 244 | |||
| 245 | /** |
||
| 246 | * Available formats in which to display the form |
||
| 247 | * @var array |
||
| 248 | */ |
||
| 249 | protected $availableDisplayFormats = [ |
||
| 250 | 'table', |
||
| 251 | 'div', |
||
| 252 | 'raw', |
||
| 253 | 'inline', |
||
| 254 | ]; |
||
| 255 | |||
| 256 | /** |
||
| 257 | * Available formats in which to display the form |
||
| 258 | * @var array |
||
| 259 | */ |
||
| 260 | protected $availableSubclassDisplayFormats = [ |
||
| 261 | 'vform', |
||
| 262 | 'ooui', |
||
| 263 | ]; |
||
| 264 | |||
| 265 | /** |
||
| 266 | * Construct a HTMLForm object for given display type. May return a HTMLForm subclass. |
||
| 267 | * |
||
| 268 | * @param string $displayFormat |
||
| 269 | * @param mixed $arguments... Additional arguments to pass to the constructor. |
||
|
|
|||
| 270 | * @return HTMLForm |
||
| 271 | */ |
||
| 272 | public static function factory( $displayFormat/*, $arguments...*/ ) { |
||
| 273 | $arguments = func_get_args(); |
||
| 274 | array_shift( $arguments ); |
||
| 275 | |||
| 276 | switch ( $displayFormat ) { |
||
| 277 | case 'vform': |
||
| 278 | return ObjectFactory::constructClassInstance( VFormHTMLForm::class, $arguments ); |
||
| 279 | case 'ooui': |
||
| 280 | return ObjectFactory::constructClassInstance( OOUIHTMLForm::class, $arguments ); |
||
| 281 | default: |
||
| 282 | /** @var HTMLForm $form */ |
||
| 283 | $form = ObjectFactory::constructClassInstance( HTMLForm::class, $arguments ); |
||
| 284 | $form->setDisplayFormat( $displayFormat ); |
||
| 285 | return $form; |
||
| 286 | } |
||
| 287 | } |
||
| 288 | |||
| 289 | /** |
||
| 290 | * Build a new HTMLForm from an array of field attributes |
||
| 291 | * |
||
| 292 | * @param array $descriptor Array of Field constructs, as described above |
||
| 293 | * @param IContextSource $context Available since 1.18, will become compulsory in 1.18. |
||
| 294 | * Obviates the need to call $form->setTitle() |
||
| 295 | * @param string $messagePrefix A prefix to go in front of default messages |
||
| 296 | */ |
||
| 297 | public function __construct( $descriptor, /*IContextSource*/ $context = null, |
||
| 356 | |||
| 357 | /** |
||
| 358 | * @param string $fieldname |
||
| 359 | * @return bool |
||
| 360 | */ |
||
| 361 | public function hasField( $fieldname ) { |
||
| 364 | |||
| 365 | /** |
||
| 366 | * @param string $fieldname |
||
| 367 | * @return HTMLFormField |
||
| 368 | * @throws DomainException on invalid field name |
||
| 369 | */ |
||
| 370 | public function getField( $fieldname ) { |
||
| 376 | |||
| 377 | /** |
||
| 378 | * Set format in which to display the form |
||
| 379 | * |
||
| 380 | * @param string $format The name of the format to use, must be one of |
||
| 381 | * $this->availableDisplayFormats |
||
| 382 | * |
||
| 383 | * @throws MWException |
||
| 384 | * @since 1.20 |
||
| 385 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 386 | */ |
||
| 387 | public function setDisplayFormat( $format ) { |
||
| 410 | |||
| 411 | /** |
||
| 412 | * Getter for displayFormat |
||
| 413 | * @since 1.20 |
||
| 414 | * @return string |
||
| 415 | */ |
||
| 416 | public function getDisplayFormat() { |
||
| 419 | |||
| 420 | /** |
||
| 421 | * Test if displayFormat is 'vform' |
||
| 422 | * @since 1.22 |
||
| 423 | * @deprecated since 1.25 |
||
| 424 | * @return bool |
||
| 425 | */ |
||
| 426 | public function isVForm() { |
||
| 430 | |||
| 431 | /** |
||
| 432 | * Get the HTMLFormField subclass for this descriptor. |
||
| 433 | * |
||
| 434 | * The descriptor can be passed either 'class' which is the name of |
||
| 435 | * a HTMLFormField subclass, or a shorter 'type' which is an alias. |
||
| 436 | * This makes sure the 'class' is always set, and also is returned by |
||
| 437 | * this function for ease. |
||
| 438 | * |
||
| 439 | * @since 1.23 |
||
| 440 | * |
||
| 441 | * @param string $fieldname Name of the field |
||
| 442 | * @param array $descriptor Input Descriptor, as described above |
||
| 443 | * |
||
| 444 | * @throws MWException |
||
| 445 | * @return string Name of a HTMLFormField subclass |
||
| 446 | */ |
||
| 447 | public static function getClassFromDescriptor( $fieldname, &$descriptor ) { |
||
| 464 | |||
| 465 | /** |
||
| 466 | * Initialise a new Object for the field |
||
| 467 | * |
||
| 468 | * @param string $fieldname Name of the field |
||
| 469 | * @param array $descriptor Input Descriptor, as described above |
||
| 470 | * @param HTMLForm|null $parent Parent instance of HTMLForm |
||
| 471 | * |
||
| 472 | * @throws MWException |
||
| 473 | * @return HTMLFormField Instance of a subclass of HTMLFormField |
||
| 474 | */ |
||
| 475 | public static function loadInputFromParameters( $fieldname, $descriptor, |
||
| 490 | |||
| 491 | /** |
||
| 492 | * Prepare form for submission. |
||
| 493 | * |
||
| 494 | * @attention When doing method chaining, that should be the very last |
||
| 495 | * method call before displayForm(). |
||
| 496 | * |
||
| 497 | * @throws MWException |
||
| 498 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 499 | */ |
||
| 500 | public function prepareForm() { |
||
| 518 | |||
| 519 | /** |
||
| 520 | * Try submitting, with edit token check first |
||
| 521 | * @return Status|bool |
||
| 522 | */ |
||
| 523 | public function tryAuthorizedSubmit() { |
||
| 555 | |||
| 556 | /** |
||
| 557 | * The here's-one-I-made-earlier option: do the submission if |
||
| 558 | * posted, or display the form with or without funky validation |
||
| 559 | * errors |
||
| 560 | * @return bool|Status Whether submission was successful. |
||
| 561 | */ |
||
| 562 | public function show() { |
||
| 574 | |||
| 575 | /** |
||
| 576 | * Same as self::show with the difference, that the form will be |
||
| 577 | * added to the output, no matter, if the validation was good or not. |
||
| 578 | * @return bool|Status Whether submission was successful. |
||
| 579 | */ |
||
| 580 | public function showAlways() { |
||
| 589 | |||
| 590 | /** |
||
| 591 | * Validate all the fields, and call the submission callback |
||
| 592 | * function if everything is kosher. |
||
| 593 | * @throws MWException |
||
| 594 | * @return bool|string|array|Status |
||
| 595 | * - Bool true or a good Status object indicates success, |
||
| 596 | * - Bool false indicates no submission was attempted, |
||
| 597 | * - Anything else indicates failure. The value may be a fatal Status |
||
| 598 | * object, an HTML string, or an array of arrays (message keys and |
||
| 599 | * params) or strings (message keys) |
||
| 600 | */ |
||
| 601 | public function trySubmit() { |
||
| 660 | |||
| 661 | /** |
||
| 662 | * Test whether the form was considered to have been submitted or not, i.e. |
||
| 663 | * whether the last call to tryAuthorizedSubmit or trySubmit returned |
||
| 664 | * non-false. |
||
| 665 | * |
||
| 666 | * This will return false until HTMLForm::tryAuthorizedSubmit or |
||
| 667 | * HTMLForm::trySubmit is called. |
||
| 668 | * |
||
| 669 | * @since 1.23 |
||
| 670 | * @return bool |
||
| 671 | */ |
||
| 672 | public function wasSubmitted() { |
||
| 675 | |||
| 676 | /** |
||
| 677 | * Set a callback to a function to do something with the form |
||
| 678 | * once it's been successfully validated. |
||
| 679 | * |
||
| 680 | * @param callable $cb The function will be passed the output from |
||
| 681 | * HTMLForm::filterDataForSubmit and this HTMLForm object, and must |
||
| 682 | * return as documented for HTMLForm::trySubmit |
||
| 683 | * |
||
| 684 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 685 | */ |
||
| 686 | public function setSubmitCallback( $cb ) { |
||
| 691 | |||
| 692 | /** |
||
| 693 | * Set a message to display on a validation error. |
||
| 694 | * |
||
| 695 | * @param string|array $msg String or Array of valid inputs to wfMessage() |
||
| 696 | * (so each entry can be either a String or Array) |
||
| 697 | * |
||
| 698 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 699 | */ |
||
| 700 | public function setValidationErrorMessage( $msg ) { |
||
| 705 | |||
| 706 | /** |
||
| 707 | * Set the introductory message, overwriting any existing message. |
||
| 708 | * |
||
| 709 | * @param string $msg Complete text of message to display |
||
| 710 | * |
||
| 711 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 712 | */ |
||
| 713 | public function setIntro( $msg ) { |
||
| 718 | |||
| 719 | /** |
||
| 720 | * Set the introductory message HTML, overwriting any existing message. |
||
| 721 | * @since 1.19 |
||
| 722 | * |
||
| 723 | * @param string $msg Complete HTML of message to display |
||
| 724 | * |
||
| 725 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 726 | */ |
||
| 727 | public function setPreText( $msg ) { |
||
| 732 | |||
| 733 | /** |
||
| 734 | * Add HTML to introductory message. |
||
| 735 | * |
||
| 736 | * @param string $msg Complete HTML of message to display |
||
| 737 | * |
||
| 738 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 739 | */ |
||
| 740 | public function addPreText( $msg ) { |
||
| 745 | |||
| 746 | /** |
||
| 747 | * Add HTML to the header, inside the form. |
||
| 748 | * |
||
| 749 | * @param string $msg Additional HTML to display in header |
||
| 750 | * @param string|null $section The section to add the header to |
||
| 751 | * |
||
| 752 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 753 | */ |
||
| 754 | View Code Duplication | public function addHeaderText( $msg, $section = null ) { |
|
| 766 | |||
| 767 | /** |
||
| 768 | * Set header text, inside the form. |
||
| 769 | * @since 1.19 |
||
| 770 | * |
||
| 771 | * @param string $msg Complete HTML of header to display |
||
| 772 | * @param string|null $section The section to add the header to |
||
| 773 | * |
||
| 774 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 775 | */ |
||
| 776 | public function setHeaderText( $msg, $section = null ) { |
||
| 785 | |||
| 786 | /** |
||
| 787 | * Get header text. |
||
| 788 | * |
||
| 789 | * @param string|null $section The section to get the header text for |
||
| 790 | * @since 1.26 |
||
| 791 | * @return string HTML |
||
| 792 | */ |
||
| 793 | public function getHeaderText( $section = null ) { |
||
| 800 | |||
| 801 | /** |
||
| 802 | * Add footer text, inside the form. |
||
| 803 | * |
||
| 804 | * @param string $msg Complete text of message to display |
||
| 805 | * @param string|null $section The section to add the footer text to |
||
| 806 | * |
||
| 807 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 808 | */ |
||
| 809 | View Code Duplication | public function addFooterText( $msg, $section = null ) { |
|
| 821 | |||
| 822 | /** |
||
| 823 | * Set footer text, inside the form. |
||
| 824 | * @since 1.19 |
||
| 825 | * |
||
| 826 | * @param string $msg Complete text of message to display |
||
| 827 | * @param string|null $section The section to add the footer text to |
||
| 828 | * |
||
| 829 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 830 | */ |
||
| 831 | public function setFooterText( $msg, $section = null ) { |
||
| 840 | |||
| 841 | /** |
||
| 842 | * Get footer text. |
||
| 843 | * |
||
| 844 | * @param string|null $section The section to get the footer text for |
||
| 845 | * @since 1.26 |
||
| 846 | * @return string |
||
| 847 | */ |
||
| 848 | public function getFooterText( $section = null ) { |
||
| 855 | |||
| 856 | /** |
||
| 857 | * Add text to the end of the display. |
||
| 858 | * |
||
| 859 | * @param string $msg Complete text of message to display |
||
| 860 | * |
||
| 861 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 862 | */ |
||
| 863 | public function addPostText( $msg ) { |
||
| 868 | |||
| 869 | /** |
||
| 870 | * Set text at the end of the display. |
||
| 871 | * |
||
| 872 | * @param string $msg Complete text of message to display |
||
| 873 | * |
||
| 874 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 875 | */ |
||
| 876 | public function setPostText( $msg ) { |
||
| 881 | |||
| 882 | /** |
||
| 883 | * Add a hidden field to the output |
||
| 884 | * |
||
| 885 | * @param string $name Field name. This will be used exactly as entered |
||
| 886 | * @param string $value Field value |
||
| 887 | * @param array $attribs |
||
| 888 | * |
||
| 889 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 890 | */ |
||
| 891 | public function addHiddenField( $name, $value, array $attribs = [] ) { |
||
| 897 | |||
| 898 | /** |
||
| 899 | * Add an array of hidden fields to the output |
||
| 900 | * |
||
| 901 | * @since 1.22 |
||
| 902 | * |
||
| 903 | * @param array $fields Associative array of fields to add; |
||
| 904 | * mapping names to their values |
||
| 905 | * |
||
| 906 | * @return HTMLForm $this for chaining calls |
||
| 907 | */ |
||
| 908 | public function addHiddenFields( array $fields ) { |
||
| 915 | |||
| 916 | /** |
||
| 917 | * Add a button to the form |
||
| 918 | * |
||
| 919 | * @since 1.27 takes an array as shown. Earlier versions accepted |
||
| 920 | * 'name', 'value', 'id', and 'attribs' as separate parameters in that |
||
| 921 | * order. |
||
| 922 | * @note Custom labels ('label', 'label-message', 'label-raw') are not |
||
| 923 | * supported for IE6 and IE7 due to bugs in those browsers. If detected, |
||
| 924 | * they will be served buttons using 'value' as the button label. |
||
| 925 | * @param array $data Data to define the button: |
||
| 926 | * - name: (string) Button name. |
||
| 927 | * - value: (string) Button value. |
||
| 928 | * - label-message: (string, optional) Button label message key to use |
||
| 929 | * instead of 'value'. Overrides 'label' and 'label-raw'. |
||
| 930 | * - label: (string, optional) Button label text to use instead of |
||
| 931 | * 'value'. Overrides 'label-raw'. |
||
| 932 | * - label-raw: (string, optional) Button label HTML to use instead of |
||
| 933 | * 'value'. |
||
| 934 | * - id: (string, optional) DOM id for the button. |
||
| 935 | * - attribs: (array, optional) Additional HTML attributes. |
||
| 936 | * - flags: (string|string[], optional) OOUI flags. |
||
| 937 | * - framed: (boolean=true, optional) OOUI framed attribute. |
||
| 938 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 939 | */ |
||
| 940 | public function addButton( $data ) { |
||
| 971 | |||
| 972 | /** |
||
| 973 | * Set the salt for the edit token. |
||
| 974 | * |
||
| 975 | * Only useful when the method is "post". |
||
| 976 | * |
||
| 977 | * @since 1.24 |
||
| 978 | * @param string|array $salt Salt to use |
||
| 979 | * @return HTMLForm $this For chaining calls |
||
| 980 | */ |
||
| 981 | public function setTokenSalt( $salt ) { |
||
| 986 | |||
| 987 | /** |
||
| 988 | * Display the form (sending to the context's OutputPage object), with an |
||
| 989 | * appropriate error message or stack of messages, and any validation errors, etc. |
||
| 990 | * |
||
| 991 | * @attention You should call prepareForm() before calling this function. |
||
| 992 | * Moreover, when doing method chaining this should be the very last method |
||
| 993 | * call just after prepareForm(). |
||
| 994 | * |
||
| 995 | * @param bool|string|array|Status $submitResult Output from HTMLForm::trySubmit() |
||
| 996 | * |
||
| 997 | * @return void Nothing, should be last call |
||
| 998 | */ |
||
| 999 | public function displayForm( $submitResult ) { |
||
| 1002 | |||
| 1003 | /** |
||
| 1004 | * Returns the raw HTML generated by the form |
||
| 1005 | * |
||
| 1006 | * @param bool|string|array|Status $submitResult Output from HTMLForm::trySubmit() |
||
| 1007 | * |
||
| 1008 | * @return string HTML |
||
| 1009 | */ |
||
| 1010 | public function getHTML( $submitResult ) { |
||
| 1028 | |||
| 1029 | /** |
||
| 1030 | * Get HTML attributes for the `<form>` tag. |
||
| 1031 | * @return array |
||
| 1032 | */ |
||
| 1033 | protected function getFormAttributes() { |
||
| 1055 | |||
| 1056 | /** |
||
| 1057 | * Wrap the form innards in an actual "<form>" element |
||
| 1058 | * |
||
| 1059 | * @param string $html HTML contents to wrap. |
||
| 1060 | * |
||
| 1061 | * @return string Wrapped HTML. |
||
| 1062 | */ |
||
| 1063 | public function wrapForm( $html ) { |
||
| 1076 | |||
| 1077 | /** |
||
| 1078 | * Get the hidden fields that should go inside the form. |
||
| 1079 | * @return string HTML. |
||
| 1080 | */ |
||
| 1081 | public function getHiddenFields() { |
||
| 1110 | |||
| 1111 | /** |
||
| 1112 | * Get the submit and (potentially) reset buttons. |
||
| 1113 | * @return string HTML. |
||
| 1114 | */ |
||
| 1115 | public function getButtons() { |
||
| 1219 | |||
| 1220 | /** |
||
| 1221 | * Get the whole body of the form. |
||
| 1222 | * @return string |
||
| 1223 | */ |
||
| 1224 | public function getBody() { |
||
| 1227 | |||
| 1228 | /** |
||
| 1229 | * Format and display an error message stack. |
||
| 1230 | * |
||
| 1231 | * @param string|array|Status $errors |
||
| 1232 | * |
||
| 1233 | * @return string |
||
| 1234 | */ |
||
| 1235 | public function getErrors( $errors ) { |
||
| 1252 | |||
| 1253 | /** |
||
| 1254 | * Format a stack of error messages into a single HTML string |
||
| 1255 | * |
||
| 1256 | * @param array $errors Array of message keys/values |
||
| 1257 | * |
||
| 1258 | * @return string HTML, a "<ul>" list of errors |
||
| 1259 | */ |
||
| 1260 | public function formatErrors( $errors ) { |
||
| 1275 | |||
| 1276 | /** |
||
| 1277 | * Set the text for the submit button |
||
| 1278 | * |
||
| 1279 | * @param string $t Plaintext |
||
| 1280 | * |
||
| 1281 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1282 | */ |
||
| 1283 | public function setSubmitText( $t ) { |
||
| 1288 | |||
| 1289 | /** |
||
| 1290 | * Identify that the submit button in the form has a destructive action |
||
| 1291 | * @since 1.24 |
||
| 1292 | * |
||
| 1293 | * @return HTMLForm $this for chaining calls (since 1.28) |
||
| 1294 | */ |
||
| 1295 | public function setSubmitDestructive() { |
||
| 1300 | |||
| 1301 | /** |
||
| 1302 | * Identify that the submit button in the form has a progressive action |
||
| 1303 | * @since 1.25 |
||
| 1304 | * |
||
| 1305 | * @return HTMLForm $this for chaining calls (since 1.28) |
||
| 1306 | */ |
||
| 1307 | public function setSubmitProgressive() { |
||
| 1312 | |||
| 1313 | /** |
||
| 1314 | * Set the text for the submit button to a message |
||
| 1315 | * @since 1.19 |
||
| 1316 | * |
||
| 1317 | * @param string|Message $msg Message key or Message object |
||
| 1318 | * |
||
| 1319 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1320 | */ |
||
| 1321 | public function setSubmitTextMsg( $msg ) { |
||
| 1329 | |||
| 1330 | /** |
||
| 1331 | * Get the text for the submit button, either customised or a default. |
||
| 1332 | * @return string |
||
| 1333 | */ |
||
| 1334 | public function getSubmitText() { |
||
| 1337 | |||
| 1338 | /** |
||
| 1339 | * @param string $name Submit button name |
||
| 1340 | * |
||
| 1341 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1342 | */ |
||
| 1343 | public function setSubmitName( $name ) { |
||
| 1348 | |||
| 1349 | /** |
||
| 1350 | * @param string $name Tooltip for the submit button |
||
| 1351 | * |
||
| 1352 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1353 | */ |
||
| 1354 | public function setSubmitTooltip( $name ) { |
||
| 1359 | |||
| 1360 | /** |
||
| 1361 | * Set the id for the submit button. |
||
| 1362 | * |
||
| 1363 | * @param string $t |
||
| 1364 | * |
||
| 1365 | * @todo FIXME: Integrity of $t is *not* validated |
||
| 1366 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1367 | */ |
||
| 1368 | public function setSubmitID( $t ) { |
||
| 1373 | |||
| 1374 | /** |
||
| 1375 | * Set an internal identifier for this form. It will be submitted as a hidden form field, allowing |
||
| 1376 | * HTMLForm to determine whether the form was submitted (or merely viewed). Setting this serves |
||
| 1377 | * two purposes: |
||
| 1378 | * |
||
| 1379 | * - If you use two or more forms on one page, it allows HTMLForm to identify which of the forms |
||
| 1380 | * was submitted, and not attempt to validate the other ones. |
||
| 1381 | * - If you use checkbox or multiselect fields inside a form using the GET method, it allows |
||
| 1382 | * HTMLForm to distinguish between the initial page view and a form submission with all |
||
| 1383 | * checkboxes or select options unchecked. |
||
| 1384 | * |
||
| 1385 | * @since 1.28 |
||
| 1386 | * @param string $ident |
||
| 1387 | * @return $this |
||
| 1388 | */ |
||
| 1389 | public function setFormIdentifier( $ident ) { |
||
| 1394 | |||
| 1395 | /** |
||
| 1396 | * Stop a default submit button being shown for this form. This implies that an |
||
| 1397 | * alternate submit method must be provided manually. |
||
| 1398 | * |
||
| 1399 | * @since 1.22 |
||
| 1400 | * |
||
| 1401 | * @param bool $suppressSubmit Set to false to re-enable the button again |
||
| 1402 | * |
||
| 1403 | * @return HTMLForm $this for chaining calls |
||
| 1404 | */ |
||
| 1405 | public function suppressDefaultSubmit( $suppressSubmit = true ) { |
||
| 1410 | |||
| 1411 | /** |
||
| 1412 | * Show a cancel button (or prevent it). The button is not shown by default. |
||
| 1413 | * @param bool $show |
||
| 1414 | * @return HTMLForm $this for chaining calls |
||
| 1415 | * @since 1.27 |
||
| 1416 | */ |
||
| 1417 | public function showCancel( $show = true ) { |
||
| 1421 | |||
| 1422 | /** |
||
| 1423 | * Sets the target where the user is redirected to after clicking cancel. |
||
| 1424 | * @param Title|string $target Target as a Title object or an URL |
||
| 1425 | * @return HTMLForm $this for chaining calls |
||
| 1426 | * @since 1.27 |
||
| 1427 | */ |
||
| 1428 | public function setCancelTarget( $target ) { |
||
| 1432 | |||
| 1433 | /** |
||
| 1434 | * Set the id of the \<table\> or outermost \<div\> element. |
||
| 1435 | * |
||
| 1436 | * @since 1.22 |
||
| 1437 | * |
||
| 1438 | * @param string $id New value of the id attribute, or "" to remove |
||
| 1439 | * |
||
| 1440 | * @return HTMLForm $this for chaining calls |
||
| 1441 | */ |
||
| 1442 | public function setTableId( $id ) { |
||
| 1447 | |||
| 1448 | /** |
||
| 1449 | * @param string $id DOM id for the form |
||
| 1450 | * |
||
| 1451 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1452 | */ |
||
| 1453 | public function setId( $id ) { |
||
| 1458 | |||
| 1459 | /** |
||
| 1460 | * @param string $name 'name' attribute for the form |
||
| 1461 | * @return HTMLForm $this for chaining calls |
||
| 1462 | */ |
||
| 1463 | public function setName( $name ) { |
||
| 1468 | |||
| 1469 | /** |
||
| 1470 | * Prompt the whole form to be wrapped in a "<fieldset>", with |
||
| 1471 | * this text as its "<legend>" element. |
||
| 1472 | * |
||
| 1473 | * @param string|bool $legend If false, no wrapper or legend will be displayed. |
||
| 1474 | * If true, a wrapper will be displayed, but no legend. |
||
| 1475 | * If a string, a wrapper will be displayed with that string as a legend. |
||
| 1476 | * The string will be escaped before being output (this doesn't support HTML). |
||
| 1477 | * |
||
| 1478 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1479 | */ |
||
| 1480 | public function setWrapperLegend( $legend ) { |
||
| 1485 | |||
| 1486 | /** |
||
| 1487 | * Prompt the whole form to be wrapped in a "<fieldset>", with |
||
| 1488 | * this message as its "<legend>" element. |
||
| 1489 | * @since 1.19 |
||
| 1490 | * |
||
| 1491 | * @param string|Message $msg Message key or Message object |
||
| 1492 | * |
||
| 1493 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1494 | */ |
||
| 1495 | public function setWrapperLegendMsg( $msg ) { |
||
| 1503 | |||
| 1504 | /** |
||
| 1505 | * Set the prefix for various default messages |
||
| 1506 | * @todo Currently only used for the "<fieldset>" legend on forms |
||
| 1507 | * with multiple sections; should be used elsewhere? |
||
| 1508 | * |
||
| 1509 | * @param string $p |
||
| 1510 | * |
||
| 1511 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1512 | */ |
||
| 1513 | public function setMessagePrefix( $p ) { |
||
| 1518 | |||
| 1519 | /** |
||
| 1520 | * Set the title for form submission |
||
| 1521 | * |
||
| 1522 | * @param Title $t Title of page the form is on/should be posted to |
||
| 1523 | * |
||
| 1524 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1525 | */ |
||
| 1526 | public function setTitle( $t ) { |
||
| 1531 | |||
| 1532 | /** |
||
| 1533 | * Get the title |
||
| 1534 | * @return Title |
||
| 1535 | */ |
||
| 1536 | public function getTitle() { |
||
| 1541 | |||
| 1542 | /** |
||
| 1543 | * Set the method used to submit the form |
||
| 1544 | * |
||
| 1545 | * @param string $method |
||
| 1546 | * |
||
| 1547 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1548 | */ |
||
| 1549 | public function setMethod( $method = 'post' ) { |
||
| 1554 | |||
| 1555 | /** |
||
| 1556 | * @return string Always lowercase |
||
| 1557 | */ |
||
| 1558 | public function getMethod() { |
||
| 1561 | |||
| 1562 | /** |
||
| 1563 | * Wraps the given $section into an user-visible fieldset. |
||
| 1564 | * |
||
| 1565 | * @param string $legend Legend text for the fieldset |
||
| 1566 | * @param string $section The section content in plain Html |
||
| 1567 | * @param array $attributes Additional attributes for the fieldset |
||
| 1568 | * @return string The fieldset's Html |
||
| 1569 | */ |
||
| 1570 | protected function wrapFieldSetSection( $legend, $section, $attributes ) { |
||
| 1573 | |||
| 1574 | /** |
||
| 1575 | * @todo Document |
||
| 1576 | * |
||
| 1577 | * @param array[]|HTMLFormField[] $fields Array of fields (either arrays or |
||
| 1578 | * objects). |
||
| 1579 | * @param string $sectionName ID attribute of the "<table>" tag for this |
||
| 1580 | * section, ignored if empty. |
||
| 1581 | * @param string $fieldsetIDPrefix ID prefix for the "<fieldset>" tag of |
||
| 1582 | * each subsection, ignored if empty. |
||
| 1583 | * @param bool &$hasUserVisibleFields Whether the section had user-visible fields. |
||
| 1584 | * @throws LogicException When called on uninitialized field data, e.g. When |
||
| 1585 | * HTMLForm::displayForm was called without calling HTMLForm::prepareForm |
||
| 1586 | * first. |
||
| 1587 | * |
||
| 1588 | * @return string |
||
| 1589 | */ |
||
| 1590 | public function displaySection( $fields, |
||
| 1673 | |||
| 1674 | /** |
||
| 1675 | * Put a form section together from the individual fields' HTML, merging it and wrapping. |
||
| 1676 | * @param array $fieldsHtml |
||
| 1677 | * @param string $sectionName |
||
| 1678 | * @param bool $anyFieldHasLabel |
||
| 1679 | * @return string HTML |
||
| 1680 | */ |
||
| 1681 | protected function formatSection( array $fieldsHtml, $sectionName, $anyFieldHasLabel ) { |
||
| 1713 | |||
| 1714 | /** |
||
| 1715 | * Construct the form fields from the Descriptor array |
||
| 1716 | */ |
||
| 1717 | public function loadData() { |
||
| 1739 | |||
| 1740 | /** |
||
| 1741 | * Stop a reset button being shown for this form |
||
| 1742 | * |
||
| 1743 | * @param bool $suppressReset Set to false to re-enable the button again |
||
| 1744 | * |
||
| 1745 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1746 | */ |
||
| 1747 | public function suppressReset( $suppressReset = true ) { |
||
| 1752 | |||
| 1753 | /** |
||
| 1754 | * Overload this if you want to apply special filtration routines |
||
| 1755 | * to the form as a whole, after it's submitted but before it's |
||
| 1756 | * processed. |
||
| 1757 | * |
||
| 1758 | * @param array $data |
||
| 1759 | * |
||
| 1760 | * @return array |
||
| 1761 | */ |
||
| 1762 | public function filterDataForSubmit( $data ) { |
||
| 1765 | |||
| 1766 | /** |
||
| 1767 | * Get a string to go in the "<legend>" of a section fieldset. |
||
| 1768 | * Override this if you want something more complicated. |
||
| 1769 | * |
||
| 1770 | * @param string $key |
||
| 1771 | * |
||
| 1772 | * @return string |
||
| 1773 | */ |
||
| 1774 | public function getLegend( $key ) { |
||
| 1777 | |||
| 1778 | /** |
||
| 1779 | * Set the value for the action attribute of the form. |
||
| 1780 | * When set to false (which is the default state), the set title is used. |
||
| 1781 | * |
||
| 1782 | * @since 1.19 |
||
| 1783 | * |
||
| 1784 | * @param string|bool $action |
||
| 1785 | * |
||
| 1786 | * @return HTMLForm $this for chaining calls (since 1.20) |
||
| 1787 | */ |
||
| 1788 | public function setAction( $action ) { |
||
| 1793 | |||
| 1794 | /** |
||
| 1795 | * Get the value for the action attribute of the form. |
||
| 1796 | * |
||
| 1797 | * @since 1.22 |
||
| 1798 | * |
||
| 1799 | * @return string |
||
| 1800 | */ |
||
| 1801 | public function getAction() { |
||
| 1819 | |||
| 1820 | /** |
||
| 1821 | * Set the value for the autocomplete attribute of the form. |
||
| 1822 | * When set to false (which is the default state), the attribute get not set. |
||
| 1823 | * |
||
| 1824 | * @since 1.27 |
||
| 1825 | * |
||
| 1826 | * @param string|bool $autocomplete |
||
| 1827 | * |
||
| 1828 | * @return HTMLForm $this for chaining calls |
||
| 1829 | */ |
||
| 1830 | public function setAutocomplete( $autocomplete ) { |
||
| 1835 | |||
| 1836 | /** |
||
| 1837 | * Turns a *-message parameter (which could be a MessageSpecifier, or a message name, or a |
||
| 1838 | * name + parameters array) into a Message. |
||
| 1839 | * @param mixed $value |
||
| 1840 | * @return Message |
||
| 1841 | */ |
||
| 1842 | protected function getMessage( $value ) { |
||
| 1845 | } |
||
| 1846 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.