Example #1
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the URL given,
  * 
  * @param string $url The URL to visit
  * @param array $postVars The $_POST & $_FILES variables
  * @param Session $session The {@link Session} object representing the current session.  By passing the same object to multiple
  * calls of Director::test(), you can simulate a persisted session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set, GET otherwise.
  *  Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body
  * @param array $headers HTTP headers with key-value pairs
  * @param array $cookies to populate $_COOKIE
  * @return SS_HTTPResponse
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null)
 {
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     $oldStage = Versioned::current_stage();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = new Session(null);
     }
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingCookieReportErrors = Cookie::report_errors();
     $existingRequirementsBackend = Requirements::backend();
     Cookie::set_report_errors(false);
     Requirements::set_backend(new Requirements_Backend());
     // Handle absolute URLs
     if (@parse_url($url, PHP_URL_HOST) != '') {
         $bits = parse_url($url);
         $_SERVER['HTTP_HOST'] = $bits['host'];
         $url = Director::makeRelative($url);
     }
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the superglobals with appropriate test values
     $_REQUEST = array_merge((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = (array) $cookies;
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $req = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $req->addHeader($k, $v);
         }
     }
     $result = Director::handleRequest($req, $session);
     // Restore the superglobals
     $_REQUEST = $existingRequestVars;
     $_GET = $existingGetVars;
     $_POST = $existingPostVars;
     $_SESSION = $existingSessionVars;
     $_COOKIE = $existingCookies;
     $_SERVER = $existingServer;
     Cookie::set_report_errors($existingCookieReportErrors);
     Requirements::set_backend($existingRequirementsBackend);
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     Versioned::reading_stage($oldStage);
     return $result;
 }
Example #2
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the
  * URL given, and return the result as an SS_HTTPResponse object.
  * 
  * @param string $url The URL to visit
  * @param array $postVars The $_POST & $_FILES variables
  * @param Session $session The {@link Session} object representing the current session.  By passing the same
  *                         object to multiple  calls of Director::test(), you can simulate a persisted session.
  * @param string $httpMethod The HTTP method, such as GET or POST.  It will default to POST if postVars is set,
  *                           GET otherwise. Overwritten by $postVars['_method'] if present.
  * @param string $body The HTTP body
  * @param array $headers HTTP headers with key-value pairs
  * @param array $cookies to populate $_COOKIE
  * @param HTTP_Request $request The {@see HTTP_Request} object generated as a part of this request
  * @return SS_HTTPResponse
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 public static function test($url, $postVars = null, $session = null, $httpMethod = null, $body = null, $headers = null, $cookies = null, &$request = null)
 {
     Config::nest();
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     $oldStage = Versioned::current_stage();
     $getVars = array();
     if (!$httpMethod) {
         $httpMethod = $postVars || is_array($postVars) ? "POST" : "GET";
     }
     if (!$session) {
         $session = new Session(null);
     }
     // Back up the current values of the superglobals
     $existingRequestVars = isset($_REQUEST) ? $_REQUEST : array();
     $existingGetVars = isset($_GET) ? $_GET : array();
     $existingPostVars = isset($_POST) ? $_POST : array();
     $existingSessionVars = isset($_SESSION) ? $_SESSION : array();
     $existingCookies = isset($_COOKIE) ? $_COOKIE : array();
     $existingServer = isset($_SERVER) ? $_SERVER : array();
     $existingRequirementsBackend = Requirements::backend();
     Config::inst()->update('Cookie', 'report_errors', false);
     Requirements::set_backend(new Requirements_Backend());
     // Handle absolute URLs
     if (@parse_url($url, PHP_URL_HOST) != '') {
         $bits = parse_url($url);
         $_SERVER['HTTP_HOST'] = $bits['host'];
         $url = Director::makeRelative($url);
     }
     $urlWithQuerystring = $url;
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     // Replace the superglobals with appropriate test values
     $_REQUEST = ArrayLib::array_merge_recursive((array) $getVars, (array) $postVars);
     $_GET = (array) $getVars;
     $_POST = (array) $postVars;
     $_SESSION = $session ? $session->inst_getAll() : array();
     $_COOKIE = (array) $cookies;
     $_SERVER['REQUEST_URI'] = Director::baseURL() . $urlWithQuerystring;
     $request = new SS_HTTPRequest($httpMethod, $url, $getVars, $postVars, $body);
     if ($headers) {
         foreach ($headers as $k => $v) {
             $request->addHeader($k, $v);
         }
     }
     // Pre-request filtering
     // @see issue #2517
     $model = DataModel::inst();
     $output = Injector::inst()->get('RequestProcessor')->preRequest($request, $session, $model);
     if ($output === false) {
         // @TODO Need to NOT proceed with the request in an elegant manner
         throw new SS_HTTPResponse_Exception(_t('Director.INVALID_REQUEST', 'Invalid request'), 400);
     }
     // TODO: Pass in the DataModel
     $result = Director::handleRequest($request, $session, $model);
     // Ensure that the result is an SS_HTTPResponse object
     if (is_string($result)) {
         if (substr($result, 0, 9) == 'redirect:') {
             $response = new SS_HTTPResponse();
             $response->redirect(substr($result, 9));
             $result = $response;
         } else {
             $result = new SS_HTTPResponse($result);
         }
     }
     $output = Injector::inst()->get('RequestProcessor')->postRequest($request, $result, $model);
     if ($output === false) {
         throw new SS_HTTPResponse_Exception("Invalid response");
     }
     // Restore the superglobals
     $_REQUEST = $existingRequestVars;
     $_GET = $existingGetVars;
     $_POST = $existingPostVars;
     $_SESSION = $existingSessionVars;
     $_COOKIE = $existingCookies;
     $_SERVER = $existingServer;
     Requirements::set_backend($existingRequirementsBackend);
     // These are needed so that calling Director::test() doesnt muck with whoever is calling it.
     // Really, it's some inappropriate coupling and should be resolved by making less use of statics
     Versioned::reading_stage($oldStage);
     Config::unnest();
     return $result;
 }