3 * Helper class to keep track of options when mixing links and form elements.
5 * @author Niklas Laxström
6 * @copyright Copyright © 2008, Niklas Laxström
10 const AUTO
= -1; //! Automatically detects simple data types
14 const INTNULL
= 3; //! Useful for namespace selector
16 protected $options = array();
20 public function add( $name, $default, $type = self
::AUTO
) {
22 $option['default'] = $default;
23 $option['value'] = null;
24 $option['consumed'] = false;
26 if ( $type !== self
::AUTO
) {
27 $option['type'] = $type;
29 $option['type'] = self
::guessType( $default );
32 $this->options
[$name] = $option;
35 public static function guessType( $data ) {
36 if ( is_bool($data) ) {
38 } elseif( is_int($data) ) {
40 } elseif( is_string($data) ) {
43 throw new MWException( 'Unsupported datatype' );
49 public function validateName( $name, $strict = false ) {
50 if ( !isset($this->options
[$name]) ) {
52 throw new MWException( "Invalid option $name" );
60 public function setValue( $name, $value, $force = false ) {
61 $this->validateName( $name, true );
62 if ( !$force && $value === $this->options
[$name]['default'] ) {
63 // null default values as unchanged
64 $this->options
[$name]['value'] = null;
66 $this->options
[$name]['value'] = $value;
70 public function getValue( $name ) {
71 $this->validateName( $name, true );
72 return $this->getValueReal( $this->options
[$name] );
75 protected function getValueReal( $option ) {
76 if ( $option['value'] !== null ) {
77 return $option['value'];
79 return $option['default'];
83 public function consumeValue( $name ) {
84 $this->validateName( $name, true );
85 $this->options
[$name]['consumed'] = true;
86 return $this->getValueReal( $this->options
[$name] );
89 public function consumeValues( /*Array*/ $names ) {
91 foreach ( $names as $name ) {
92 $this->validateName( $name, true );
93 $this->options
[$name]['consumed'] = true;
94 $out[] = $this->getValueReal( $this->options
[$name] );
101 public function validateIntBounds( $name, $min, $max ) {
102 $this->validateName( $name, true );
104 if ( $this->options
[$name]['type'] !== self
::INT )
105 throw new MWException( "Option $name is not of type int" );
107 $value = $this->getValueReal( $this->options
[$name] );
108 $value = max( $min, min( $max, $value ) );
110 $this->setValue( $name, $value );
113 # Getting the data out for use
115 public function getUnconsumedValues( $all = false ) {
117 foreach ( $this->options
as $name => $data ) {
118 if ( !$data['consumed'] ) {
119 if ( $all ||
$data['value'] !== null ) {
120 $values[$name] = $this->getValueReal( $data );
127 public function getChangedValues() {
129 foreach ( $this->options
as $name => $data ) {
130 if ( $data['value'] !== null ) {
131 $values[$name] = $data['value'];
139 public function fetchValuesFromRequest( WebRequest
$r ) {
140 foreach ( array_keys($this->options
) as $name ) {
141 $default = $this->options
[$name]['default'];
142 $type = $this->options
[$name]['type'];
146 $value = $r->getBool( $name, $default ); break;
148 $value = $r->getInt( $name, $default ); break;
150 $value = $r->getText( $name, $default ); break;
152 $value = $r->getIntOrNull( $name ); break;
154 throw new MWException( 'Unsupported datatype' );
157 if ( $value !== $default && $value !== null ) {
158 $this->options
[$name]['value'] = $value;