MediaWiki  master
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 
00090         public static function guessType( $data ) {
00091                 if ( is_bool( $data ) ) {
00092                         return self::BOOL;
00093                 } elseif ( is_int( $data ) ) {
00094                         return self::INT;
00095                 } elseif ( is_string( $data ) ) {
00096                         return self::STRING;
00097                 } else {
00098                         throw new MWException( 'Unsupported datatype' );
00099                 }
00100         }
00101 
00102         # Handling values
00103 
00112         public function validateName( $name, $strict = false ) {
00113                 if ( !isset( $this->options[$name] ) ) {
00114                         if ( $strict ) {
00115                                 throw new MWException( "Invalid option $name" );
00116                         } else {
00117                                 return false;
00118                         }
00119                 }
00120                 return true;
00121         }
00122 
00131         public function setValue( $name, $value, $force = false ) {
00132                 $this->validateName( $name, true );
00133 
00134                 if ( !$force && $value === $this->options[$name]['default'] ) {
00135                         // null default values as unchanged
00136                         $this->options[$name]['value'] = null;
00137                 } else {
00138                         $this->options[$name]['value'] = $value;
00139                 }
00140         }
00141 
00149         public function getValue( $name ) {
00150                 $this->validateName( $name, true );
00151 
00152                 return $this->getValueReal( $this->options[$name] );
00153         }
00154 
00160         protected function getValueReal( $option ) {
00161                 if ( $option['value'] !== null ) {
00162                         return $option['value'];
00163                 } else {
00164                         return $option['default'];
00165                 }
00166         }
00167 
00174         public function reset( $name ) {
00175                 $this->validateName( $name, true );
00176                 $this->options[$name]['value'] = null;
00177         }
00178 
00184         public function consumeValue( $name ) {
00185                 $this->validateName( $name, true );
00186                 $this->options[$name]['consumed'] = true;
00187 
00188                 return $this->getValueReal( $this->options[$name] );
00189         }
00190 
00196         public function consumeValues( /*Array*/ $names ) {
00197                 $out = array();
00198 
00199                 foreach ( $names as $name ) {
00200                         $this->validateName( $name, true );
00201                         $this->options[$name]['consumed'] = true;
00202                         $out[] = $this->getValueReal( $this->options[$name] );
00203                 }
00204 
00205                 return $out;
00206         }
00207 
00219         public function validateIntBounds( $name, $min, $max ) {
00220                 $this->validateName( $name, true );
00221 
00222                 if ( $this->options[$name]['type'] !== self::INT ) {
00223                         throw new MWException( "Option $name is not of type int" );
00224                 }
00225 
00226                 $value = $this->getValueReal( $this->options[$name] );
00227                 $value = max( $min, min( $max, $value ) );
00228 
00229                 $this->setValue( $name, $value );
00230         }
00231 
00237         public function getUnconsumedValues( $all = false ) {
00238                 $values = array();
00239 
00240                 foreach ( $this->options as $name => $data ) {
00241                         if ( !$data['consumed'] ) {
00242                                 if ( $all || $data['value'] !== null ) {
00243                                         $values[$name] = $this->getValueReal( $data );
00244                                 }
00245                         }
00246                 }
00247 
00248                 return $values;
00249         }
00250 
00255         public function getChangedValues() {
00256                 $values = array();
00257 
00258                 foreach ( $this->options as $name => $data ) {
00259                         if ( $data['value'] !== null ) {
00260                                 $values[$name] = $data['value'];
00261                         }
00262                 }
00263 
00264                 return $values;
00265         }
00266 
00271         public function getAllValues() {
00272                 $values = array();
00273 
00274                 foreach ( $this->options as $name => $data ) {
00275                         $values[$name] = $this->getValueReal( $data );
00276                 }
00277 
00278                 return $values;
00279         }
00280 
00281         # Reading values
00282 
00283         public function fetchValuesFromRequest( WebRequest $r, $values = false ) {
00284                 if ( !$values ) {
00285                         $values = array_keys( $this->options );
00286                 }
00287 
00288                 foreach ( $values as $name ) {
00289                         $default = $this->options[$name]['default'];
00290                         $type = $this->options[$name]['type'];
00291 
00292                         switch( $type ) {
00293                                 case self::BOOL:
00294                                         $value = $r->getBool( $name, $default ); break;
00295                                 case self::INT:
00296                                         $value = $r->getInt( $name, $default ); break;
00297                                 case self::STRING:
00298                                         $value = $r->getText( $name, $default ); break;
00299                                 case self::INTNULL:
00300                                         $value = $r->getIntOrNull( $name ); break;
00301                                 default:
00302                                         throw new MWException( 'Unsupported datatype' );
00303                         }
00304 
00305                         if ( $value !== null ) {
00306                                 $this->options[$name]['value'] = $value === $default ? null : $value;
00307                         }
00308                 }
00309         }
00310 
00315         /* @{ */
00320         public function offsetExists( $name ) {
00321                 return isset( $this->options[$name] );
00322         }
00327         public function offsetGet( $name ) {
00328                 return $this->getValue( $name );
00329         }
00331         public function offsetSet( $name, $value ) {
00332                 $this->setValue( $name, $value );
00333         }
00335         public function offsetUnset( $name ) {
00336                 $this->delete( $name );
00337         }
00338         /* @} */
00339 }