Merge "Allow setting the ID of the main table in HTMLForm"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 28 May 2013 21:23:44 +0000 (21:23 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 28 May 2013 21:23:44 +0000 (21:23 +0000)
1  2 
includes/HTMLForm.php

diff --combined includes/HTMLForm.php
@@@ -140,6 -140,7 +140,7 @@@ class HTMLForm extends ContextSource 
        protected $mSectionFooters = array();
        protected $mPost = '';
        protected $mId;
+       protected $mTableId = '';
  
        protected $mSubmitID;
        protected $mSubmitName;
                        $this->setContext( $context );
                        $this->mTitle = false; // We don't need them to set a title
                        $this->mMessagePrefix = $messagePrefix;
 -              } else {
 +              } elseif ( is_null( $context ) && $messagePrefix !== '' ) {
 +                      $this->mMessagePrefix = $messagePrefix;
 +              } elseif ( is_string( $context ) && $messagePrefix === '' ) {
                        // B/C since 1.18
 -                      if ( is_string( $context ) && $messagePrefix === '' ) {
 -                              // it's actually $messagePrefix
 -                              $this->mMessagePrefix = $context;
 -                      }
 +                      // it's actually $messagePrefix
 +                      $this->mMessagePrefix = $context;
                }
  
                // Expand out into a tree.
         * @return String
         */
        function getBody() {
-               return $this->displaySection( $this->mFieldTree );
+               return $this->displaySection( $this->mFieldTree, $this->mTableId );
        }
  
        /**
                return $this;
        }
  
+       /**
+        * Set the id of the \<table\> or outermost \<div\> element.
+        *
+        * @since 1.22
+        * @param string $id new value of the id attribute, or "" to remove
+        * @return HTMLForm $this for chaining calls
+        */
+       public function setTableId( $id ) {
+               $this->mTableId = $id;
+               return $this;
+       }
        /**
         * @param string $id DOM id for the form
         * @return HTMLForm $this for chaining calls (since 1.20)
                $this->mId = $id;
                return $this;
        }
        /**
         * Prompt the whole form to be wrapped in a "<fieldset>", with
         * this text as its "<legend>" element.
                                        $hasLabel = true;
                                }
                        } elseif ( is_array( $value ) ) {
-                               $section = $this->displaySection( $value, $key, "$fieldsetIDPrefix$key-" );
+                               $section = $this->displaySection( $value, "mw-htmlform-$key", "$fieldsetIDPrefix$key-" );
                                $legend = $this->getLegend( $key );
                                if ( isset( $this->mSectionHeaders[$key] ) ) {
                                        $section = $this->mSectionHeaders[$key] . $section;
                        );
  
                        if ( $sectionName ) {
-                               $attribs['id'] = Sanitizer::escapeId( "mw-htmlform-$sectionName" );
+                               $attribs['id'] = Sanitizer::escapeId( $sectionName );
                        }
  
                        if ( $displayFormat === 'table' ) {
@@@ -1844,33 -1858,9 +1858,33 @@@ class HTMLCheckField extends HTMLFormFi
   * A checkbox matrix
   * Operates similarly to HTMLMultiSelectField, but instead of using an array of
   * options, uses an array of rows and an array of columns to dynamically
 - * construct a matrix of options.
 + * construct a matrix of options. The tags used to identify a particular cell
 + * are of the form "columnName-rowName"
 + *
 + * Options:
 + *   columns:           Required list of columns in the matrix.
 + *   rows:              Required list of rows in the matrix.
 + *   force-options-on:  Accepts array of column-row tags to be displayed as enabled
 + *                      but unavailable to change
 + *   force-options-off: Accepts array of column-row tags to be displayed as disabled
 + *                      but unavailable to change.
   */
 -class HTMLCheckMatrix extends HTMLFormField {
 +class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
 +
 +      static private $requiredParams = array(
 +              // Required by underlying HTMLFormField
 +              'fieldname',
 +              // Required by HTMLCheckMatrix
 +              'rows', 'columns'
 +      );
 +
 +      public function __construct( $params ) {
 +              $missing = array_diff( self::$requiredParams, array_keys( $params ) );
 +              if ( $missing ) {
 +                      throw HTMLFormFieldRequiredOptionsException::create( $this, $missing );
 +              }
 +              parent::__construct( $params );
 +      }
  
        function validate( $value, $alldata ) {
                $rows = $this->mParams['rows'];
                foreach ( $rows as $rowLabel => $rowTag ) {
                        $rowContents = Html::rawElement( 'td', array(), $rowLabel );
                        foreach ( $columns as $columnTag ) {
 -                              // Knock out any options that are not wanted
 -                              if ( isset( $this->mParams['remove-options'] )
 -                                      && in_array( "$columnTag-$rowTag", $this->mParams['remove-options'] ) )
 -                              {
 -                                      $rowContents .= Html::rawElement( 'td', array(), '&#160;' );
 -                              } else {
 -                                      // Construct the checkbox
 -                                      $thisAttribs = array(
 -                                              'id' => "{$this->mID}-$columnTag-$rowTag",
 -                                              'value' => $columnTag . '-' . $rowTag
 -                                      );
 -                                      $checkbox = Xml::check(
 -                                              $this->mName . '[]',
 -                                              in_array( $columnTag . '-' . $rowTag, (array)$value, true ),
 -                                              $attribs + $thisAttribs );
 -                                      $rowContents .= Html::rawElement( 'td', array(), $checkbox );
 +                              $thisTag = "$columnTag-$rowTag";
 +                              // Construct the checkbox
 +                              $thisAttribs = array(
 +                                      'id' => "{$this->mID}-$thisTag",
 +                                      'value' => $thisTag,
 +                              );
 +                              $checked = in_array( $thisTag, (array)$value, true );
 +                              if ( $this->isTagForcedOff( $thisTag ) ) {
 +                                      $checked = false;
 +                                      $thisAttribs['disabled'] = 1;
 +                              } elseif ( $this->isTagForcedOn( $thisTag ) ) {
 +                                      $checked = true;
 +                                      $thisAttribs['disabled'] = 1;
                                }
 +                              $rowContents .= Html::rawElement(
 +                                      'td',
 +                                      array(),
 +                                      Xml::check( "{$this->mName}[]", $checked, $attribs + $thisAttribs )
 +                              );
                        }
                        $tableContents .= Html::rawElement( 'tr', array(), "\n$rowContents\n" );
                }
                return $html;
        }
  
 +      protected function isTagForcedOff( $tag ) {
 +              return isset( $this->mParams['force-options-off'] )
 +                      && in_array( $tag, $this->mParams['force-options-off'] );
 +      }
 +
 +      protected function isTagForcedOn( $tag ) {
 +              return isset( $this->mParams['force-options-on'] )
 +                      && in_array( $tag, $this->mParams['force-options-on'] );
 +      }
 +
        /**
         * Get the complete table row for the input, including help text,
         * labels, and whatever.
                        return array();
                }
        }
 +
 +      function filterDataForSubmit( $data ) {
 +              $columns = HTMLFormField::flattenOptions( $this->mParams['columns'] );
 +              $rows = HTMLFormField::flattenOptions( $this->mParams['rows'] );
 +              $res = array();
 +              foreach ( $columns as $column ) {
 +                      foreach ( $rows as $row ) {
 +                              // Make sure option hasn't been forced
 +                              $thisTag = "$column-$row";
 +                              if ( $this->isTagForcedOff( $thisTag ) ) {
 +                                      $res[$thisTag] = false;
 +                              } elseif ( $this->isTagForcedOn( $thisTag ) ) {
 +                                      $res[$thisTag] = true;
 +                              } else {
 +                                      $res[$thisTag] = in_array( $thisTag, $data );
 +                              }
 +                      }
 +              }
 +
 +              return $res;
 +      }
  }
  
  /**
@@@ -2200,7 -2157,7 +2214,7 @@@ class HTMLSelectOrOtherField extends HT
  /**
   * Multi-select field
   */
 -class HTMLMultiSelectField extends HTMLFormField {
 +class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable {
  
        function validate( $value, $alldata ) {
                $p = parent::validate( $value, $alldata );
                }
        }
  
 +      function filterDataForSubmit( $data ) {
 +              $options = HTMLFormField::flattenOptions( $this->mParams['options'] );
 +
 +              $res = array();
 +              foreach ( $options as $opt ) {
 +                      $res["$opt"] = in_array( $opt, $data );
 +              }
 +
 +              return $res;
 +      }
 +
        protected function needsLabel() {
                return false;
        }
@@@ -2759,22 -2705,3 +2773,22 @@@ class HTMLApiField extends HTMLFormFiel
                return '';
        }
  }
 +
 +interface HTMLNestedFilterable {
 +      /**
 +       * Support for seperating multi-option preferences into multiple preferences
 +       * Due to lack of array support.
 +       * @param $data array
 +       */
 +      function filterDataForSubmit( $data );
 +}
 +
 +class HTMLFormFieldRequiredOptionsException extends MWException {
 +      static public function create( HTMLFormField $field, array $missing ) {
 +              return new self( sprintf(
 +                      "Form type `%s` expected the following parameters to be set: %s",
 +                      get_class( $field ),
 +                      implode( ', ', $missing )
 +              ) );
 +      }
 +}