MediaWiki  REL1_21
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 
00185         public function consumeValue( $name ) {
00186                 $this->validateName( $name, true );
00187                 $this->options[$name]['consumed'] = true;
00188 
00189                 return $this->getValueReal( $this->options[$name] );
00190         }
00191 
00197         public function consumeValues( /*Array*/ $names ) {
00198                 $out = array();
00199 
00200                 foreach ( $names as $name ) {
00201                         $this->validateName( $name, true );
00202                         $this->options[$name]['consumed'] = true;
00203                         $out[] = $this->getValueReal( $this->options[$name] );
00204                 }
00205 
00206                 return $out;
00207         }
00208 
00220         public function validateIntBounds( $name, $min, $max ) {
00221                 $this->validateName( $name, true );
00222 
00223                 if ( $this->options[$name]['type'] !== self::INT ) {
00224                         throw new MWException( "Option $name is not of type int" );
00225                 }
00226 
00227                 $value = $this->getValueReal( $this->options[$name] );
00228                 $value = max( $min, min( $max, $value ) );
00229 
00230                 $this->setValue( $name, $value );
00231         }
00232 
00238         public function getUnconsumedValues( $all = false ) {
00239                 $values = array();
00240 
00241                 foreach ( $this->options as $name => $data ) {
00242                         if ( !$data['consumed'] ) {
00243                                 if ( $all || $data['value'] !== null ) {
00244                                         $values[$name] = $this->getValueReal( $data );
00245                                 }
00246                         }
00247                 }
00248 
00249                 return $values;
00250         }
00251 
00256         public function getChangedValues() {
00257                 $values = array();
00258 
00259                 foreach ( $this->options as $name => $data ) {
00260                         if ( $data['value'] !== null ) {
00261                                 $values[$name] = $data['value'];
00262                         }
00263                 }
00264 
00265                 return $values;
00266         }
00267 
00272         public function getAllValues() {
00273                 $values = array();
00274 
00275                 foreach ( $this->options as $name => $data ) {
00276                         $values[$name] = $this->getValueReal( $data );
00277                 }
00278 
00279                 return $values;
00280         }
00281 
00282         # Reading values
00283 
00284         public function fetchValuesFromRequest( WebRequest $r, $values = false ) {
00285                 if ( !$values ) {
00286                         $values = array_keys( $this->options );
00287                 }
00288 
00289                 foreach ( $values as $name ) {
00290                         $default = $this->options[$name]['default'];
00291                         $type = $this->options[$name]['type'];
00292 
00293                         switch( $type ) {
00294                                 case self::BOOL:
00295                                         $value = $r->getBool( $name, $default ); break;
00296                                 case self::INT:
00297                                         $value = $r->getInt( $name, $default ); break;
00298                                 case self::STRING:
00299                                         $value = $r->getText( $name, $default ); break;
00300                                 case self::INTNULL:
00301                                         $value = $r->getIntOrNull( $name ); break;
00302                                 default:
00303                                         throw new MWException( 'Unsupported datatype' );
00304                         }
00305 
00306                         if ( $value !== null ) {
00307                                 $this->options[$name]['value'] = $value === $default ? null : $value;
00308                         }
00309                 }
00310         }
00311 
00316         /* @{ */
00321         public function offsetExists( $name ) {
00322                 return isset( $this->options[$name] );
00323         }
00328         public function offsetGet( $name ) {
00329                 return $this->getValue( $name );
00330         }
00332         public function offsetSet( $name, $value ) {
00333                 $this->setValue( $name, $value );
00334         }
00336         public function offsetUnset( $name ) {
00337                 $this->delete( $name );
00338         }
00339         /* @} */
00340 }