MediaWiki  REL1_22
FormOptions.php
Go to the documentation of this file.
00001 <?php
00034 class FormOptions implements ArrayAccess {
00038     /* @{ */
00040     const AUTO = -1;
00042     const STRING = 0;
00044     const INT = 1;
00046     const BOOL = 2;
00050     const INTNULL = 3;
00051     /* @} */
00052 
00063     protected $options = array();
00064 
00065     # Setting up
00066 
00074     public function add( $name, $default, $type = self::AUTO ) {
00075         $option = array();
00076         $option['default'] = $default;
00077         $option['value'] = null;
00078         $option['consumed'] = false;
00079 
00080         if ( $type !== self::AUTO ) {
00081             $option['type'] = $type;
00082         } else {
00083             $option['type'] = self::guessType( $default );
00084         }
00085 
00086         $this->options[$name] = $option;
00087     }
00088 
00094     public function delete( $name ) {
00095         $this->validateName( $name, true );
00096         unset( $this->options[$name] );
00097     }
00098 
00110     public static function guessType( $data ) {
00111         if ( is_bool( $data ) ) {
00112             return self::BOOL;
00113         } elseif ( is_int( $data ) ) {
00114             return self::INT;
00115         } elseif ( is_string( $data ) ) {
00116             return self::STRING;
00117         } else {
00118             throw new MWException( 'Unsupported datatype' );
00119         }
00120     }
00121 
00122     # Handling values
00123 
00132     public function validateName( $name, $strict = false ) {
00133         if ( !isset( $this->options[$name] ) ) {
00134             if ( $strict ) {
00135                 throw new MWException( "Invalid option $name" );
00136             } else {
00137                 return false;
00138             }
00139         }
00140 
00141         return true;
00142     }
00143 
00152     public function setValue( $name, $value, $force = false ) {
00153         $this->validateName( $name, true );
00154 
00155         if ( !$force && $value === $this->options[$name]['default'] ) {
00156             // null default values as unchanged
00157             $this->options[$name]['value'] = null;
00158         } else {
00159             $this->options[$name]['value'] = $value;
00160         }
00161     }
00162 
00169     public function getValue( $name ) {
00170         $this->validateName( $name, true );
00171 
00172         return $this->getValueReal( $this->options[$name] );
00173     }
00174 
00181     protected function getValueReal( $option ) {
00182         if ( $option['value'] !== null ) {
00183             return $option['value'];
00184         } else {
00185             return $option['default'];
00186         }
00187     }
00188 
00194     public function reset( $name ) {
00195         $this->validateName( $name, true );
00196         $this->options[$name]['value'] = null;
00197     }
00198 
00208     public function consumeValue( $name ) {
00209         $this->validateName( $name, true );
00210         $this->options[$name]['consumed'] = true;
00211 
00212         return $this->getValueReal( $this->options[$name] );
00213     }
00214 
00224     public function consumeValues( $names ) {
00225         $out = array();
00226 
00227         foreach ( $names as $name ) {
00228             $this->validateName( $name, true );
00229             $this->options[$name]['consumed'] = true;
00230             $out[] = $this->getValueReal( $this->options[$name] );
00231         }
00232 
00233         return $out;
00234     }
00235 
00245     public function validateIntBounds( $name, $min, $max ) {
00246         $this->validateName( $name, true );
00247 
00248         if ( $this->options[$name]['type'] !== self::INT ) {
00249             throw new MWException( "Option $name is not of type int" );
00250         }
00251 
00252         $value = $this->getValueReal( $this->options[$name] );
00253         $value = max( $min, min( $max, $value ) );
00254 
00255         $this->setValue( $name, $value );
00256     }
00257 
00264     public function getUnconsumedValues( $all = false ) {
00265         $values = array();
00266 
00267         foreach ( $this->options as $name => $data ) {
00268             if ( !$data['consumed'] ) {
00269                 if ( $all || $data['value'] !== null ) {
00270                     $values[$name] = $this->getValueReal( $data );
00271                 }
00272             }
00273         }
00274 
00275         return $values;
00276     }
00277 
00282     public function getChangedValues() {
00283         $values = array();
00284 
00285         foreach ( $this->options as $name => $data ) {
00286             if ( $data['value'] !== null ) {
00287                 $values[$name] = $data['value'];
00288             }
00289         }
00290 
00291         return $values;
00292     }
00293 
00298     public function getAllValues() {
00299         $values = array();
00300 
00301         foreach ( $this->options as $name => $data ) {
00302             $values[$name] = $this->getValueReal( $data );
00303         }
00304 
00305         return $values;
00306     }
00307 
00308     # Reading values
00309 
00320     public function fetchValuesFromRequest( WebRequest $r, $optionKeys = null ) {
00321         if ( !$optionKeys ) {
00322             $optionKeys = array_keys( $this->options );
00323         }
00324 
00325         foreach ( $optionKeys as $name ) {
00326             $default = $this->options[$name]['default'];
00327             $type = $this->options[$name]['type'];
00328 
00329             switch ( $type ) {
00330                 case self::BOOL:
00331                     $value = $r->getBool( $name, $default );
00332                     break;
00333                 case self::INT:
00334                     $value = $r->getInt( $name, $default );
00335                     break;
00336                 case self::STRING:
00337                     $value = $r->getText( $name, $default );
00338                     break;
00339                 case self::INTNULL:
00340                     $value = $r->getIntOrNull( $name );
00341                     break;
00342                 default:
00343                     throw new MWException( 'Unsupported datatype' );
00344             }
00345 
00346             if ( $value !== null ) {
00347                 $this->options[$name]['value'] = $value === $default ? null : $value;
00348             }
00349         }
00350     }
00351 
00356     /* @{ */
00358     public function offsetExists( $name ) {
00359         return isset( $this->options[$name] );
00360     }
00361 
00363     public function offsetGet( $name ) {
00364         return $this->getValue( $name );
00365     }
00366 
00368     public function offsetSet( $name, $value ) {
00369         $this->setValue( $name, $value );
00370     }
00371 
00373     public function offsetUnset( $name ) {
00374         $this->delete( $name );
00375     }
00376     /* @} */
00377 }