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