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