MediaWiki  REL1_20
FormOptions.php
Go to the documentation of this file.
00001 <?php
00033 class FormOptions implements ArrayAccess {
00037         /* @{ */
00039         const AUTO = -1;
00041         const STRING = 0;
00043         const INT = 1;
00045         const BOOL = 2;
00049         const INTNULL = 3;
00050         /* @} */
00051 
00055         protected $options = array();
00056 
00057         # Setting up
00058 
00059         public function add( $name, $default, $type = self::AUTO ) {
00060                 $option = array();
00061                 $option['default'] = $default;
00062                 $option['value'] = null;
00063                 $option['consumed'] = false;
00064 
00065                 if ( $type !== self::AUTO ) {
00066                         $option['type'] = $type;
00067                 } else {
00068                         $option['type'] = self::guessType( $default );
00069                 }
00070 
00071                 $this->options[$name] = $option;
00072         }
00073 
00074         public function delete( $name ) {
00075                 $this->validateName( $name, true );
00076                 unset( $this->options[$name] );
00077         }
00078 
00089         public static function guessType( $data ) {
00090                 if ( is_bool( $data ) ) {
00091                         return self::BOOL;
00092                 } elseif ( is_int( $data ) ) {
00093                         return self::INT;
00094                 } elseif ( is_string( $data ) ) {
00095                         return self::STRING;
00096                 } else {
00097                         throw new MWException( 'Unsupported datatype' );
00098                 }
00099         }
00100 
00101         # Handling values
00102 
00110         public function validateName( $name, $strict = false ) {
00111                 if ( !isset( $this->options[$name] ) ) {
00112                         if ( $strict ) {
00113                                 throw new MWException( "Invalid option $name" );
00114                         } else {
00115                                 return false;
00116                         }
00117                 }
00118                 return true;
00119         }
00120 
00129         public function setValue( $name, $value, $force = false ) {
00130                 $this->validateName( $name, true );
00131 
00132                 if ( !$force && $value === $this->options[$name]['default'] ) {
00133                         // null default values as unchanged
00134                         $this->options[$name]['value'] = null;
00135                 } else {
00136                         $this->options[$name]['value'] = $value;
00137                 }
00138         }
00139 
00147         public function getValue( $name ) {
00148                 $this->validateName( $name, true );
00149 
00150                 return $this->getValueReal( $this->options[$name] );
00151         }
00152 
00158         protected function getValueReal( $option ) {
00159                 if ( $option['value'] !== null ) {
00160                         return $option['value'];
00161                 } else {
00162                         return $option['default'];
00163                 }
00164         }
00165 
00172         public function reset( $name ) {
00173                 $this->validateName( $name, true );
00174                 $this->options[$name]['value'] = null;
00175         }
00176 
00182         public function consumeValue( $name ) {
00183                 $this->validateName( $name, true );
00184                 $this->options[$name]['consumed'] = true;
00185 
00186                 return $this->getValueReal( $this->options[$name] );
00187         }
00188 
00194         public function consumeValues( /*Array*/ $names ) {
00195                 $out = array();
00196 
00197                 foreach ( $names as $name ) {
00198                         $this->validateName( $name, true );
00199                         $this->options[$name]['consumed'] = true;
00200                         $out[] = $this->getValueReal( $this->options[$name] );
00201                 }
00202 
00203                 return $out;
00204         }
00205 
00216         public function validateIntBounds( $name, $min, $max ) {
00217                 $this->validateName( $name, true );
00218 
00219                 if ( $this->options[$name]['type'] !== self::INT ) {
00220                         throw new MWException( "Option $name is not of type int" );
00221                 }
00222 
00223                 $value = $this->getValueReal( $this->options[$name] );
00224                 $value = max( $min, min( $max, $value ) );
00225 
00226                 $this->setValue( $name, $value );
00227         }
00228 
00234         public function getUnconsumedValues( $all = false ) {
00235                 $values = array();
00236 
00237                 foreach ( $this->options as $name => $data ) {
00238                         if ( !$data['consumed'] ) {
00239                                 if ( $all || $data['value'] !== null ) {
00240                                         $values[$name] = $this->getValueReal( $data );
00241                                 }
00242                         }
00243                 }
00244 
00245                 return $values;
00246         }
00247 
00252         public function getChangedValues() {
00253                 $values = array();
00254 
00255                 foreach ( $this->options as $name => $data ) {
00256                         if ( $data['value'] !== null ) {
00257                                 $values[$name] = $data['value'];
00258                         }
00259                 }
00260 
00261                 return $values;
00262         }
00263 
00268         public function getAllValues() {
00269                 $values = array();
00270 
00271                 foreach ( $this->options as $name => $data ) {
00272                         $values[$name] = $this->getValueReal( $data );
00273                 }
00274 
00275                 return $values;
00276         }
00277 
00278         # Reading values
00279 
00280         public function fetchValuesFromRequest( WebRequest $r, $values = false ) {
00281                 if ( !$values ) {
00282                         $values = array_keys( $this->options );
00283                 }
00284 
00285                 foreach ( $values as $name ) {
00286                         $default = $this->options[$name]['default'];
00287                         $type = $this->options[$name]['type'];
00288 
00289                         switch( $type ) {
00290                                 case self::BOOL:
00291                                         $value = $r->getBool( $name, $default ); break;
00292                                 case self::INT:
00293                                         $value = $r->getInt( $name, $default ); break;
00294                                 case self::STRING:
00295                                         $value = $r->getText( $name, $default ); break;
00296                                 case self::INTNULL:
00297                                         $value = $r->getIntOrNull( $name ); break;
00298                                 default:
00299                                         throw new MWException( 'Unsupported datatype' );
00300                         }
00301 
00302                         if ( $value !== null ) {
00303                                 $this->options[$name]['value'] = $value === $default ? null : $value;
00304                         }
00305                 }
00306         }
00307 
00312         /* @{ */
00317         public function offsetExists( $name ) {
00318                 return isset( $this->options[$name] );
00319         }
00324         public function offsetGet( $name ) {
00325                 return $this->getValue( $name );
00326         }
00328         public function offsetSet( $name, $value ) {
00329                 $this->setValue( $name, $value );
00330         }
00332         public function offsetUnset( $name ) {
00333                 $this->delete( $name );
00334         }
00335         /* @} */
00336 }