xref: /dokuwiki/_test/core/TestRequest.php (revision d6ba7eb1ef8c1fe1b561e77b0788611bde35c527)
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