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