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 10f8369d7dSTobias Sarnowskifunction ob_start_callback($buffer) { 11f8369d7dSTobias Sarnowski global $output_buffer; 12f8369d7dSTobias Sarnowski $output_buffer .= $buffer; 13f8369d7dSTobias Sarnowski} 14f8369d7dSTobias Sarnowski 15f8369d7dSTobias Sarnowski 16f8369d7dSTobias Sarnowski/** 17f8369d7dSTobias Sarnowski * Helper class to execute a fake request 18f8369d7dSTobias Sarnowski */ 19f8369d7dSTobias Sarnowskiclass TestRequest { 20f8369d7dSTobias Sarnowski 21*9894e7afSChristopher Smith private $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php'); 22*9894e7afSChristopher Smith private $script; 23*9894e7afSChristopher Smith 24f8369d7dSTobias Sarnowski private $server = array(); 25f8369d7dSTobias Sarnowski private $session = array(); 26f8369d7dSTobias Sarnowski private $get = array(); 27f8369d7dSTobias Sarnowski private $post = array(); 28f8369d7dSTobias Sarnowski 29f8369d7dSTobias Sarnowski public function getServer($key) { return $this->server[$key]; } 30f8369d7dSTobias Sarnowski public function getSession($key) { return $this->session[$key]; } 31f8369d7dSTobias Sarnowski public function getGet($key) { return $this->get[$key]; } 32f8369d7dSTobias Sarnowski public function getPost($key) { return $this->post[$key]; } 33*9894e7afSChristopher Smith public function getScript() { return $this->script; } 34f8369d7dSTobias Sarnowski 35f8369d7dSTobias Sarnowski public function setServer($key, $value) { $this->server[$key] = $value; } 36f8369d7dSTobias Sarnowski public function setSession($key, $value) { $this->session[$key] = $value; } 37f8369d7dSTobias Sarnowski public function setGet($key, $value) { $this->get[$key] = $value; } 38f8369d7dSTobias Sarnowski public function setPost($key, $value) { $this->post[$key] = $value; } 39f8369d7dSTobias Sarnowski 40f8369d7dSTobias Sarnowski /** 41f8369d7dSTobias Sarnowski * Executes the request 42f8369d7dSTobias Sarnowski * 434d053d04SAndreas Gohr * @param string $url end URL to simulate, needs to start with /doku.php currently 44f8369d7dSTobias Sarnowski * @return TestResponse the resulting output of the request 45f8369d7dSTobias Sarnowski */ 464d053d04SAndreas Gohr public function execute($uri='/doku.php') { 47f8369d7dSTobias Sarnowski // save old environment 48f8369d7dSTobias Sarnowski $server = $_SERVER; 49f8369d7dSTobias Sarnowski $session = $_SESSION; 50f8369d7dSTobias Sarnowski $get = $_GET; 51f8369d7dSTobias Sarnowski $post = $_POST; 52f8369d7dSTobias Sarnowski $request = $_REQUEST; 53f8369d7dSTobias Sarnowski 544d053d04SAndreas Gohr // prepare the right URI 554d053d04SAndreas Gohr $this->setUri($uri); 564d053d04SAndreas Gohr 570189bd86SAndreas Gohr // import all defined globals into the function scope 580189bd86SAndreas Gohr foreach(array_keys($GLOBALS) as $glb){ 590189bd86SAndreas Gohr global $$glb; 600189bd86SAndreas Gohr } 610189bd86SAndreas Gohr 62f8369d7dSTobias Sarnowski // fake environment 63f8369d7dSTobias Sarnowski global $default_server_vars; 64f8369d7dSTobias Sarnowski $_SERVER = array_merge($default_server_vars, $this->server); 65f8369d7dSTobias Sarnowski $_SESSION = $this->session; 66f8369d7dSTobias Sarnowski $_GET = $this->get; 67f8369d7dSTobias Sarnowski $_POST = $this->post; 68f8369d7dSTobias Sarnowski $_REQUEST = array_merge($_GET, $_POST); 69f8369d7dSTobias Sarnowski 70f8369d7dSTobias Sarnowski // reset output buffer 71f8369d7dSTobias Sarnowski global $output_buffer; 72f8369d7dSTobias Sarnowski $output_buffer = ''; 73f8369d7dSTobias Sarnowski 74f8369d7dSTobias Sarnowski // now execute dokuwiki and grep the output 75f8369d7dSTobias Sarnowski header_remove(); 76f8369d7dSTobias Sarnowski ob_start('ob_start_callback'); 77*9894e7afSChristopher Smith include(DOKU_INC.$this->script); 78f8369d7dSTobias Sarnowski ob_end_flush(); 79f8369d7dSTobias Sarnowski 80f8369d7dSTobias Sarnowski // create the response object 81f8369d7dSTobias Sarnowski $response = new TestResponse( 82f8369d7dSTobias Sarnowski $output_buffer, 83*9894e7afSChristopher 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 84f8369d7dSTobias Sarnowski ); 85f8369d7dSTobias Sarnowski 86f8369d7dSTobias Sarnowski // reset environment 87f8369d7dSTobias Sarnowski $_SERVER = $server; 88f8369d7dSTobias Sarnowski $_SESSION = $session; 89f8369d7dSTobias Sarnowski $_GET = $get; 90f8369d7dSTobias Sarnowski $_POST = $post; 91f8369d7dSTobias Sarnowski $_REQUEST = $request; 92f8369d7dSTobias Sarnowski 93f8369d7dSTobias Sarnowski return $response; 94f8369d7dSTobias Sarnowski } 959e777ceeSAndreas Gohr 969e777ceeSAndreas Gohr /** 979e777ceeSAndreas Gohr * Set the virtual URI the request works against 989e777ceeSAndreas Gohr * 999e777ceeSAndreas Gohr * This parses the given URI and sets any contained GET variables 1009e777ceeSAndreas Gohr * but will not overwrite any previously set ones (eg. set via setGet()). 1019e777ceeSAndreas Gohr * 1029e777ceeSAndreas Gohr * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] 1039e777ceeSAndreas Gohr * with all set GET variables. 1049e777ceeSAndreas Gohr * 1059e777ceeSAndreas Gohr * @param string $url end URL to simulate, needs to start with /doku.php currently 1064d053d04SAndreas Gohr * @todo make this work with other end points 1079e777ceeSAndreas Gohr */ 1084d053d04SAndreas Gohr protected function setUri($uri){ 109*9894e7afSChristopher Smith if(!preg_match('#^('.join('|',$this->valid_scripts).')#',$uri)){ 110*9894e7afSChristopher Smith throw new Exception("$uri \n--- only ".join(', ',$this->valid_scripts)." are supported currently"); 1119e777ceeSAndreas Gohr } 1129e777ceeSAndreas Gohr 1139e777ceeSAndreas Gohr $params = array(); 1149e777ceeSAndreas Gohr list($uri, $query) = explode('?',$uri,2); 1159e777ceeSAndreas Gohr if($query) parse_str($query, $params); 1169e777ceeSAndreas Gohr 117*9894e7afSChristopher Smith $this->script = substr($uri,1); 1189e777ceeSAndreas Gohr $this->get = array_merge($params, $this->get); 1199e777ceeSAndreas Gohr if(count($this->get)){ 1209e777ceeSAndreas Gohr $query = '?'.http_build_query($this->get, '', '&'); 1219e777ceeSAndreas Gohr $query = str_replace( 1229e777ceeSAndreas Gohr array('%3A', '%5B', '%5D'), 1239e777ceeSAndreas Gohr array(':', '[', ']'), 1249e777ceeSAndreas Gohr $query 1259e777ceeSAndreas Gohr ); 1269e777ceeSAndreas Gohr $uri = $uri.$query; 1279e777ceeSAndreas Gohr } 1289e777ceeSAndreas Gohr 1299e777ceeSAndreas Gohr $this->setServer('QUERY_STRING', $query); 1309e777ceeSAndreas Gohr $this->setServer('REQUEST_URI', $uri); 1319e777ceeSAndreas Gohr } 1329e777ceeSAndreas Gohr 1339e777ceeSAndreas Gohr /** 1349e777ceeSAndreas Gohr * Simulate a POST request with the given variables 1359e777ceeSAndreas Gohr * 1369e777ceeSAndreas Gohr * @param array $post all the POST parameters to use 137*9894e7afSChristopher Smith * @param string $url end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently 1389e777ceeSAndreas Gohr * @param return TestResponse 1399e777ceeSAndreas Gohr */ 1409e777ceeSAndreas Gohr public function post($post=array(), $uri='/doku.php') { 1419e777ceeSAndreas Gohr $this->post = array_merge($this->post, $post); 1429e777ceeSAndreas Gohr $this->setServer('REQUEST_METHOD', 'POST'); 1434d053d04SAndreas Gohr return $this->execute($uri); 1449e777ceeSAndreas Gohr } 1459e777ceeSAndreas Gohr 1469e777ceeSAndreas Gohr /** 1479e777ceeSAndreas Gohr * Simulate a GET request with the given variables 1489e777ceeSAndreas Gohr * 149*9894e7afSChristopher Smith * @param array $GET all the GET parameters to use 150*9894e7afSChristopher Smith * @param string $url end URL to simulate, needs to start with /doku.php, /lib/exe/fetch.php or /lib/exe/detail.php currently 1519e777ceeSAndreas Gohr * @param return TestResponse 1529e777ceeSAndreas Gohr */ 1539e777ceeSAndreas Gohr public function get($get=array(), $uri='/doku.php') { 1549e777ceeSAndreas Gohr $this->get = array_merge($this->get, $get); 1559e777ceeSAndreas Gohr $this->setServer('REQUEST_METHOD', 'GET'); 1564d053d04SAndreas Gohr return $this->execute($uri); 1579e777ceeSAndreas Gohr } 1589e777ceeSAndreas Gohr 1599e777ceeSAndreas Gohr 160f8369d7dSTobias Sarnowski} 161