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