MediaWiki
REL1_22
|
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 }