server[$key]; } /** * Get a $_SESSION var * * @param string $key * @return mixed */ public function getSession($key) { return $this->session[$key]; } /** * Get a $_GET var * * @param string $key * @return mixed */ public function getGet($key) { return $this->get[$key]; } /** * Get a $_POST var * * @param string $key * @return mixed */ public function getPost($key) { return $this->post[$key]; } /** * Get the script that will execute the request * * @return string */ public function getScript() { return $this->script; } /** * Set a $_SERVER var * * @param string $key * @param mixed $value */ public function setServer($key, $value) { $this->server[$key] = $value; } /** * Set a $_SESSION var * * @param string $key * @param mixed $value */ public function setSession($key, $value) { $this->session[$key] = $value; } /** * Set a $_GET var * * @param string $key * @param mixed $value */ public function setGet($key, $value) { $this->get[$key] = $value; } /** * Set a $_POST var * * @param string $key * @param mixed $value */ public function setPost($key, $value) { $this->post[$key] = $value; } /** * Executes the request * * @param string $uri end URL to simulate, needs to be one of the testable scripts * @return TestResponse the resulting output of the request */ public function execute($uri = '/doku.php') { global $INPUT; // save old environment $server = $_SERVER; $session = $_SESSION; $get = $_GET; $post = $_POST; $request = $_REQUEST; $input = $INPUT; // prepare the right URI $this->setUri($uri); // import all defined globals into the function scope foreach(array_keys($GLOBALS) as $glb) { global $$glb; } // fake environment global $default_server_vars; $_SERVER = array_merge($default_server_vars, $this->server); $_SESSION = $this->session; $_GET = $this->get; $_POST = $this->post; $_REQUEST = array_merge($_GET, $_POST); // reset output buffer $this->output_buffer = ''; // now execute dokuwiki and grep the output self::$running = $this; header_remove(); ob_start(array($this, 'ob_start_callback')); $INPUT = new Input(); include(DOKU_INC . $this->script); ob_end_flush(); self::$running = null; // create the response object $response = new TestResponse( $this->output_buffer, // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()), $this->data ); // reset environment $_SERVER = $server; $_SESSION = $session; $_GET = $get; $_POST = $post; $_REQUEST = $request; $INPUT = $input; return $response; } /** * Set the virtual URI the request works against * * This parses the given URI and sets any contained GET variables * but will not overwrite any previously set ones (eg. set via setGet()). * * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'] * with all set GET variables. * * @param string $uri end URL to simulate * @throws Exception when an invalid script is passed */ protected function setUri($uri) { if(!preg_match('#^(' . join('|', $this->valid_scripts) . ')#', $uri)) { throw new Exception("$uri \n--- only " . join(', ', $this->valid_scripts) . " are supported currently"); } $params = array(); list($uri, $query) = sexplode('?', $uri, 2); if($query) parse_str($query, $params); $this->script = substr($uri, 1); $this->get = array_merge($params, $this->get); if(count($this->get)) { $query = '?' . http_build_query($this->get, '', '&'); $query = str_replace( array('%3A', '%5B', '%5D'), array(':', '[', ']'), $query ); $uri = $uri . $query; } $this->setServer('QUERY_STRING', $query); $this->setServer('REQUEST_URI', $uri); } /** * Simulate a POST request with the given variables * * @param array $post all the POST parameters to use * @param string $uri end URL to simulate * @return TestResponse */ public function post($post = array(), $uri = '/doku.php') { $this->post = array_merge($this->post, $post); $this->setServer('REQUEST_METHOD', 'POST'); return $this->execute($uri); } /** * Simulate a GET request with the given variables * * @param array $get all the GET parameters to use * @param string $uri end URL to simulate * @return TestResponse */ public function get($get = array(), $uri = '/doku.php') { $this->get = array_merge($this->get, $get); $this->setServer('REQUEST_METHOD', 'GET'); return $this->execute($uri); } /** * Callback for ob_start * * This continues to fill our own buffer, even when some part * of the code askes for flushing the buffers * * @param string $buffer */ public function ob_start_callback($buffer) { $this->output_buffer .= $buffer; } /** * Access the TestRequest from the executed code * * This allows certain functions to access the TestRequest that is accessing them * to add additional info. * * @return null|TestRequest the currently executed request if any */ public static function getRunning() { return self::$running; } /** * Store data to be read in the response later * * When called multiple times with the same key, the data is appended to this * key's array * * @param string $key the identifier for this information * @param mixed $value arbitrary data to store */ public function addData($key, $value) { if(!isset($this->data[$key])) $this->data[$key] = array(); $this->data[$key][] = $value; } }