Mereged updates from DokuWiki 38
[sudaraka-org:dokuwiki-mods.git] / inc / Input.class.php
1 <?php
2
3 /**
4  * Encapsulates access to the $_REQUEST array, making sure used parameters are initialized and
5  * have the correct type.
6  *
7  * All function access the $_REQUEST array by default, if you want to access $_POST or $_GET
8  * explicitly use the $post and $get members.
9  *
10  * @author Andreas Gohr <andi@splitbrain.org>
11  */
12 class Input {
13
14     /** @var PostInput Access $_POST parameters */
15     public $post;
16     /** @var GetInput Access $_GET parameters */
17     public $get;
18
19     protected $access;
20
21     /**
22      * Intilizes the Input class and it subcomponents
23      */
24     function __construct() {
25         $this->access = &$_REQUEST;
26         $this->post   = new PostInput();
27         $this->get    = new GetInput();
28     }
29
30     /**
31      * Check if a parameter was set
32      *
33      * Basically a wrapper around isset. When called on the $post and $get subclasses,
34      * the parameter is set to $_POST or $_GET and to $_REQUEST
35      *
36      * @see isset
37      * @param string $name Parameter name
38      * @return bool
39      */
40     public function has($name) {
41         return isset($this->access[$name]);
42     }
43
44     /**
45      * Remove a parameter from the superglobals
46      *
47      * Basically a wrapper around unset. When NOT called on the $post and $get subclasses,
48      * the parameter will also be removed from $_POST or $_GET
49      *
50      * @see isset
51      * @param string $name Parameter name
52      * @return bool
53      */
54     public function remove($name) {
55         if(isset($this->access[$name])) {
56             unset($this->access[$name]);
57         }
58         // also remove from sub classes
59         if(isset($this->post) && isset($_POST[$name])) {
60             unset($_POST[$name]);
61         }
62         if(isset($this->get) && isset($_GET[$name])) {
63             unset($_GET[$name]);
64         }
65     }
66
67     /**
68      * Access a request parameter without any type conversion
69      *
70      * @param string    $name     Parameter name
71      * @param mixed     $default  Default to return if parameter isn't set
72      * @param bool      $nonempty Return $default if parameter is set but empty()
73      * @return mixed
74      */
75     public function param($name, $default = null, $nonempty = false) {
76         if(!isset($this->access[$name])) return $default;
77         if($nonempty && empty($this->access[$name])) return $default;
78         return $this->access[$name];
79     }
80
81     /**
82      * Sets a parameter
83      *
84      * @param string $name Parameter name
85      * @param mixed  $value Value to set
86      */
87     public function set($name, $value) {
88         $this->access[$name] = $value;
89     }
90
91     /**
92      * Get a reference to a request parameter
93      *
94      * This avoids copying data in memory, when the parameter is not set it will be created
95      * and intialized with the given $default value before a reference is returned
96      *
97      * @param string    $name Parameter name
98      * @param mixed     $default If parameter is not set, initialize with this value
99      * @param bool      $nonempty Init with $default if parameter is set but empty()
100      * @return &mixed
101      */
102     public function &ref($name, $default = '', $nonempty = false) {
103         if(!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) {
104             $this->set($name, $default);
105         }
106
107         return $this->access[$name];
108     }
109
110     /**
111      * Access a request parameter as int
112      *
113      * @param string    $name     Parameter name
114      * @param mixed     $default  Default to return if parameter isn't set or is an array
115      * @param bool      $nonempty Return $default if parameter is set but empty()
116      * @return int
117      */
118     public function int($name, $default = 0, $nonempty = false) {
119         if(!isset($this->access[$name])) return $default;
120         if(is_array($this->access[$name])) return $default;
121         if($this->access[$name] === '') return $default;
122         if($nonempty && empty($this->access[$name])) return $default;
123
124         return (int) $this->access[$name];
125     }
126
127     /**
128      * Access a request parameter as string
129      *
130      * @param string    $name     Parameter name
131      * @param mixed     $default  Default to return if parameter isn't set or is an array
132      * @param bool      $nonempty Return $default if parameter is set but empty()
133      * @return string
134      */
135     public function str($name, $default = '', $nonempty = false) {
136         if(!isset($this->access[$name])) return $default;
137         if(is_array($this->access[$name])) return $default;
138         if($nonempty && empty($this->access[$name])) return $default;
139
140         return (string) $this->access[$name];
141     }
142
143     /**
144      * Access a request parameter as bool
145      *
146      * Note: $nonempty is here for interface consistency and makes not much sense for booleans
147      *
148      * @param string    $name     Parameter name
149      * @param mixed     $default  Default to return if parameter isn't set
150      * @param bool      $nonempty Return $default if parameter is set but empty()
151      * @return bool
152      */
153     public function bool($name, $default = false, $nonempty = false) {
154         if(!isset($this->access[$name])) return $default;
155         if(is_array($this->access[$name])) return $default;
156         if($this->access[$name] === '') return $default;
157         if($nonempty && empty($this->access[$name])) return $default;
158
159         return (bool) $this->access[$name];
160     }
161
162     /**
163      * Access a request parameter as array
164      *
165      * @param string    $name     Parameter name
166      * @param mixed     $default  Default to return if parameter isn't set
167      * @param bool      $nonempty Return $default if parameter is set but empty()
168      * @return array
169      */
170     public function arr($name, $default = array(), $nonempty = false) {
171         if(!isset($this->access[$name])) return $default;
172         if(!is_array($this->access[$name])) return $default;
173         if($nonempty && empty($this->access[$name])) return $default;
174
175         return (array) $this->access[$name];
176     }
177
178     /**
179      * Create a simple key from an array key
180      *
181      * This is useful to access keys where the information is given as an array key or as a single array value.
182      * For example when the information was submitted as the name of a submit button.
183      *
184      * This function directly changes the access array.
185      *
186      * Eg. $_REQUEST['do']['save']='Speichern' becomes $_REQUEST['do'] = 'save'
187      *
188      * This function returns the $INPUT object itself for easy chaining
189      *
190      * @param $name
191      * @return Input
192      */
193     public function extract($name){
194         if(!isset($this->access[$name])) return $this;
195         if(!is_array($this->access[$name])) return $this;
196         $keys = array_keys($this->access[$name]);
197         if(!$keys){
198             // this was an empty array
199             $this->remove($name);
200             return $this;
201         }
202         // get the first key
203         $value = array_shift($keys);
204         if($value === 0){
205             // we had a numeric array, assume the value is not in the key
206             $value = array_shift($this->access[$name]);
207         }
208
209         $this->set($name, $value);
210         return $this;
211     }
212 }
213
214 /**
215  * Internal class used for $_POST access in Input class
216  */
217 class PostInput extends Input {
218     protected $access;
219
220     /**
221      * Initialize the $access array, remove subclass members
222      */
223     function __construct() {
224         $this->access = &$_POST;
225     }
226
227     /**
228      * Sets a parameter in $_POST and $_REQUEST
229      *
230      * @param string $name Parameter name
231      * @param mixed  $value Value to set
232      */
233     public function set($name, $value) {
234         parent::set($name, $value);
235         $_REQUEST[$name] = $value;
236     }
237 }
238
239 /**
240  * Internal class used for $_GET access in Input class
241
242  */
243 class GetInput extends Input {
244     protected $access;
245
246     /**
247      * Initialize the $access array, remove subclass members
248      */
249     function __construct() {
250         $this->access = &$_GET;
251     }
252
253     /**
254      * Sets a parameter in $_GET and $_REQUEST
255      *
256      * @param string $name Parameter name
257      * @param mixed  $value Value to set
258      */
259     public function set($name, $value) {
260         parent::set($name, $value);
261         $_REQUEST[$name] = $value;
262     }
263 }