diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
commit | 370e83bb0dfd0c70de268c93bf07ad5ee0897192 (patch) | |
tree | 491674f4c242e4d6ba0d04eafa305174c35a3391 /includes/FormOptions.php | |
parent | f4debf0f12d0524d2b2427c55ea3f16b680fad97 (diff) |
Update auf 1.13.0
Diffstat (limited to 'includes/FormOptions.php')
-rw-r--r-- | includes/FormOptions.php | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/includes/FormOptions.php b/includes/FormOptions.php new file mode 100644 index 00000000..5888a0c4 --- /dev/null +++ b/includes/FormOptions.php @@ -0,0 +1,202 @@ +<?php +/** + * Helper class to keep track of options when mixing links and form elements. + * + * @author Niklas Laxström + * @copyright Copyright © 2008, Niklas Laxström + */ + +class FormOptions implements ArrayAccess { + const AUTO = -1; //! Automatically detects simple data types + const STRING = 0; + const INT = 1; + const BOOL = 2; + const INTNULL = 3; //! Useful for namespace selector + + protected $options = array(); + + # Setting up + + public function add( $name, $default, $type = self::AUTO ) { + $option = array(); + $option['default'] = $default; + $option['value'] = null; + $option['consumed'] = false; + + if ( $type !== self::AUTO ) { + $option['type'] = $type; + } else { + $option['type'] = self::guessType( $default ); + } + + $this->options[$name] = $option; + } + + public function delete( $name ) { + $this->validateName( $name, true ); + unset($this->options[$name]); + } + + public static function guessType( $data ) { + if ( is_bool($data) ) { + return self::BOOL; + } elseif( is_int($data) ) { + return self::INT; + } elseif( is_string($data) ) { + return self::STRING; + } else { + throw new MWException( 'Unsupported datatype' ); + } + } + + # Handling values + + public function validateName( $name, $strict = false ) { + if ( !isset($this->options[$name]) ) { + if ( $strict ) { + throw new MWException( "Invalid option $name" ); + } else { + return false; + } + } + return true; + } + + public function setValue( $name, $value, $force = false ) { + $this->validateName( $name, true ); + if ( !$force && $value === $this->options[$name]['default'] ) { + // null default values as unchanged + $this->options[$name]['value'] = null; + } else { + $this->options[$name]['value'] = $value; + } + } + + public function getValue( $name ) { + $this->validateName( $name, true ); + return $this->getValueReal( $this->options[$name] ); + } + + protected function getValueReal( $option ) { + if ( $option['value'] !== null ) { + return $option['value']; + } else { + return $option['default']; + } + } + + public function reset( $name ) { + $this->validateName( $name, true ); + $this->options[$name]['value'] = null; + } + + public function consumeValue( $name ) { + $this->validateName( $name, true ); + $this->options[$name]['consumed'] = true; + return $this->getValueReal( $this->options[$name] ); + } + + public function consumeValues( /*Array*/ $names ) { + $out = array(); + foreach ( $names as $name ) { + $this->validateName( $name, true ); + $this->options[$name]['consumed'] = true; + $out[] = $this->getValueReal( $this->options[$name] ); + } + return $out; + } + + # Validating values + + public function validateIntBounds( $name, $min, $max ) { + $this->validateName( $name, true ); + + if ( $this->options[$name]['type'] !== self::INT ) + throw new MWException( "Option $name is not of type int" ); + + $value = $this->getValueReal( $this->options[$name] ); + $value = max( $min, min( $max, $value ) ); + + $this->setValue( $name, $value ); + } + + # Getting the data out for use + + public function getUnconsumedValues( $all = false ) { + $values = array(); + foreach ( $this->options as $name => $data ) { + if ( !$data['consumed'] ) { + if ( $all || $data['value'] !== null ) { + $values[$name] = $this->getValueReal( $data ); + } + } + } + return $values; + } + + public function getChangedValues() { + $values = array(); + foreach ( $this->options as $name => $data ) { + if ( $data['value'] !== null ) { + $values[$name] = $data['value']; + } + } + return $values; + } + + public function getAllValues() { + $values = array(); + foreach ( $this->options as $name => $data ) { + $values[$name] = $this->getValueReal( $data ); + } + return $values; + } + + # Reading values + + public function fetchValuesFromRequest( WebRequest $r, $values = false ) { + if ( !$values ) { + $values = array_keys($this->options); + } + + foreach ( $values as $name ) { + $default = $this->options[$name]['default']; + $type = $this->options[$name]['type']; + + switch( $type ) { + case self::BOOL: + $value = $r->getBool( $name, $default ); break; + case self::INT: + $value = $r->getInt( $name, $default ); break; + case self::STRING: + $value = $r->getText( $name, $default ); break; + case self::INTNULL: + $value = $r->getIntOrNull( $name ); break; + default: + throw new MWException( 'Unsupported datatype' ); + } + + if ( $value !== $default && $value !== null ) { + $this->options[$name]['value'] = $value; + } + } + } + + /* ArrayAccess methods */ + public function offsetExists( $name ) { + return isset($this->options[$name]); + } + + public function offsetGet( $name ) { + return $this->getValue( $name ); + } + + public function offsetSet( $name, $value ) { + return $this->setValue( $name, $value ); + } + + public function offsetUnset( $name ) { + return $this->delete( $name ); + } + +} |