Merge pull request #2723 from splitbrain/install-useacl
[dokuwiki.git] / inc / Input.class.php
blob199994d8d7c7077185b9f6b77324ff85866c0204
1 <?php
3 /**
4 * Encapsulates access to the $_REQUEST array, making sure used parameters are initialized and
5 * have the correct type.
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.
10 * @author Andreas Gohr <andi@splitbrain.org>
12 class Input {
14 /** @var PostInput Access $_POST parameters */
15 public $post;
16 /** @var GetInput Access $_GET parameters */
17 public $get;
18 /** @var ServerInput Access $_SERVER parameters */
19 public $server;
21 protected $access;
23 /**
24 * @var Callable
26 protected $filter;
28 /**
29 * Intilizes the Input class and it subcomponents
31 function __construct() {
32 $this->access = &$_REQUEST;
33 $this->post = new PostInput();
34 $this->get = new GetInput();
35 $this->server = new ServerInput();
38 /**
39 * Apply the set filter to the given value
41 * @param string $data
42 * @return string
44 protected function applyfilter($data){
45 if(!$this->filter) return $data;
46 return call_user_func($this->filter, $data);
49 /**
50 * Return a filtered copy of the input object
52 * Expects a callable that accepts one string parameter and returns a filtered string
54 * @param Callable|string $filter
55 * @return Input
57 public function filter($filter='stripctl'){
58 $this->filter = $filter;
59 $clone = clone $this;
60 $this->filter = '';
61 return $clone;
64 /**
65 * Check if a parameter was set
67 * Basically a wrapper around isset. When called on the $post and $get subclasses,
68 * the parameter is set to $_POST or $_GET and to $_REQUEST
70 * @see isset
71 * @param string $name Parameter name
72 * @return bool
74 public function has($name) {
75 return isset($this->access[$name]);
78 /**
79 * Remove a parameter from the superglobals
81 * Basically a wrapper around unset. When NOT called on the $post and $get subclasses,
82 * the parameter will also be removed from $_POST or $_GET
84 * @see isset
85 * @param string $name Parameter name
87 public function remove($name) {
88 if(isset($this->access[$name])) {
89 unset($this->access[$name]);
91 // also remove from sub classes
92 if(isset($this->post) && isset($_POST[$name])) {
93 unset($_POST[$name]);
95 if(isset($this->get) && isset($_GET[$name])) {
96 unset($_GET[$name]);
101 * Access a request parameter without any type conversion
103 * @param string $name Parameter name
104 * @param mixed $default Default to return if parameter isn't set
105 * @param bool $nonempty Return $default if parameter is set but empty()
106 * @return mixed
108 public function param($name, $default = null, $nonempty = false) {
109 if(!isset($this->access[$name])) return $default;
110 $value = $this->applyfilter($this->access[$name]);
111 if($nonempty && empty($value)) return $default;
112 return $value;
116 * Sets a parameter
118 * @param string $name Parameter name
119 * @param mixed $value Value to set
121 public function set($name, $value) {
122 $this->access[$name] = $value;
126 * Get a reference to a request parameter
128 * This avoids copying data in memory, when the parameter is not set it will be created
129 * and intialized with the given $default value before a reference is returned
131 * @param string $name Parameter name
132 * @param mixed $default If parameter is not set, initialize with this value
133 * @param bool $nonempty Init with $default if parameter is set but empty()
134 * @return mixed (reference)
136 public function &ref($name, $default = '', $nonempty = false) {
137 if(!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) {
138 $this->set($name, $default);
141 return $this->access[$name];
145 * Access a request parameter as int
147 * @param string $name Parameter name
148 * @param int $default Default to return if parameter isn't set or is an array
149 * @param bool $nonempty Return $default if parameter is set but empty()
150 * @return int
152 public function int($name, $default = 0, $nonempty = false) {
153 if(!isset($this->access[$name])) return $default;
154 if(is_array($this->access[$name])) return $default;
155 $value = $this->applyfilter($this->access[$name]);
156 if($value === '') return $default;
157 if($nonempty && empty($value)) return $default;
159 return (int) $value;
163 * Access a request parameter as string
165 * @param string $name Parameter name
166 * @param string $default Default to return if parameter isn't set or is an array
167 * @param bool $nonempty Return $default if parameter is set but empty()
168 * @return string
170 public function str($name, $default = '', $nonempty = false) {
171 if(!isset($this->access[$name])) return $default;
172 if(is_array($this->access[$name])) return $default;
173 $value = $this->applyfilter($this->access[$name]);
174 if($nonempty && empty($value)) return $default;
176 return (string) $value;
180 * Access a request parameter and make sure it is has a valid value
182 * Please note that comparisons to the valid values are not done typesafe (request vars
183 * are always strings) however the function will return the correct type from the $valids
184 * array when an match was found.
186 * @param string $name Parameter name
187 * @param array $valids Array of valid values
188 * @param mixed $default Default to return if parameter isn't set or not valid
189 * @return null|mixed
191 public function valid($name, $valids, $default = null) {
192 if(!isset($this->access[$name])) return $default;
193 if(is_array($this->access[$name])) return $default; // we don't allow arrays
194 $value = $this->applyfilter($this->access[$name]);
195 $found = array_search($value, $valids);
196 if($found !== false) return $valids[$found]; // return the valid value for type safety
197 return $default;
201 * Access a request parameter as bool
203 * Note: $nonempty is here for interface consistency and makes not much sense for booleans
205 * @param string $name Parameter name
206 * @param mixed $default Default to return if parameter isn't set
207 * @param bool $nonempty Return $default if parameter is set but empty()
208 * @return bool
210 public function bool($name, $default = false, $nonempty = false) {
211 if(!isset($this->access[$name])) return $default;
212 if(is_array($this->access[$name])) return $default;
213 $value = $this->applyfilter($this->access[$name]);
214 if($value === '') return $default;
215 if($nonempty && empty($value)) return $default;
217 return (bool) $value;
221 * Access a request parameter as array
223 * @param string $name Parameter name
224 * @param mixed $default Default to return if parameter isn't set
225 * @param bool $nonempty Return $default if parameter is set but empty()
226 * @return array
228 public function arr($name, $default = array(), $nonempty = false) {
229 if(!isset($this->access[$name])) return $default;
230 if(!is_array($this->access[$name])) return $default;
231 if($nonempty && empty($this->access[$name])) return $default;
233 return (array) $this->access[$name];
237 * Create a simple key from an array key
239 * This is useful to access keys where the information is given as an array key or as a single array value.
240 * For example when the information was submitted as the name of a submit button.
242 * This function directly changes the access array.
244 * Eg. $_REQUEST['do']['save']='Speichern' becomes $_REQUEST['do'] = 'save'
246 * This function returns the $INPUT object itself for easy chaining
248 * @param string $name
249 * @return Input
251 public function extract($name){
252 if(!isset($this->access[$name])) return $this;
253 if(!is_array($this->access[$name])) return $this;
254 $keys = array_keys($this->access[$name]);
255 if(!$keys){
256 // this was an empty array
257 $this->remove($name);
258 return $this;
260 // get the first key
261 $value = array_shift($keys);
262 if($value === 0){
263 // we had a numeric array, assume the value is not in the key
264 $value = array_shift($this->access[$name]);
267 $this->set($name, $value);
268 return $this;
273 * Internal class used for $_POST access in Input class
275 class PostInput extends Input {
276 protected $access;
279 * Initialize the $access array, remove subclass members
281 function __construct() {
282 $this->access = &$_POST;
286 * Sets a parameter in $_POST and $_REQUEST
288 * @param string $name Parameter name
289 * @param mixed $value Value to set
291 public function set($name, $value) {
292 parent::set($name, $value);
293 $_REQUEST[$name] = $value;
298 * Internal class used for $_GET access in Input class
300 class GetInput extends Input {
301 protected $access;
304 * Initialize the $access array, remove subclass members
306 function __construct() {
307 $this->access = &$_GET;
311 * Sets a parameter in $_GET and $_REQUEST
313 * @param string $name Parameter name
314 * @param mixed $value Value to set
316 public function set($name, $value) {
317 parent::set($name, $value);
318 $_REQUEST[$name] = $value;
323 * Internal class used for $_SERVER access in Input class
325 class ServerInput extends Input {
326 protected $access;
329 * Initialize the $access array, remove subclass members
331 function __construct() {
332 $this->access = &$_SERVER;