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