1<?php 2/** 3 * Simulates a full DokuWiki HTTP Request and allows 4 * runtime inspection. 5 */ 6 7// output buffering 8$output_buffer = ''; 9 10function ob_start_callback($buffer) { 11 global $output_buffer; 12 $output_buffer .= $buffer; 13} 14 15 16/** 17 * Helper class to execute a fake request 18 */ 19class TestRequest { 20 21 private $server = array(); 22 private $session = array(); 23 private $get = array(); 24 private $post = array(); 25 26 public function getServer($key) { return $this->server[$key]; } 27 public function getSession($key) { return $this->session[$key]; } 28 public function getGet($key) { return $this->get[$key]; } 29 public function getPost($key) { return $this->post[$key]; } 30 31 public function setServer($key, $value) { $this->server[$key] = $value; } 32 public function setSession($key, $value) { $this->session[$key] = $value; } 33 public function setGet($key, $value) { $this->get[$key] = $value; } 34 public function setPost($key, $value) { $this->post[$key] = $value; } 35 36 /** 37 * Executes the request 38 * 39 * @param string $url end URL to simulate, needs to start with /doku.php currently 40 * @return TestResponse the resulting output of the request 41 */ 42 public function execute($uri='/doku.php') { 43 // save old environment 44 $server = $_SERVER; 45 $session = $_SESSION; 46 $get = $_GET; 47 $post = $_POST; 48 $request = $_REQUEST; 49 50 // prepare the right URI 51 $this->setUri($uri); 52 53 // import all defined globals into the function scope 54 foreach(array_keys($GLOBALS) as $glb){ 55 global $$glb; 56 } 57 58 // fake environment 59 global $default_server_vars; 60 $_SERVER = array_merge($default_server_vars, $this->server); 61 $_SESSION = $this->session; 62 $_GET = $this->get; 63 $_POST = $this->post; 64 $_REQUEST = array_merge($_GET, $_POST); 65 66 // reset output buffer 67 global $output_buffer; 68 $output_buffer = ''; 69 70 // now execute dokuwiki and grep the output 71 header_remove(); 72 ob_start('ob_start_callback'); 73 include(DOKU_INC.'doku.php'); 74 ob_end_flush(); 75 76 // create the response object 77 $response = new TestResponse( 78 $output_buffer, 79 headers_list() 80 ); 81 82 // reset environment 83 $_SERVER = $server; 84 $_SESSION = $session; 85 $_GET = $get; 86 $_POST = $post; 87 $_REQUEST = $request; 88 89 return $response; 90 } 91 92 /** 93 * Set the virtual URI the request works against 94 * 95 * This parses the given URI and sets any contained GET variables 96 * but will not overwrite any previously set ones (eg. set via setGet()). 97 * 98 * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] 99 * with all set GET variables. 100 * 101 * @param string $url end URL to simulate, needs to start with /doku.php currently 102 * @todo make this work with other end points 103 */ 104 protected function setUri($uri){ 105 if(substr($uri,0,9) != '/doku.php'){ 106 throw new Exception("only '/doku.php' is supported currently"); 107 } 108 109 $params = array(); 110 list($uri, $query) = explode('?',$uri,2); 111 if($query) parse_str($query, $params); 112 113 $this->get = array_merge($params, $this->get); 114 if(count($this->get)){ 115 $query = '?'.http_build_query($this->get, '', '&'); 116 $query = str_replace( 117 array('%3A', '%5B', '%5D'), 118 array(':', '[', ']'), 119 $query 120 ); 121 $uri = $uri.$query; 122 } 123 124 $this->setServer('QUERY_STRING', $query); 125 $this->setServer('REQUEST_URI', $uri); 126 } 127 128 /** 129 * Simulate a POST request with the given variables 130 * 131 * @param array $post all the POST parameters to use 132 * @param string $url end URL to simulate, needs to start with /doku.php currently 133 * @param return TestResponse 134 */ 135 public function post($post=array(), $uri='/doku.php') { 136 $this->post = array_merge($this->post, $post); 137 $this->setServer('REQUEST_METHOD', 'POST'); 138 return $this->execute($uri); 139 } 140 141 /** 142 * Simulate a GET request with the given variables 143 * 144 * @param array $GET all the POST parameters to use 145 * @param string $url end URL to simulate, needs to start with /doku.php currently 146 * @param return TestResponse 147 */ 148 public function get($get=array(), $uri='/doku.php') { 149 $this->get = array_merge($this->get, $get); 150 $this->setServer('REQUEST_METHOD', 'GET'); 151 return $this->execute($uri); 152 } 153 154 155} 156