[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/htmlform/ -> HTMLCheckMatrix.php (source)

   1  <?php
   2  
   3  /**
   4   * A checkbox matrix
   5   * Operates similarly to HTMLMultiSelectField, but instead of using an array of
   6   * options, uses an array of rows and an array of columns to dynamically
   7   * construct a matrix of options. The tags used to identify a particular cell
   8   * are of the form "columnName-rowName"
   9   *
  10   * Options:
  11   *   - columns
  12   *     - Required list of columns in the matrix.
  13   *   - rows
  14   *     - Required list of rows in the matrix.
  15   *   - force-options-on
  16   *     - Accepts array of column-row tags to be displayed as enabled but unavailable to change
  17   *   - force-options-off
  18   *     - Accepts array of column-row tags to be displayed as disabled but unavailable to change.
  19   *   - tooltips
  20   *     - Optional array mapping row label to tooltip content
  21   *   - tooltip-class
  22   *     - Optional CSS class used on tooltip container span. Defaults to mw-icon-question.
  23   */
  24  class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
  25      static private $requiredParams = array(
  26          // Required by underlying HTMLFormField
  27          'fieldname',
  28          // Required by HTMLCheckMatrix
  29          'rows',
  30          'columns'
  31      );
  32  
  33  	public function __construct( $params ) {
  34          $missing = array_diff( self::$requiredParams, array_keys( $params ) );
  35          if ( $missing ) {
  36              throw new HTMLFormFieldRequiredOptionsException( $this, $missing );
  37          }
  38          parent::__construct( $params );
  39      }
  40  
  41  	function validate( $value, $alldata ) {
  42          $rows = $this->mParams['rows'];
  43          $columns = $this->mParams['columns'];
  44  
  45          // Make sure user-defined validation callback is run
  46          $p = parent::validate( $value, $alldata );
  47          if ( $p !== true ) {
  48              return $p;
  49          }
  50  
  51          // Make sure submitted value is an array
  52          if ( !is_array( $value ) ) {
  53              return false;
  54          }
  55  
  56          // If all options are valid, array_intersect of the valid options
  57          // and the provided options will return the provided options.
  58          $validOptions = array();
  59          foreach ( $rows as $rowTag ) {
  60              foreach ( $columns as $columnTag ) {
  61                  $validOptions[] = $columnTag . '-' . $rowTag;
  62              }
  63          }
  64          $validValues = array_intersect( $value, $validOptions );
  65          if ( count( $validValues ) == count( $value ) ) {
  66              return true;
  67          } else {
  68              return $this->msg( 'htmlform-select-badoption' )->parse();
  69          }
  70      }
  71  
  72      /**
  73       * Build a table containing a matrix of checkbox options.
  74       * The value of each option is a combination of the row tag and column tag.
  75       * mParams['rows'] is an array with row labels as keys and row tags as values.
  76       * mParams['columns'] is an array with column labels as keys and column tags as values.
  77       *
  78       * @param array $value Array of the options that should be checked
  79       *
  80       * @return string
  81       */
  82  	function getInputHTML( $value ) {
  83          $html = '';
  84          $tableContents = '';
  85          $rows = $this->mParams['rows'];
  86          $columns = $this->mParams['columns'];
  87  
  88          $attribs = $this->getAttributes( array( 'disabled', 'tabindex' ) );
  89  
  90          // Build the column headers
  91          $headerContents = Html::rawElement( 'td', array(), '&#160;' );
  92          foreach ( $columns as $columnLabel => $columnTag ) {
  93              $headerContents .= Html::rawElement( 'td', array(), $columnLabel );
  94          }
  95          $tableContents .= Html::rawElement( 'tr', array(), "\n$headerContents\n" );
  96  
  97          $tooltipClass = 'mw-icon-question';
  98          if ( isset( $this->mParams['tooltip-class'] ) ) {
  99              $tooltipClass = $this->mParams['tooltip-class'];
 100          }
 101  
 102          // Build the options matrix
 103          foreach ( $rows as $rowLabel => $rowTag ) {
 104              // Append tooltip if configured
 105              if ( isset( $this->mParams['tooltips'][$rowLabel] ) ) {
 106                  $tooltipAttribs = array(
 107                      'class' => "mw-htmlform-tooltip $tooltipClass",
 108                      'title' => $this->mParams['tooltips'][$rowLabel],
 109                  );
 110                  $rowLabel .= ' ' . Html::element( 'span', $tooltipAttribs, '' );
 111              }
 112              $rowContents = Html::rawElement( 'td', array(), $rowLabel );
 113              foreach ( $columns as $columnTag ) {
 114                  $thisTag = "$columnTag-$rowTag";
 115                  // Construct the checkbox
 116                  $thisId = "{$this->mID}-$thisTag";
 117                  $thisAttribs = array(
 118                      'id' => $thisId,
 119                      'value' => $thisTag,
 120                  );
 121                  $checked = in_array( $thisTag, (array)$value, true );
 122                  if ( $this->isTagForcedOff( $thisTag ) ) {
 123                      $checked = false;
 124                      $thisAttribs['disabled'] = 1;
 125                  } elseif ( $this->isTagForcedOn( $thisTag ) ) {
 126                      $checked = true;
 127                      $thisAttribs['disabled'] = 1;
 128                  }
 129                  $chkBox = Xml::check( "{$this->mName}[]", $checked, $attribs + $thisAttribs );
 130                  if ( $this->mParent->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
 131                      $chkBox = Html::openElement( 'div', array( 'class' => 'mw-ui-checkbox' ) ) .
 132                          $chkBox .
 133                          Html::element( 'label', array( 'for' => $thisId ) ) .
 134                          Html::closeElement( 'div' );
 135                  }
 136                  $rowContents .= Html::rawElement(
 137                      'td',
 138                      array(),
 139                      $chkBox
 140                  );
 141              }
 142              $tableContents .= Html::rawElement( 'tr', array(), "\n$rowContents\n" );
 143          }
 144  
 145          // Put it all in a table
 146          $html .= Html::rawElement( 'table',
 147                  array( 'class' => 'mw-htmlform-matrix' ),
 148                  Html::rawElement( 'tbody', array(), "\n$tableContents\n" ) ) . "\n";
 149  
 150          return $html;
 151      }
 152  
 153  	protected function isTagForcedOff( $tag ) {
 154          return isset( $this->mParams['force-options-off'] )
 155              && in_array( $tag, $this->mParams['force-options-off'] );
 156      }
 157  
 158  	protected function isTagForcedOn( $tag ) {
 159          return isset( $this->mParams['force-options-on'] )
 160              && in_array( $tag, $this->mParams['force-options-on'] );
 161      }
 162  
 163      /**
 164       * Get the complete table row for the input, including help text,
 165       * labels, and whatever.
 166       * We override this function since the label should always be on a separate
 167       * line above the options in the case of a checkbox matrix, i.e. it's always
 168       * a "vertical-label".
 169       *
 170       * @param string $value The value to set the input to
 171       *
 172       * @return string Complete HTML table row
 173       */
 174  	function getTableRow( $value ) {
 175          list( $errors, $errorClass ) = $this->getErrorsAndErrorClass( $value );
 176          $inputHtml = $this->getInputHTML( $value );
 177          $fieldType = get_class( $this );
 178          $helptext = $this->getHelpTextHtmlTable( $this->getHelpText() );
 179          $cellAttributes = array( 'colspan' => 2 );
 180  
 181          $label = $this->getLabelHtml( $cellAttributes );
 182  
 183          $field = Html::rawElement(
 184              'td',
 185              array( 'class' => 'mw-input' ) + $cellAttributes,
 186              $inputHtml . "\n$errors"
 187          );
 188  
 189          $html = Html::rawElement( 'tr', array( 'class' => 'mw-htmlform-vertical-label' ), $label );
 190          $html .= Html::rawElement( 'tr',
 191              array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass" ),
 192              $field );
 193  
 194          return $html . $helptext;
 195      }
 196  
 197      /**
 198       * @param WebRequest $request
 199       *
 200       * @return array
 201       */
 202  	function loadDataFromRequest( $request ) {
 203          if ( $this->mParent->getMethod() == 'post' ) {
 204              if ( $request->wasPosted() ) {
 205                  // Checkboxes are not added to the request arrays if they're not checked,
 206                  // so it's perfectly possible for there not to be an entry at all
 207                  return $request->getArray( $this->mName, array() );
 208              } else {
 209                  // That's ok, the user has not yet submitted the form, so show the defaults
 210                  return $this->getDefault();
 211              }
 212          } else {
 213              // This is the impossible case: if we look at $_GET and see no data for our
 214              // field, is it because the user has not yet submitted the form, or that they
 215              // have submitted it with all the options unchecked. We will have to assume the
 216              // latter, which basically means that you can't specify 'positive' defaults
 217              // for GET forms.
 218              return $request->getArray( $this->mName, array() );
 219          }
 220      }
 221  
 222  	function getDefault() {
 223          if ( isset( $this->mDefault ) ) {
 224              return $this->mDefault;
 225          } else {
 226              return array();
 227          }
 228      }
 229  
 230  	function filterDataForSubmit( $data ) {
 231          $columns = HTMLFormField::flattenOptions( $this->mParams['columns'] );
 232          $rows = HTMLFormField::flattenOptions( $this->mParams['rows'] );
 233          $res = array();
 234          foreach ( $columns as $column ) {
 235              foreach ( $rows as $row ) {
 236                  // Make sure option hasn't been forced
 237                  $thisTag = "$column-$row";
 238                  if ( $this->isTagForcedOff( $thisTag ) ) {
 239                      $res[$thisTag] = false;
 240                  } elseif ( $this->isTagForcedOn( $thisTag ) ) {
 241                      $res[$thisTag] = true;
 242                  } else {
 243                      $res[$thisTag] = in_array( $thisTag, $data );
 244                  }
 245              }
 246          }
 247  
 248          return $res;
 249      }
 250  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1