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