[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Simulates a full DokuWiki HTTP Request and allows 4 * runtime inspection. 5 */ 6 7 use dokuwiki\Input\Input; 8 9 /** 10 * Helper class to execute a fake request 11 */ 12 class TestRequest { 13 14 protected $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php', '/lib/exe/ajax.php'); 15 protected $script; 16 17 protected $server = array(); 18 protected $session = array(); 19 protected $get = array(); 20 protected $post = array(); 21 protected $data = array(); 22 23 /** @var string stores the output buffer, even when it's flushed */ 24 protected $output_buffer = ''; 25 26 /** @var null|TestRequest the currently running request */ 27 static protected $running = null; 28 29 /** 30 * Get a $_SERVER var 31 * 32 * @param string $key 33 * @return mixed 34 */ 35 public function getServer($key) { 36 return $this->server[$key]; 37 } 38 39 /** 40 * Get a $_SESSION var 41 * 42 * @param string $key 43 * @return mixed 44 */ 45 public function getSession($key) { 46 return $this->session[$key]; 47 } 48 49 /** 50 * Get a $_GET var 51 * 52 * @param string $key 53 * @return mixed 54 */ 55 public function getGet($key) { 56 return $this->get[$key]; 57 } 58 59 /** 60 * Get a $_POST var 61 * 62 * @param string $key 63 * @return mixed 64 */ 65 public function getPost($key) { 66 return $this->post[$key]; 67 } 68 69 /** 70 * Get the script that will execute the request 71 * 72 * @return string 73 */ 74 public function getScript() { 75 return $this->script; 76 } 77 78 /** 79 * Set a $_SERVER var 80 * 81 * @param string $key 82 * @param mixed $value 83 */ 84 public function setServer($key, $value) { 85 $this->server[$key] = $value; 86 } 87 88 /** 89 * Set a $_SESSION var 90 * 91 * @param string $key 92 * @param mixed $value 93 */ 94 public function setSession($key, $value) { 95 $this->session[$key] = $value; 96 } 97 98 /** 99 * Set a $_GET var 100 * 101 * @param string $key 102 * @param mixed $value 103 */ 104 public function setGet($key, $value) { 105 $this->get[$key] = $value; 106 } 107 108 /** 109 * Set a $_POST var 110 * 111 * @param string $key 112 * @param mixed $value 113 */ 114 public function setPost($key, $value) { 115 $this->post[$key] = $value; 116 } 117 118 /** 119 * Executes the request 120 * 121 * @param string $uri end URL to simulate, needs to be one of the testable scripts 122 * @return TestResponse the resulting output of the request 123 */ 124 public function execute($uri = '/doku.php') { 125 global $INPUT; 126 127 // save old environment 128 $server = $_SERVER; 129 $session = $_SESSION; 130 $get = $_GET; 131 $post = $_POST; 132 $request = $_REQUEST; 133 $input = $INPUT; 134 135 // prepare the right URI 136 $this->setUri($uri); 137 138 // import all defined globals into the function scope 139 foreach(array_keys($GLOBALS) as $glb) { 140 global $$glb; 141 } 142 143 // fake environment 144 global $default_server_vars; 145 $_SERVER = array_merge($default_server_vars, $this->server); 146 $_SESSION = $this->session; 147 $_GET = $this->get; 148 $_POST = $this->post; 149 $_REQUEST = array_merge($_GET, $_POST); 150 151 // reset output buffer 152 $this->output_buffer = ''; 153 154 // now execute dokuwiki and grep the output 155 self::$running = $this; 156 header_remove(); 157 ob_start(array($this, 'ob_start_callback')); 158 $INPUT = new Input(); 159 include(DOKU_INC . $this->script); 160 ob_end_flush(); 161 self::$running = null; 162 163 // create the response object 164 $response = new TestResponse( 165 $this->output_buffer, 166 // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli 167 (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()), 168 $this->data 169 ); 170 171 // reset environment 172 $_SERVER = $server; 173 $_SESSION = $session; 174 $_GET = $get; 175 $_POST = $post; 176 $_REQUEST = $request; 177 $INPUT = $input; 178 179 return $response; 180 } 181 182 /** 183 * Set the virtual URI the request works against 184 * 185 * This parses the given URI and sets any contained GET variables 186 * but will not overwrite any previously set ones (eg. set via setGet()). 187 * 188 * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] 189 * with all set GET variables. 190 * 191 * @param string $uri end URL to simulate 192 * @throws Exception when an invalid script is passed 193 */ 194 protected function setUri($uri) { 195 if(!preg_match('#^(' . join('|', $this->valid_scripts) . ')#', $uri)) { 196 throw new Exception("$uri \n--- only " . join(', ', $this->valid_scripts) . " are supported currently"); 197 } 198 199 $params = array(); 200 list($uri, $query) = sexplode('?', $uri, 2); 201 if($query) parse_str($query, $params); 202 203 $this->script = substr($uri, 1); 204 $this->get = array_merge($params, $this->get); 205 if(count($this->get)) { 206 $query = '?' . http_build_query($this->get, '', '&'); 207 $query = str_replace( 208 array('%3A', '%5B', '%5D'), 209 array(':', '[', ']'), 210 $query 211 ); 212 $uri = $uri . $query; 213 } 214 215 $this->setServer('QUERY_STRING', $query); 216 $this->setServer('REQUEST_URI', $uri); 217 } 218 219 /** 220 * Simulate a POST request with the given variables 221 * 222 * @param array $post all the POST parameters to use 223 * @param string $uri end URL to simulate 224 * @return TestResponse 225 */ 226 public function post($post = array(), $uri = '/doku.php') { 227 $this->post = array_merge($this->post, $post); 228 $this->setServer('REQUEST_METHOD', 'POST'); 229 return $this->execute($uri); 230 } 231 232 /** 233 * Simulate a GET request with the given variables 234 * 235 * @param array $get all the GET parameters to use 236 * @param string $uri end URL to simulate 237 * @return TestResponse 238 */ 239 public function get($get = array(), $uri = '/doku.php') { 240 $this->get = array_merge($this->get, $get); 241 $this->setServer('REQUEST_METHOD', 'GET'); 242 return $this->execute($uri); 243 } 244 245 /** 246 * Callback for ob_start 247 * 248 * This continues to fill our own buffer, even when some part 249 * of the code askes for flushing the buffers 250 * 251 * @param string $buffer 252 */ 253 public function ob_start_callback($buffer) { 254 $this->output_buffer .= $buffer; 255 } 256 257 /** 258 * Access the TestRequest from the executed code 259 * 260 * This allows certain functions to access the TestRequest that is accessing them 261 * to add additional info. 262 * 263 * @return null|TestRequest the currently executed request if any 264 */ 265 public static function getRunning() { 266 return self::$running; 267 } 268 269 /** 270 * Store data to be read in the response later 271 * 272 * When called multiple times with the same key, the data is appended to this 273 * key's array 274 * 275 * @param string $key the identifier for this information 276 * @param mixed $value arbitrary data to store 277 */ 278 public function addData($key, $value) { 279 if(!isset($this->data[$key])) $this->data[$key] = array(); 280 $this->data[$key][] = $value; 281 } 282 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body