MediaWiki  REL1_19
FormOptions.php
Go to the documentation of this file.
00001 <?php
00014 class FormOptions implements ArrayAccess {
00018         /* @{ */
00020         const AUTO = -1;
00022         const STRING = 0;
00024         const INT = 1;
00026         const BOOL = 2;
00030         const INTNULL = 3;
00031         /* @} */
00032 
00036         protected $options = array();
00037 
00038         # Setting up
00039 
00040         public function add( $name, $default, $type = self::AUTO ) {
00041                 $option = array();
00042                 $option['default'] = $default;
00043                 $option['value'] = null;
00044                 $option['consumed'] = false;
00045 
00046                 if ( $type !== self::AUTO ) {
00047                         $option['type'] = $type;
00048                 } else {
00049                         $option['type'] = self::guessType( $default );
00050                 }
00051 
00052                 $this->options[$name] = $option;
00053         }
00054 
00055         public function delete( $name ) {
00056                 $this->validateName( $name, true );
00057                 unset( $this->options[$name] );
00058         }
00059 
00070         public static function guessType( $data ) {
00071                 if ( is_bool( $data ) ) {
00072                         return self::BOOL;
00073                 } elseif ( is_int( $data ) ) {
00074                         return self::INT;
00075                 } elseif ( is_string( $data ) ) {
00076                         return self::STRING;
00077                 } else {
00078                         throw new MWException( 'Unsupported datatype' );
00079                 }
00080         }
00081 
00082         # Handling values
00083 
00091         public function validateName( $name, $strict = false ) {
00092                 if ( !isset( $this->options[$name] ) ) {
00093                         if ( $strict ) {
00094                                 throw new MWException( "Invalid option $name" );
00095                         } else {
00096                                 return false;
00097                         }
00098                 }
00099                 return true;
00100         }
00101 
00110         public function setValue( $name, $value, $force = false ) {
00111                 $this->validateName( $name, true );
00112 
00113                 if ( !$force && $value === $this->options[$name]['default'] ) {
00114                         // null default values as unchanged
00115                         $this->options[$name]['value'] = null;
00116                 } else {
00117                         $this->options[$name]['value'] = $value;
00118                 }
00119         }
00120 
00128         public function getValue( $name ) {
00129                 $this->validateName( $name, true );
00130 
00131                 return $this->getValueReal( $this->options[$name] );
00132         }
00133 
00139         protected function getValueReal( $option ) {
00140                 if ( $option['value'] !== null ) {
00141                         return $option['value'];
00142                 } else {
00143                         return $option['default'];
00144                 }
00145         }
00146 
00153         public function reset( $name ) {
00154                 $this->validateName( $name, true );
00155                 $this->options[$name]['value'] = null;
00156         }
00157 
00163         public function consumeValue( $name ) {
00164                 $this->validateName( $name, true );
00165                 $this->options[$name]['consumed'] = true;
00166 
00167                 return $this->getValueReal( $this->options[$name] );
00168         }
00169 
00175         public function consumeValues( /*Array*/ $names ) {
00176                 $out = array();
00177 
00178                 foreach ( $names as $name ) {
00179                         $this->validateName( $name, true );
00180                         $this->options[$name]['consumed'] = true;
00181                         $out[] = $this->getValueReal( $this->options[$name] );
00182                 }
00183 
00184                 return $out;
00185         }
00186 
00197         public function validateIntBounds( $name, $min, $max ) {
00198                 $this->validateName( $name, true );
00199 
00200                 if ( $this->options[$name]['type'] !== self::INT ) {
00201                         throw new MWException( "Option $name is not of type int" );
00202                 }
00203 
00204                 $value = $this->getValueReal( $this->options[$name] );
00205                 $value = max( $min, min( $max, $value ) );
00206 
00207                 $this->setValue( $name, $value );
00208         }
00209 
00215         public function getUnconsumedValues( $all = false ) {
00216                 $values = array();
00217 
00218                 foreach ( $this->options as $name => $data ) {
00219                         if ( !$data['consumed'] ) {
00220                                 if ( $all || $data['value'] !== null ) {
00221                                         $values[$name] = $this->getValueReal( $data );
00222                                 }
00223                         }
00224                 }
00225 
00226                 return $values;
00227         }
00228 
00233         public function getChangedValues() {
00234                 $values = array();
00235 
00236                 foreach ( $this->options as $name => $data ) {
00237                         if ( $data['value'] !== null ) {
00238                                 $values[$name] = $data['value'];
00239                         }
00240                 }
00241 
00242                 return $values;
00243         }
00244 
00249         public function getAllValues() {
00250                 $values = array();
00251 
00252                 foreach ( $this->options as $name => $data ) {
00253                         $values[$name] = $this->getValueReal( $data );
00254                 }
00255 
00256                 return $values;
00257         }
00258 
00259         # Reading values
00260 
00261         public function fetchValuesFromRequest( WebRequest $r, $values = false ) {
00262                 if ( !$values ) {
00263                         $values = array_keys( $this->options );
00264                 }
00265 
00266                 foreach ( $values as $name ) {
00267                         $default = $this->options[$name]['default'];
00268                         $type = $this->options[$name]['type'];
00269 
00270                         switch( $type ) {
00271                                 case self::BOOL:
00272                                         $value = $r->getBool( $name, $default ); break;
00273                                 case self::INT:
00274                                         $value = $r->getInt( $name, $default ); break;
00275                                 case self::STRING:
00276                                         $value = $r->getText( $name, $default ); break;
00277                                 case self::INTNULL:
00278                                         $value = $r->getIntOrNull( $name ); break;
00279                                 default:
00280                                         throw new MWException( 'Unsupported datatype' );
00281                         }
00282 
00283                         if ( $value !== null ) {
00284                                 $this->options[$name]['value'] = $value === $default ? null : $value;
00285                         }
00286                 }
00287         }
00288 
00293         /* @{ */
00295         public function offsetExists( $name ) {
00296                 return isset( $this->options[$name] );
00297         }
00299         public function offsetGet( $name ) {
00300                 return $this->getValue( $name );
00301         }
00303         public function offsetSet( $name, $value ) {
00304                 $this->setValue( $name, $value );
00305         }
00307         public function offsetUnset( $name ) {
00308                 $this->delete( $name );
00309         }
00310         /* @} */
00311 }