xref: /dokuwiki/_test/core/TestRequest.php (revision 9e777cee116bd29c51b62ccd1c4353cc00014522)
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     * @return TestResponse the resulting output of the request
40     */
41    public function execute() {
42        // save old environment
43        $server = $_SERVER;
44        $session = $_SESSION;
45        $get = $_GET;
46        $post = $_POST;
47        $request = $_REQUEST;
48
49        // import all defined globals into the function scope
50        foreach(array_keys($GLOBALS) as $glb){
51            global $$glb;
52        }
53
54        // fake environment
55        global $default_server_vars;
56        $_SERVER = array_merge($default_server_vars, $this->server);
57        $_SESSION = $this->session;
58        $_GET = $this->get;
59        $_POST = $this->post;
60        $_REQUEST = array_merge($_GET, $_POST);
61
62        // reset output buffer
63        global $output_buffer;
64        $output_buffer = '';
65
66        // now execute dokuwiki and grep the output
67        header_remove();
68        ob_start('ob_start_callback');
69        include(DOKU_INC.'doku.php');
70        ob_end_flush();
71
72        // create the response object
73        $response = new TestResponse(
74            $output_buffer,
75            headers_list()
76        );
77
78        // reset environment
79        $_SERVER = $server;
80        $_SESSION = $session;
81        $_GET = $get;
82        $_POST = $post;
83        $_REQUEST = $request;
84
85        return $response;
86    }
87
88    /**
89     * Set the virtual URI the request works against
90     *
91     * This parses the given URI and sets any contained GET variables
92     * but will not overwrite any previously set ones (eg. set via setGet()).
93     *
94     * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING']
95     * with all set GET variables.
96     *
97     * @param string $url  end URL to simulate, needs to start with /doku.php currently
98     */
99    public function setUri($uri){
100        if(substr($uri,0,9) != '/doku.php'){
101            throw new Exception("only '/doku.php' is supported currently");
102        }
103
104        $params = array();
105        list($uri, $query) = explode('?',$uri,2);
106        if($query) parse_str($query, $params);
107
108        $this->get  = array_merge($params, $this->get);
109        if(count($this->get)){
110            $query = '?'.http_build_query($this->get, '', '&');
111            $query = str_replace(
112                array('%3A', '%5B', '%5D'),
113                array(':', '[', ']'),
114                $query
115            );
116            $uri = $uri.$query;
117        }
118
119        $this->setServer('QUERY_STRING', $query);
120        $this->setServer('REQUEST_URI', $uri);
121    }
122
123    /**
124     * Simulate a POST request with the given variables
125     *
126     * @param array $post  all the POST parameters to use
127     * @param string $url  end URL to simulate, needs to start with /doku.php currently
128     * @param return TestResponse
129     */
130    public function post($post=array(), $uri='/doku.php') {
131        $this->setUri($uri);
132        $this->post = array_merge($this->post, $post);
133        $this->setServer('REQUEST_METHOD', 'POST');
134        return $this->execute();
135    }
136
137    /**
138     * Simulate a GET request with the given variables
139     *
140     * @param array $GET  all the POST parameters to use
141     * @param string $url  end URL to simulate, needs to start with /doku.php currently
142     * @param return TestResponse
143     */
144    public function get($get=array(), $uri='/doku.php') {
145        $this->get  = array_merge($this->get, $get);
146        $this->setUri($uri);
147        $this->setServer('REQUEST_METHOD', 'GET');
148        return $this->execute();
149    }
150
151
152}
153