[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/core/ -> TestRequest.php (source)

   1  <?php
   2  /**
   3   * Simulates a full DokuWiki HTTP Request and allows
   4   * runtime inspection.
   5   */
   6  
   7  use dokuwiki\Input\Input;
   8  
   9  /**
  10   * Helper class to execute a fake request
  11   */
  12  class TestRequest {
  13  
  14      protected $valid_scripts = array('/doku.php', '/lib/exe/fetch.php', '/lib/exe/detail.php', '/lib/exe/ajax.php');
  15      protected $script;
  16  
  17      protected $server = array();
  18      protected $session = array();
  19      protected $get = array();
  20      protected $post = array();
  21      protected $data = array();
  22  
  23      /** @var string stores the output buffer, even when it's flushed */
  24      protected $output_buffer = '';
  25  
  26      /** @var null|TestRequest the currently running request */
  27      static protected $running = null;
  28  
  29      /**
  30       * Get a $_SERVER var
  31       *
  32       * @param string $key
  33       * @return mixed
  34       */
  35      public function getServer($key) {
  36          return $this->server[$key];
  37      }
  38  
  39      /**
  40       * Get a $_SESSION var
  41       *
  42       * @param string $key
  43       * @return mixed
  44       */
  45      public function getSession($key) {
  46          return $this->session[$key];
  47      }
  48  
  49      /**
  50       * Get a $_GET var
  51       *
  52       * @param string $key
  53       * @return mixed
  54       */
  55      public function getGet($key) {
  56          return $this->get[$key];
  57      }
  58  
  59      /**
  60       * Get a $_POST var
  61       *
  62       * @param string $key
  63       * @return mixed
  64       */
  65      public function getPost($key) {
  66          return $this->post[$key];
  67      }
  68  
  69      /**
  70       * Get the script that will execute the request
  71       *
  72       * @return string
  73       */
  74      public function getScript() {
  75          return $this->script;
  76      }
  77  
  78      /**
  79       * Set a $_SERVER var
  80       *
  81       * @param string $key
  82       * @param mixed $value
  83       */
  84      public function setServer($key, $value) {
  85          $this->server[$key] = $value;
  86      }
  87  
  88      /**
  89       * Set a $_SESSION var
  90       *
  91       * @param string $key
  92       * @param mixed $value
  93       */
  94      public function setSession($key, $value) {
  95          $this->session[$key] = $value;
  96      }
  97  
  98      /**
  99       * Set a $_GET var
 100       *
 101       * @param string $key
 102       * @param mixed $value
 103       */
 104      public function setGet($key, $value) {
 105          $this->get[$key] = $value;
 106      }
 107  
 108      /**
 109       * Set a $_POST var
 110       *
 111       * @param string $key
 112       * @param mixed $value
 113       */
 114      public function setPost($key, $value) {
 115          $this->post[$key] = $value;
 116      }
 117  
 118      /**
 119       * Executes the request
 120       *
 121       * @param string $uri end URL to simulate, needs to be one of the testable scripts
 122       * @return TestResponse the resulting output of the request
 123       */
 124      public function execute($uri = '/doku.php') {
 125          global $INPUT;
 126  
 127          // save old environment
 128          $server = $_SERVER;
 129          $session = $_SESSION;
 130          $get = $_GET;
 131          $post = $_POST;
 132          $request = $_REQUEST;
 133          $input = $INPUT;
 134  
 135          // prepare the right URI
 136          $this->setUri($uri);
 137  
 138          // import all defined globals into the function scope
 139          foreach(array_keys($GLOBALS) as $glb) {
 140              global $$glb;
 141          }
 142  
 143          // fake environment
 144          global $default_server_vars;
 145          $_SERVER = array_merge($default_server_vars, $this->server);
 146          $_SESSION = $this->session;
 147          $_GET = $this->get;
 148          $_POST = $this->post;
 149          $_REQUEST = array_merge($_GET, $_POST);
 150  
 151          // reset output buffer
 152          $this->output_buffer = '';
 153  
 154          // now execute dokuwiki and grep the output
 155          self::$running = $this;
 156          header_remove();
 157          ob_start(array($this, 'ob_start_callback'));
 158          $INPUT = new Input();
 159          include(DOKU_INC . $this->script);
 160          ob_end_flush();
 161          self::$running = null;
 162  
 163          // create the response object
 164          $response = new TestResponse(
 165              $this->output_buffer,
 166              // cli sapi doesn't do headers, prefer xdebug_get_headers() which works under cli
 167              (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list()),
 168              $this->data
 169          );
 170  
 171          // reset environment
 172          $_SERVER = $server;
 173          $_SESSION = $session;
 174          $_GET = $get;
 175          $_POST = $post;
 176          $_REQUEST = $request;
 177          $INPUT = $input;
 178  
 179          return $response;
 180      }
 181  
 182      /**
 183       * Set the virtual URI the request works against
 184       *
 185       * This parses the given URI and sets any contained GET variables
 186       * but will not overwrite any previously set ones (eg. set via setGet()).
 187       *
 188       * It initializes the $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING']
 189       * with all set GET variables.
 190       *
 191       * @param string $uri end URL to simulate
 192       * @throws Exception when an invalid script is passed
 193       */
 194      protected function setUri($uri) {
 195          if(!preg_match('#^(' . join('|', $this->valid_scripts) . ')#', $uri)) {
 196              throw new Exception("$uri \n--- only " . join(', ', $this->valid_scripts) . " are supported currently");
 197          }
 198  
 199          $params = array();
 200          list($uri, $query) = explode('?', $uri, 2);
 201          if($query) parse_str($query, $params);
 202  
 203          $this->script = substr($uri, 1);
 204          $this->get = array_merge($params, $this->get);
 205          if(count($this->get)) {
 206              $query = '?' . http_build_query($this->get, '', '&');
 207              $query = str_replace(
 208                  array('%3A', '%5B', '%5D'),
 209                  array(':', '[', ']'),
 210                  $query
 211              );
 212              $uri = $uri . $query;
 213          }
 214  
 215          $this->setServer('QUERY_STRING', $query);
 216          $this->setServer('REQUEST_URI', $uri);
 217      }
 218  
 219      /**
 220       * Simulate a POST request with the given variables
 221       *
 222       * @param array $post all the POST parameters to use
 223       * @param string $uri end URL to simulate
 224       * @return TestResponse
 225       */
 226      public function post($post = array(), $uri = '/doku.php') {
 227          $this->post = array_merge($this->post, $post);
 228          $this->setServer('REQUEST_METHOD', 'POST');
 229          return $this->execute($uri);
 230      }
 231  
 232      /**
 233       * Simulate a GET request with the given variables
 234       *
 235       * @param array $get all the GET parameters to use
 236       * @param string $uri end URL to simulate
 237       * @return TestResponse
 238       */
 239      public function get($get = array(), $uri = '/doku.php') {
 240          $this->get = array_merge($this->get, $get);
 241          $this->setServer('REQUEST_METHOD', 'GET');
 242          return $this->execute($uri);
 243      }
 244  
 245      /**
 246       * Callback for ob_start
 247       *
 248       * This continues to fill our own buffer, even when some part
 249       * of the code askes for flushing the buffers
 250       *
 251       * @param string $buffer
 252       */
 253      public function ob_start_callback($buffer) {
 254          $this->output_buffer .= $buffer;
 255      }
 256  
 257      /**
 258       * Access the TestRequest from the executed code
 259       *
 260       * This allows certain functions to access the TestRequest that is accessing them
 261       * to add additional info.
 262       *
 263       * @return null|TestRequest the currently executed request if any
 264       */
 265      public static function getRunning() {
 266          return self::$running;
 267      }
 268  
 269      /**
 270       * Store data to be read in the response later
 271       *
 272       * When called multiple times with the same key, the data is appended to this
 273       * key's array
 274       *
 275       * @param string $key the identifier for this information
 276       * @param mixed $value arbitrary data to store
 277       */
 278      public function addData($key, $value) {
 279          if(!isset($this->data[$key])) $this->data[$key] = array();
 280          $this->data[$key][] = $value;
 281      }
 282  }