widget: Fix changes of copyright year
[lhc/web/wiklou.git] / includes / Xml.php
index d016433..7dcd4a4 100644 (file)
@@ -160,8 +160,9 @@ class Xml {
        }
 
        /**
-        * @param int $year
-        * @param int $month
+        * @param int|string $year Use '' or 0 to start with no year preselected.
+        * @param int|string $month A month in the 1..12 range. Use '', 0 or -1 to start with no month
+        *  preselected.
         * @return string Formatted HTML
         */
        public static function dateMenu( $year, $month ) {
@@ -225,7 +226,7 @@ class Xml {
                $selected = isset( $languages[$selected] ) ? $selected : $wgLanguageCode;
                $options = "\n";
                foreach ( $languages as $code => $name ) {
-                       $options .= Xml::option( "$code - $name", $code, $code == $selected ) . "\n";
+                       $options .= self::option( "$code - $name", $code, $code == $selected ) . "\n";
                }
 
                $attrs = [ 'id' => 'wpUserLanguage', 'name' => 'wpUserLanguage' ];
@@ -235,8 +236,8 @@ class Xml {
                        $msg = wfMessage( 'yourlanguage' );
                }
                return [
-                       Xml::label( $msg->text(), $attrs['id'] ),
-                       Xml::tags( 'select', $attrs, $options )
+                       self::label( $msg->text(), $attrs['id'] ),
+                       self::tags( 'select', $attrs, $options )
                ];
        }
 
@@ -400,7 +401,7 @@ class Xml {
                $value = false, $attribs = []
        ) {
                return [
-                       Xml::label( $label, $id, $attribs ),
+                       self::label( $label, $id, $attribs ),
                        self::input( $name, $size, $value, [ 'id' => $id ] + $attribs )
                ];
        }
@@ -493,7 +494,8 @@ class Xml {
        }
 
        /**
-        * Build a drop-down box from a textual list.
+        * Build a drop-down box from a textual list. This is a wrapper
+        * for Xml::listDropDownOptions() plus the XmlSelect class.
         *
         * @param string $name Name and id for the drop-down
         * @param string $list Correctly formatted text (newline delimited) to be
@@ -507,60 +509,91 @@ class Xml {
        public static function listDropDown( $name = '', $list = '', $other = '',
                $selected = '', $class = '', $tabindex = null
        ) {
-               $optgroup = false;
+               $options = self::listDropDownOptions( $list, [ 'other' => $other ] );
+
+               $xmlSelect = new XmlSelect( $name, $name, $selected );
+               $xmlSelect->addOptions( $options );
+
+               if ( $class ) {
+                       $xmlSelect->setAttribute( 'class', $class );
+               }
+               if ( $tabindex ) {
+                       $xmlSelect->setAttribute( 'tabindex', $tabindex );
+               }
 
-               $options = self::option( $other, 'other', $selected === 'other' );
+               return $xmlSelect->getHTML();
+       }
 
+       /**
+        * Build options for a drop-down box from a textual list.
+        *
+        * The result of this function can be passed to XmlSelect::addOptions()
+        * (to render a plain `<select>` dropdown box) or to Xml::listDropDownOptionsOoui()
+        * and then OOUI\DropdownInputWidget() (to render a pretty one).
+        *
+        * @param string $list Correctly formatted text (newline delimited) to be
+        *   used to generate the options.
+        * @param array $params Extra parameters:
+        *   - string $params['other'] If set, add an option with this as text and a value of 'other'
+        * @return array Array keys are textual labels, values are internal values
+        */
+       public static function listDropDownOptions( $list, $params = [] ) {
+               $options = [];
+
+               if ( isset( $params['other'] ) ) {
+                       $options[ $params['other'] ] = 'other';
+               }
+
+               $optgroup = false;
                foreach ( explode( "\n", $list ) as $option ) {
                        $value = trim( $option );
                        if ( $value == '' ) {
                                continue;
                        } elseif ( substr( $value, 0, 1 ) == '*' && substr( $value, 1, 1 ) != '*' ) {
-                               // A new group is starting ...
+                               # A new group is starting...
                                $value = trim( substr( $value, 1 ) );
-                               if ( $optgroup ) {
-                                       $options .= self::closeElement( 'optgroup' );
-                               }
-                               $options .= self::openElement( 'optgroup', [ 'label' => $value ] );
-                               $optgroup = true;
+                               $optgroup = $value;
                        } elseif ( substr( $value, 0, 2 ) == '**' ) {
-                               // groupmember
-                               $value = trim( substr( $value, 2 ) );
-                               $options .= self::option( $value, $value, $selected === $value );
-                       } else {
-                               // groupless reason list
-                               if ( $optgroup ) {
-                                       $options .= self::closeElement( 'optgroup' );
+                               # groupmember
+                               $opt = trim( substr( $value, 2 ) );
+                               if ( $optgroup === false ) {
+                                       $options[$opt] = $opt;
+                               } else {
+                                       $options[$optgroup][$opt] = $opt;
                                }
-                               $options .= self::option( $value, $value, $selected === $value );
+                       } else {
+                               # groupless reason list
                                $optgroup = false;
+                               $options[$option] = $option;
                        }
                }
 
-               if ( $optgroup ) {
-                       $options .= self::closeElement( 'optgroup' );
-               }
-
-               $attribs = [];
-
-               if ( $name ) {
-                       $attribs['id'] = $name;
-                       $attribs['name'] = $name;
-               }
+               return $options;
+       }
 
-               if ( $class ) {
-                       $attribs['class'] = $class;
-               }
+       /**
+        * Convert options for a drop-down box into a format accepted by OOUI\DropdownInputWidget etc.
+        *
+        * TODO Find a better home for this function.
+        *
+        * @param array $options Options, as returned e.g. by Xml::listDropDownOptions()
+        * @return array
+        */
+       public static function listDropDownOptionsOoui( $options ) {
+               $optionsOoui = [];
 
-               if ( $tabindex ) {
-                       $attribs['tabindex'] = $tabindex;
+               foreach ( $options as $text => $value ) {
+                       if ( is_array( $value ) ) {
+                               $optionsOoui[] = [ 'optgroup' => (string)$text ];
+                               foreach ( $value as $text2 => $value2 ) {
+                                       $optionsOoui[] = [ 'data' => (string)$value2, 'label' => (string)$text2 ];
+                               }
+                       } else {
+                               $optionsOoui[] = [ 'data' => (string)$value, 'label' => (string)$text ];
+                       }
                }
 
-               return Xml::openElement( 'select', $attribs )
-                       . "\n"
-                       . $options
-                       . "\n"
-                       . Xml::closeElement( 'select' );
+               return $optionsOoui;
        }
 
        /**
@@ -575,15 +608,15 @@ class Xml {
         * @return string
         */
        public static function fieldset( $legend = false, $content = false, $attribs = [] ) {
-               $s = Xml::openElement( 'fieldset', $attribs ) . "\n";
+               $s = self::openElement( 'fieldset', $attribs ) . "\n";
 
                if ( $legend ) {
-                       $s .= Xml::element( 'legend', null, $legend ) . "\n";
+                       $s .= self::element( 'legend', null, $legend ) . "\n";
                }
 
                if ( $content !== false ) {
                        $s .= $content . "\n";
-                       $s .= Xml::closeElement( 'fieldset' ) . "\n";
+                       $s .= self::closeElement( 'fieldset' ) . "\n";
                }
 
                return $s;
@@ -644,7 +677,7 @@ class Xml {
         */
        public static function encodeJsCall( $name, $args, $pretty = false ) {
                foreach ( $args as &$arg ) {
-                       $arg = Xml::encodeJsVar( $arg, $pretty );
+                       $arg = self::encodeJsVar( $arg, $pretty );
                        if ( $arg === false ) {
                                return false;
                        }
@@ -702,7 +735,7 @@ class Xml {
                        $text .
                        '</html>';
 
-               return Xml::isWellFormed( $html );
+               return self::isWellFormed( $html );
        }
 
        /**
@@ -736,25 +769,25 @@ class Xml {
 
                foreach ( $fields as $labelmsg => $input ) {
                        $id = "mw-$labelmsg";
-                       $form .= Xml::openElement( 'tr', [ 'id' => $id ] );
+                       $form .= self::openElement( 'tr', [ 'id' => $id ] );
 
                        // TODO use a <label> here for accessibility purposes - will need
                        // to either not use a table to build the form, or find the ID of
                        // the input somehow.
 
-                       $form .= Xml::tags( 'td', [ 'class' => 'mw-label' ], wfMessage( $labelmsg )->parse() );
-                       $form .= Xml::openElement( 'td', [ 'class' => 'mw-input' ] )
-                               . $input . Xml::closeElement( 'td' );
-                       $form .= Xml::closeElement( 'tr' );
+                       $form .= self::tags( 'td', [ 'class' => 'mw-label' ], wfMessage( $labelmsg )->parse() );
+                       $form .= self::openElement( 'td', [ 'class' => 'mw-input' ] )
+                               . $input . self::closeElement( 'td' );
+                       $form .= self::closeElement( 'tr' );
                }
 
                if ( $submitLabel ) {
-                       $form .= Xml::openElement( 'tr' );
-                       $form .= Xml::tags( 'td', [], '' );
-                       $form .= Xml::openElement( 'td', [ 'class' => 'mw-submit' ] )
-                               . Xml::submitButton( wfMessage( $submitLabel )->text(), $submitAttribs )
-                               . Xml::closeElement( 'td' );
-                       $form .= Xml::closeElement( 'tr' );
+                       $form .= self::openElement( 'tr' );
+                       $form .= self::tags( 'td', [], '' );
+                       $form .= self::openElement( 'td', [ 'class' => 'mw-submit' ] )
+                               . self::submitButton( wfMessage( $submitLabel )->text(), $submitAttribs )
+                               . self::closeElement( 'td' );
+                       $form .= self::closeElement( 'tr' );
                }
 
                $form .= "</tbody></table>";
@@ -770,10 +803,10 @@ class Xml {
         * @return string
         */
        public static function buildTable( $rows, $attribs = [], $headers = null ) {
-               $s = Xml::openElement( 'table', $attribs );
+               $s = self::openElement( 'table', $attribs );
 
                if ( is_array( $headers ) ) {
-                       $s .= Xml::openElement( 'thead', $attribs );
+                       $s .= self::openElement( 'thead', $attribs );
 
                        foreach ( $headers as $id => $header ) {
                                $attribs = [];
@@ -782,9 +815,9 @@ class Xml {
                                        $attribs['id'] = $id;
                                }
 
-                               $s .= Xml::element( 'th', $attribs, $header );
+                               $s .= self::element( 'th', $attribs, $header );
                        }
-                       $s .= Xml::closeElement( 'thead' );
+                       $s .= self::closeElement( 'thead' );
                }
 
                foreach ( $rows as $id => $row ) {
@@ -794,10 +827,10 @@ class Xml {
                                $attribs['id'] = $id;
                        }
 
-                       $s .= Xml::buildTableRow( $attribs, $row );
+                       $s .= self::buildTableRow( $attribs, $row );
                }
 
-               $s .= Xml::closeElement( 'table' );
+               $s .= self::closeElement( 'table' );
 
                return $s;
        }
@@ -809,7 +842,7 @@ class Xml {
         * @return string
         */
        public static function buildTableRow( $attribs, $cells ) {
-               $s = Xml::openElement( 'tr', $attribs );
+               $s = self::openElement( 'tr', $attribs );
 
                foreach ( $cells as $id => $cell ) {
                        $attribs = [];
@@ -818,10 +851,10 @@ class Xml {
                                $attribs['id'] = $id;
                        }
 
-                       $s .= Xml::element( 'td', $attribs, $cell );
+                       $s .= self::element( 'td', $attribs, $cell );
                }
 
-               $s .= Xml::closeElement( 'tr' );
+               $s .= self::closeElement( 'tr' );
 
                return $s;
        }