Instead of creating an OutputPage and then setting a context start initializing Outpu...
[lhc/web/wiklou.git] / includes / HTMLForm.php
index 1010229..d8d83e8 100644 (file)
@@ -159,7 +159,7 @@ class HTMLForm {
        /**
         * Add the HTMLForm-specific JavaScript, if it hasn't been
         * done already.
-        * @deprecated @since 1.18 load modules with ResourceLoader instead
+        * @deprecated since 1.18 load modules with ResourceLoader instead
         */
        static function addJS() { }
 
@@ -522,7 +522,7 @@ class HTMLForm {
         * @param $errors Array of message keys/values
         * @return String HTML, a <ul> list of errors
         */
-       static function formatErrors( $errors ) {
+       public static function formatErrors( $errors ) {
                $errorstr = '';
 
                foreach ( $errors as $error ) {
@@ -648,7 +648,7 @@ class HTMLForm {
                                        $hasLeftColumn = true;
                        } elseif ( is_array( $value ) ) {
                                $section = $this->displaySection( $value, $key );
-                               $legend = wfMsg( "{$this->mMessagePrefix}-$key" );
+                               $legend = $this->getLegend( $key );
                                if ( isset( $this->mSectionHeaders[$key] ) ) {
                                        $section = $this->mSectionHeaders[$key] . $section;
                                } 
@@ -725,6 +725,16 @@ class HTMLForm {
        function filterDataForSubmit( $data ) {
                return $data;
        }
+
+       /**
+        * Get a string to go in the <legend> of a section fieldset.  Override this if you
+        * want something more complicated
+        * @param $key String
+        * @return String
+        */
+       public function getLegend( $key ) {
+               return wfMsg( "{$this->mMessagePrefix}-$key" );
+       }
 }
 
 /**
@@ -890,8 +900,10 @@ abstract class HTMLFormField {
 
                if ( $errors === true || ( !$wgRequest->wasPosted() && ( $this->mParent->getMethod() == 'post' ) ) ) {
                        $errors = '';
+                       $errorClass = '';
                } else {
-                       $errors = Html::rawElement( 'span', array( 'class' => 'error' ), $errors );
+                       $errors = self::formatErrors( $errors );
+                       $errorClass = 'mw-htmlform-invalid-input';
                }
 
                $label = $this->getLabelHtml( $cellAttributes );
@@ -903,15 +915,15 @@ abstract class HTMLFormField {
 
                $fieldType = get_class( $this );
 
-               if ($verticalLabel) {
+               if ( $verticalLabel ) {
                        $html = Html::rawElement( 'tr',
                                array( 'class' => 'mw-htmlform-vertical-label' ), $label );
                        $html .= Html::rawElement( 'tr',
-                               array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass}" ),
+                               array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass" ),
                                $field );
                } else {
                        $html = Html::rawElement( 'tr',
-                               array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass}" ),
+                               array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass" ),
                                $label . $field );
                }
 
@@ -1009,6 +1021,35 @@ abstract class HTMLFormField {
 
                return $flatOpts;
        }
+
+       /**
+        * Formats one or more errors as accepted by field validation-callback.
+        * @param $errors String|Message|Array of strings or Message instances
+        * @return String html
+        * @since 1.18
+        */
+       protected static function formatErrors( $errors ) {
+               if ( is_array( $errors ) && count( $errors ) === 1 ) {
+                       $errors = array_shift( $errors );
+               }
+
+               if ( is_array( $errors ) ) {
+                       $lines = array();
+                       foreach ( $errors as $error ) {
+                               if ( $error instanceof Message ) {
+                                       $lines[] = Html::rawElement( 'li', array(), $error->parse() );
+                               } else {
+                                       $lines[] = Html::rawElement( 'li', array(), $error );
+                               }
+                       }
+                       return Html::rawElement( 'ul', array( 'class' => 'error' ), implode( "\n", $lines ) );
+               } else {
+                       if ( $errors instanceof Message ) {
+                               $errors = $errors->parse();
+                       }
+                       return Html::rawElement( 'span', array( 'class' => 'error' ), $errors );
+               }
+       }
 }
 
 class HTMLTextField extends HTMLFormField {
@@ -1223,7 +1264,7 @@ class HTMLCheckField extends HTMLFormField {
                }
 
                // GetCheck won't work like we want for checks.
-               if ( $request->getCheck( 'wpEditToken' ) ) {
+               if ( $request->getCheck( 'wpEditToken' ) || $this->mParent->getMethod() != 'post' ) {
                        // XOR has the following truth table, which is what we want
                        // INVERT VALUE | OUTPUT
                        // true   true  | false
@@ -1362,6 +1403,14 @@ class HTMLSelectOrOtherField extends HTMLTextField {
  * Multi-select field
  */
 class HTMLMultiSelectField extends HTMLFormField {
+
+       public function __construct( $params ){
+               parent::__construct( $params );
+               if( isset( $params['flatlist'] ) ){
+                       $this->mClass .= ' mw-htmlform-multiselect-flatlist';
+               }
+       }
+
        function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
 
@@ -1413,7 +1462,7 @@ class HTMLMultiSelectField extends HTMLFormField {
                                        $attribs + $thisAttribs );
                                $checkbox .= '&#160;' . Html::rawElement( 'label', array( 'for' => "{$this->mID}-$info" ), $label );
 
-                               $html .= $checkbox . '<br />';
+                               $html .= ' ' . Html::rawElement( 'div', array( 'class' => 'mw-htmlform-multiselect-item' ), $checkbox );
                        }
                }
 
@@ -1421,17 +1470,22 @@ class HTMLMultiSelectField extends HTMLFormField {
        }
 
        function loadDataFromRequest( $request ) {
-               # won't work with getCheck
-               if ( $request->getCheck( 'wpEditToken' ) ) {
-                       $arr = $request->getArray( $this->mName );
-
-                       if ( !$arr ) {
-                               $arr = array();
+               if ( $this->mParent->getMethod() == 'post' ) {
+                       if( $request->wasPosted() ){
+                               # Checkboxes are just not added to the request arrays if they're not checked,
+                               # so it's perfectly possible for there not to be an entry at all
+                               return $request->getArray( $this->mName, array() );
+                       } else {
+                               # That's ok, the user has not yet submitted the form, so show the defaults
+                               return $this->getDefault();
                        }
-
-                       return $arr;
                } else {
-                       return $this->getDefault();
+                       # This is the impossible case: if we look at $_GET and see no data for our
+                       # field, is it because the user has not yet submitted the form, or that they
+                       # have submitted it with all the options unchecked? We will have to assume the
+                       # latter, which basically means that you can't specify 'positive' defaults
+                       # for GET forms.  FIXME...
+                       return $request->getArray( $this->mName, array() );
                }
        }