public function call($uri, $method = 'get', $parameters = array(), $changeStack = true) { $uri = $this->fixUri($uri); // add uri to the stack if ($changeStack) { $this->stack = array_slice($this->stack, 0, $this->stackPosition + 1); $this->stack[] = array('uri' => $uri, 'method' => $method, 'parameters' => $parameters); $this->stackPosition = count($this->stack) - 1; } list($path, $query_string) = false !== ($pos = strpos($uri, '?')) ? array(substr($uri, 0, $pos), substr($uri, $pos + 1)) : array($uri, ''); $query_string = html_entity_decode($query_string); // remove anchor $path = preg_replace('/#.*/', '', $path); // removes all fields from previous request $this->fields = array(); // prepare the request object $_SERVER = $this->defaultServerArray; $_SERVER['HTTP_HOST'] = $this->hostname ? $this->hostname : sfConfig::get('sf_app') . '-' . sfConfig::get('sf_environment'); $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST']; $_SERVER['SERVER_PORT'] = 80; $_SERVER['HTTP_USER_AGENT'] = 'PHP5/CLI'; $_SERVER['REMOTE_ADDR'] = $this->remote ? $this->remote : '127.0.0.1'; $_SERVER['REQUEST_METHOD'] = strtoupper($method); $_SERVER['PATH_INFO'] = $path; $_SERVER['REQUEST_URI'] = '/index.php' . $uri; $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['SCRIPT_FILENAME'] = '/index.php'; $_SERVER['QUERY_STRING'] = $query_string; foreach ($this->vars as $key => $value) { $_SERVER[strtoupper($key)] = $value; } // request parameters $_GET = $_POST = array(); if (strtoupper($method) == 'POST') { $_POST = $parameters; } if (strtoupper($method) == 'GET') { $_GET = $parameters; } parse_str($query_string, $qs); if (is_array($qs)) { $_GET = array_merge($qs, $_GET); } // restore cookies $_COOKIE = array(); foreach ($this->cookieJar as $name => $cookie) { $_COOKIE[$name] = $cookie['value']; } // recycle our context object sfContext::removeInstance(); $this->context = sfContext::getInstance(); // launch request via controller $controller = $this->context->getController(); $request = $this->context->getRequest(); $response = $this->context->getResponse(); // we register a fake rendering filter sfConfig::set('sf_rendering_filter', array('sfFakeRenderingFilter', null)); $this->currentException = null; // dispatch our request ob_start(); try { $controller->dispatch(); } catch (sfException $e) { $this->currentException = $e; $e->printStackTrace(); } catch (Exception $e) { $this->currentException = $e; $sfException = new sfException(); $sfException->printStackTrace($e); } $retval = ob_get_clean(); if ($this->currentException instanceof sfStopException) { $this->currentException = null; } // append retval to the response content $response->setContent($retval); // manually shutdown user to save current session data $this->context->getUser()->shutdown(); $this->context->getStorage()->shutdown(); // save cookies $this->cookieJar = array(); foreach ($response->getCookies() as $name => $cookie) { // FIXME: deal with expire, path, secure, ... $this->cookieJar[$name] = $cookie; } // for HTML/XML content, create a DOM and sfDomCssSelector objects for the response content if (preg_match('/(x|ht)ml/i', $response->getContentType())) { $this->dom = new DomDocument('1.0', sfConfig::get('sf_charset')); $this->dom->validateOnParse = true; @$this->dom->loadHTML($response->getContent()); $this->domCssSelector = new sfDomCssSelector($this->dom); } return $this; }