]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/FormOptions.php
MediaWiki 1.14.0-scripts
[autoinstallsdev/mediawiki.git] / includes / FormOptions.php
1 <?php
2 /**
3  * Helper class to keep track of options when mixing links and form elements.
4  *
5  * @author Niklas Laxström
6  * @copyright Copyright © 2008, Niklas Laxström
7  */
8
9 class FormOptions implements ArrayAccess {
10         const AUTO = -1; //! Automatically detects simple data types
11         const STRING = 0;
12         const INT = 1;
13         const BOOL = 2;
14         const INTNULL = 3; //! Useful for namespace selector
15
16         protected $options = array();
17
18         # Setting up
19
20         public function add( $name, $default, $type = self::AUTO ) {
21                 $option = array();
22                 $option['default'] = $default;
23                 $option['value'] = null;
24                 $option['consumed'] = false;
25
26                 if ( $type !== self::AUTO ) {
27                         $option['type'] = $type;
28                 } else {
29                         $option['type'] = self::guessType( $default );
30                 }
31
32                 $this->options[$name] = $option;
33         }
34
35         public function delete( $name ) {
36                 $this->validateName( $name, true );
37                 unset($this->options[$name]);
38         }
39
40         public static function guessType( $data ) {
41                 if ( is_bool($data) ) {
42                         return self::BOOL;
43                 } elseif( is_int($data) ) {
44                         return self::INT;
45                 } elseif( is_string($data) ) {
46                         return self::STRING;
47                 } else {
48                         throw new MWException( 'Unsupported datatype' );
49                 }
50         }
51
52         # Handling values
53
54         public function validateName( $name, $strict = false ) {
55                 if ( !isset($this->options[$name]) ) {
56                         if ( $strict ) {
57                                 throw new MWException( "Invalid option $name" );
58                         } else {
59                                 return false;
60                         }
61                 }
62                 return true;
63         }
64
65         public function setValue( $name, $value, $force = false ) {
66                 $this->validateName( $name, true );
67                 if ( !$force && $value === $this->options[$name]['default'] ) {
68                         // null default values as unchanged
69                         $this->options[$name]['value'] = null;
70                 } else {
71                         $this->options[$name]['value'] = $value;
72                 }
73         }
74
75         public function getValue( $name ) {
76                 $this->validateName( $name, true );
77                 return $this->getValueReal( $this->options[$name] );
78         }
79
80         protected function getValueReal( $option ) {
81                 if ( $option['value'] !== null ) {
82                         return $option['value'];
83                 } else {
84                         return $option['default'];
85                 }
86         }
87
88         public function reset( $name ) {
89                 $this->validateName( $name, true );
90                 $this->options[$name]['value'] = null;
91         }
92
93         public function consumeValue( $name ) {
94                 $this->validateName( $name, true );
95                 $this->options[$name]['consumed'] = true;
96                 return $this->getValueReal( $this->options[$name] );
97         }
98
99         public function consumeValues( /*Array*/ $names ) {
100                 $out = array();
101                 foreach ( $names as $name ) {
102                         $this->validateName( $name, true );
103                         $this->options[$name]['consumed'] = true;
104                         $out[] = $this->getValueReal( $this->options[$name] );
105                 }
106                 return $out;
107         }
108
109         # Validating values
110
111         public function validateIntBounds( $name, $min, $max ) {
112                 $this->validateName( $name, true );
113
114                 if ( $this->options[$name]['type'] !== self::INT )
115                         throw new MWException( "Option $name is not of type int" );
116
117                 $value = $this->getValueReal( $this->options[$name] );
118                 $value = max( $min, min( $max, $value ) );
119
120                 $this->setValue( $name, $value );
121         }
122
123         # Getting the data out for use
124
125         public function getUnconsumedValues( $all = false ) {
126                 $values = array();
127                 foreach ( $this->options as $name => $data ) {
128                         if ( !$data['consumed'] ) {
129                                 if ( $all || $data['value'] !== null ) {
130                                         $values[$name] = $this->getValueReal( $data );
131                                 }
132                         }
133                 }
134                 return $values;
135         }
136
137         public function getChangedValues() {
138                 $values = array();
139                 foreach ( $this->options as $name => $data ) {
140                         if ( $data['value'] !== null ) {
141                                 $values[$name] = $data['value'];
142                         }
143                 }
144                 return $values;
145         }
146
147         public function getAllValues() {
148                 $values = array();
149                 foreach ( $this->options as $name => $data ) {
150                         $values[$name] = $this->getValueReal( $data );
151                 }
152                 return $values;
153         }
154
155         # Reading values
156
157         public function fetchValuesFromRequest( WebRequest $r, $values = false ) {
158                 if ( !$values ) {
159                         $values = array_keys($this->options);
160                 }
161
162                 foreach ( $values as $name ) {
163                         $default = $this->options[$name]['default'];
164                         $type = $this->options[$name]['type'];
165
166                         switch( $type ) {
167                                 case self::BOOL:
168                                         $value = $r->getBool( $name, $default ); break;
169                                 case self::INT:
170                                         $value = $r->getInt( $name, $default ); break;
171                                 case self::STRING:
172                                         $value = $r->getText( $name, $default ); break;
173                                 case self::INTNULL:
174                                         $value = $r->getIntOrNull( $name ); break;
175                                 default:
176                                         throw new MWException( 'Unsupported datatype' );
177                         }
178
179                         if ( $value !== null ) {
180                                 $this->options[$name]['value'] = $value === $default ? null : $value;
181                         }
182                 }
183         }
184
185         /* ArrayAccess methods */
186         public function offsetExists( $name ) {
187                 return isset($this->options[$name]);
188         }
189
190         public function offsetGet( $name ) {
191                 return $this->getValue( $name );
192         }
193
194         public function offsetSet( $name, $value ) {
195                 return $this->setValue( $name, $value );
196         }
197
198         public function offsetUnset( $name ) {
199                 return $this->delete( $name );
200         }
201
202 }