Hoist validation errors from hidden fields to the top of the form
authorGergő Tisza <gtisza@wikimedia.org>
Tue, 15 Sep 2015 21:49:25 +0000 (21:49 +0000)
committerGergő Tisza <gtisza@wikimedia.org>
Fri, 25 Sep 2015 17:40:30 +0000 (17:40 +0000)
HTMLFormField subclasses are supposed to handle error display but
some (like hidden fields) have no means of doing this. Add
a HTMLFormField::canDisplayErrors() method which can be overridden
to return false, in which case HTMLForm will take care of the
error display.

Also adds a 'rawmessage' message which can be used to wrap
arbitrary text. This can be passed to methods which expect a message
specifier array but do not allow a message object (so the RawMessage
class cannot be used), such as HTMLFormField::trySubmit().

Bug: T112635
Change-Id: I5d73536805774ff2ee0ec64b5442650c4888dc84

includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLHiddenField.php
languages/i18n/en.json
languages/i18n/qqq.json

index 38729a5..11eb04d 100644 (file)
@@ -537,6 +537,12 @@ class HTMLForm extends ContextSource {
         *       params) or strings (message keys)
         */
        function trySubmit() {
+               $valid = true;
+               $hoistedErrors = array();
+               $hoistedErrors[] = isset( $this->mValidationErrorMessage )
+                       ? $this->mValidationErrorMessage
+                       : array( 'htmlform-invalid-input' );
+
                $this->mWasSubmitted = true;
 
                # Check for cancelled submission
@@ -558,15 +564,20 @@ class HTMLForm extends ContextSource {
                        if ( $field->isHidden( $this->mFieldData ) ) {
                                continue;
                        }
-                       if ( $field->validate(
-                                       $this->mFieldData[$fieldname],
-                                       $this->mFieldData )
-                               !== true
-                       ) {
-                               return isset( $this->mValidationErrorMessage )
-                                       ? $this->mValidationErrorMessage
-                                       : array( 'htmlform-invalid-input' );
+                       $res = $field->validate( $this->mFieldData[$fieldname], $this->mFieldData );
+                       if ( $res !== true ) {
+                               $valid = false;
+                               if ( $res !== false && !$field->canDisplayErrors() ) {
+                                       $hoistedErrors[] = array( 'rawmessage', $res );
+                               }
+                       }
+               }
+
+               if ( !$valid ) {
+                       if ( count( $hoistedErrors ) === 1 ) {
+                               $hoistedErrors = $hoistedErrors[0];
                        }
+                       return $hoistedErrors;
                }
 
                $callback = $this->mSubmitCallback;
index 0fab033..5d405c3 100644 (file)
@@ -55,6 +55,15 @@ abstract class HTMLFormField {
                return false;
        }
 
+       /**
+        * True if this field type is able to display errors; false if validation errors need to be
+        * displayed in the main HTMLForm error area.
+        * @return bool
+        */
+       public function canDisplayErrors() {
+               return true;
+       }
+
        /**
         * Get a translated interface message
         *
index ffde915..e4695f7 100644 (file)
@@ -55,4 +55,8 @@ class HTMLHiddenField extends HTMLFormField {
        public function getInputHTML( $value ) {
                return '';
        }
+
+       public function canDisplayErrors() {
+               return false;
+       }
 }
index 51cc927..38bba39 100644 (file)
        "htmlform-title-not-exists": "[[:$1]] does not exist.",
        "htmlform-user-not-exists": "<strong>$1</strong> does not exist.",
        "htmlform-user-not-valid": "<strong>$1</strong> isn't a valid username.",
+       "rawmessage": "$1",
        "sqlite-has-fts": "$1 with full-text search support",
        "sqlite-no-fts": "$1 without full-text search support",
        "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} page $3",
index 0cf37cd..0455a41 100644 (file)
        "htmlform-title-not-exists": "Error message shown if the page title provided by the user does not exist. $1 is the page title.",
        "htmlform-user-not-exists": "Error message shown if a user with the name provided by the user does not exist. $1 is the username.",
        "htmlform-user-not-valid": "Error message shown if the name provided by the user isn't a valid username. $1 is the username.",
+       "rawmessage": "{{notranslate}} Used to pass arbitrary text as a message specifier array",
        "sqlite-has-fts": "Shown on [[Special:Version]].\nParameters:\n* $1 - version",
        "sqlite-no-fts": "Shown on [[Special:Version]].\nParameters:\n* $1 - version",
        "logentry-delete-delete": "{{Logentry|[[Special:Log/delete]]}}",