1f8369d7dSTobias Sarnowski<?php 2f8369d7dSTobias Sarnowski/** 3f8369d7dSTobias Sarnowski * Simulates a full DokuWiki HTTP Request and allows 4f8369d7dSTobias Sarnowski * runtime inspection. 5f8369d7dSTobias Sarnowski */ 6f8369d7dSTobias Sarnowski 7f8369d7dSTobias Sarnowski// output buffering 8f8369d7dSTobias Sarnowski$output_buffer = ''; 9f8369d7dSTobias Sarnowski 10*572dc222SLarsDW223$currentTestRequest = null; 11*572dc222SLarsDW223 12f8369d7dSTobias Sarnowskifunction ob_start_callback($buffer) { 13f8369d7dSTobias Sarnowski global $output_buffer; 14f8369d7dSTobias Sarnowski $output_buffer .= $buffer; 15f8369d7dSTobias Sarnowski} 16f8369d7dSTobias Sarnowski 17f8369d7dSTobias Sarnowski 18f8369d7dSTobias Sarnowski/** 19f8369d7dSTobias Sarnowski * Helper class to execute a fake request 20f8369d7dSTobias Sarnowski */ 21f8369d7dSTobias Sarnowskiclass TestRequest { 22f8369d7dSTobias Sarnowski 239894e7afSChristopher Smith private $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php'); 249894e7afSChristopher Smith private $script; 259894e7afSChristopher Smith 26f8369d7dSTobias Sarnowski private $server = array(); 27f8369d7dSTobias Sarnowski private $session = array(); 28f8369d7dSTobias Sarnowski private $get = array(); 29f8369d7dSTobias Sarnowski private $post = array(); 30*572dc222SLarsDW223 private $notifications = array(); 31f8369d7dSTobias Sarnowski 32f8369d7dSTobias Sarnowski public function getServer($key) { return $this->server[$key]; } 33f8369d7dSTobias Sarnowski public function getSession($key) { return $this->session[$key]; } 34f8369d7dSTobias Sarnowski public function getGet($key) { return $this->get[$key]; } 35f8369d7dSTobias Sarnowski public function getPost($key) { return $this->post[$key]; } 369894e7afSChristopher Smith public function getScript() { return $this->script; } 37f8369d7dSTobias Sarnowski 38f8369d7dSTobias Sarnowski public function setServer($key, $value) { $this->server[$key] = $value; } 39f8369d7dSTobias Sarnowski public function setSession($key, $value) { $this->session[$key] = $value; } 40f8369d7dSTobias Sarnowski public function setGet($key, $value) { $this->get[$key] = $value; } 41f8369d7dSTobias Sarnowski public function setPost($key, $value) { $this->post[$key] = $value; } 42f8369d7dSTobias Sarnowski 43f8369d7dSTobias Sarnowski /** 44f8369d7dSTobias Sarnowski * Executes the request 45f8369d7dSTobias Sarnowski * 464d053d04SAndreas Gohr * @param string $url end URL to simulate, needs to start with /doku.php currently 47f8369d7dSTobias Sarnowski * @return TestResponse the resulting output of the request 48f8369d7dSTobias Sarnowski */ 494d053d04SAndreas Gohr public function execute($uri='/doku.php') { 50fe717f57Slisps global $INPUT; 51*572dc222SLarsDW223 global $currentTestRequest; 52*572dc222SLarsDW223 53*572dc222SLarsDW223 $currentTestRequest = $this; 54fe717f57Slisps 55f8369d7dSTobias Sarnowski // save old environment 56f8369d7dSTobias Sarnowski $server = $_SERVER; 57f8369d7dSTobias Sarnowski $session = $_SESSION; 58f8369d7dSTobias Sarnowski $get = $_GET; 59f8369d7dSTobias Sarnowski $post = $_POST; 60f8369d7dSTobias Sarnowski $request = $_REQUEST; 61fe717f57Slisps $input = $INPUT; 62f8369d7dSTobias Sarnowski 634d053d04SAndreas Gohr // prepare the right URI 644d053d04SAndreas Gohr $this->setUri($uri); 654d053d04SAndreas Gohr 660189bd86SAndreas Gohr // import all defined globals into the function scope 670189bd86SAndreas Gohr foreach(array_keys($GLOBALS) as $glb){ 680189bd86SAndreas Gohr global $$glb; 690189bd86SAndreas Gohr } 700189bd86SAndreas Gohr 71f8369d7dSTobias Sarnowski // fake environment 72f8369d7dSTobias Sarnowski global $default_server_vars; 73f8369d7dSTobias Sarnowski $_SERVER = array_merge($default_server_vars, $this->server); 74f8369d7dSTobias Sarnowski $_SESSION = $this->session; 75f8369d7dSTobias Sarnowski $_GET = $this->get; 76f8369d7dSTobias Sarnowski $_POST = $this->post; 77f8369d7dSTobias Sarnowski $_REQUEST = array_merge($_GET, $_POST); 78f8369d7dSTobias Sarnowski 79f8369d7dSTobias Sarnowski // reset output buffer 80f8369d7dSTobias Sarnowski global $output_buffer; 81f8369d7dSTobias Sarnowski $output_buffer = ''; 82f8369d7dSTobias Sarnowski 83f8369d7dSTobias Sarnowski // now execute dokuwiki and grep the output 84f8369d7dSTobias Sarnowski header_remove(); 85f8369d7dSTobias Sarnowski ob_start('ob_start_callback'); 86fe717f57Slisps $INPUT = new Input(); 879894e7afSChristopher Smith include(DOKU_INC.$this->script); 88f8369d7dSTobias Sarnowski ob_end_flush(); 89f8369d7dSTobias Sarnowski 90f8369d7dSTobias Sarnowski // create the response object 91f8369d7dSTobias Sarnowski $response = new TestResponse( 92f8369d7dSTobias Sarnowski $output_buffer, 939894e7afSChristopher Smith (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()) // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli 94f8369d7dSTobias Sarnowski ); 95*572dc222SLarsDW223 if ($this->notifications != null) { 96*572dc222SLarsDW223 $response->setNotifications($this->notifications); 97*572dc222SLarsDW223 } 98f8369d7dSTobias Sarnowski 99f8369d7dSTobias Sarnowski // reset environment 100f8369d7dSTobias Sarnowski $_SERVER = $server; 101f8369d7dSTobias Sarnowski $_SESSION = $session; 102f8369d7dSTobias Sarnowski $_GET = $get; 103f8369d7dSTobias Sarnowski $_POST = $post; 104f8369d7dSTobias Sarnowski $_REQUEST = $request; 105fe717f57Slisps $INPUT = $input; 106f8369d7dSTobias Sarnowski 107*572dc222SLarsDW223 $currentTestRequest = null; 108*572dc222SLarsDW223 109f8369d7dSTobias Sarnowski return $response; 110f8369d7dSTobias Sarnowski } 1119e777ceeSAndreas Gohr 1129e777ceeSAndreas Gohr /** 1139e777ceeSAndreas Gohr * Set the virtual URI the request works against 1149e777ceeSAndreas Gohr * 1159e777ceeSAndreas Gohr * This parses the given URI and sets any contained GET variables 1169e777ceeSAndreas Gohr * but will not overwrite any previously set ones (eg. set via setGet()). 1179e777ceeSAndreas Gohr * 1189e777ceeSAndreas Gohr * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] 1199e777ceeSAndreas Gohr * with all set GET variables. 1209e777ceeSAndreas Gohr * 1219e777ceeSAndreas Gohr * @param string $url end URL to simulate, needs to start with /doku.php currently 1224d053d04SAndreas Gohr * @todo make this work with other end points 1239e777ceeSAndreas Gohr */ 1244d053d04SAndreas Gohr protected function setUri($uri){ 1259894e7afSChristopher Smith if(!preg_match('#^('.join('|',$this->valid_scripts).')#',$uri)){ 1269894e7afSChristopher Smith throw new Exception("$uri \n--- only ".join(', ',$this->valid_scripts)." are supported currently"); 1279e777ceeSAndreas Gohr } 1289e777ceeSAndreas Gohr 1299e777ceeSAndreas Gohr $params = array(); 1309e777ceeSAndreas Gohr list($uri, $query) = explode('?',$uri,2); 1319e777ceeSAndreas Gohr if($query) parse_str($query, $params); 1329e777ceeSAndreas Gohr 1339894e7afSChristopher Smith $this->script = substr($uri,1); 1349e777ceeSAndreas Gohr $this->get = array_merge($params, $this->get); 1359e777ceeSAndreas Gohr if(count($this->get)){ 1369e777ceeSAndreas Gohr $query = '?'.http_build_query($this->get, '', '&'); 1379e777ceeSAndreas Gohr $query = str_replace( 1389e777ceeSAndreas Gohr array('%3A', '%5B', '%5D'), 1399e777ceeSAndreas Gohr array(':', '[', ']'), 1409e777ceeSAndreas Gohr $query 1419e777ceeSAndreas Gohr ); 1429e777ceeSAndreas Gohr $uri = $uri.$query; 1439e777ceeSAndreas Gohr } 1449e777ceeSAndreas Gohr 1459e777ceeSAndreas Gohr $this->setServer('QUERY_STRING', $query); 1469e777ceeSAndreas Gohr $this->setServer('REQUEST_URI', $uri); 1479e777ceeSAndreas Gohr } 1489e777ceeSAndreas Gohr 1499e777ceeSAndreas Gohr /** 1509e777ceeSAndreas Gohr * Simulate a POST request with the given variables 1519e777ceeSAndreas Gohr * 1529e777ceeSAndreas Gohr * @param array $post all the POST parameters to use 1539894e7afSChristopher Smith * @param string $url end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently 1549e777ceeSAndreas Gohr * @param return TestResponse 1559e777ceeSAndreas Gohr */ 1569e777ceeSAndreas Gohr public function post($post=array(), $uri='/doku.php') { 1579e777ceeSAndreas Gohr $this->post = array_merge($this->post, $post); 1589e777ceeSAndreas Gohr $this->setServer('REQUEST_METHOD', 'POST'); 1594d053d04SAndreas Gohr return $this->execute($uri); 1609e777ceeSAndreas Gohr } 1619e777ceeSAndreas Gohr 1629e777ceeSAndreas Gohr /** 1639e777ceeSAndreas Gohr * Simulate a GET request with the given variables 1649e777ceeSAndreas Gohr * 1659894e7afSChristopher Smith * @param array $GET all the GET parameters to use 1669894e7afSChristopher Smith * @param string $url end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently 1679e777ceeSAndreas Gohr * @param return TestResponse 1689e777ceeSAndreas Gohr */ 1699e777ceeSAndreas Gohr public function get($get=array(), $uri='/doku.php') { 1709e777ceeSAndreas Gohr $this->get = array_merge($this->get, $get); 1719e777ceeSAndreas Gohr $this->setServer('REQUEST_METHOD', 'GET'); 1724d053d04SAndreas Gohr return $this->execute($uri); 1739e777ceeSAndreas Gohr } 1749e777ceeSAndreas Gohr 175*572dc222SLarsDW223 /** 176*572dc222SLarsDW223 * Add a notification to later store it in the test respone. 177*572dc222SLarsDW223 */ 178*572dc222SLarsDW223 public function addNotification(array $new) { 179*572dc222SLarsDW223 $this->notifications[] = $new; 180*572dc222SLarsDW223 } 181f8369d7dSTobias Sarnowski} 182