This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
symfony/src/Symfony/Component/HttpKernel/Client.php
Fabien Potencier 54ab31a7fc Merge branch '2.3' into 2.4
* 2.3:
  Fixed the XPath filtering to have the same behavior than Symfony 2.4
  [DomCrawler] Fixed filterXPath() chaining
  [DomCrawler] Added more tests for the XPath filtering
  [HttpKernel] fixed file uploads in functional tests when no file was selected
  Fixed test cases failing when the Intl extension is not installed
  Fixed the Travis build to avoid exiting too early

Conflicts:
	src/Symfony/Component/DomCrawler/Crawler.php
	src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php
2014-05-21 17:50:42 +02:00

226 lines
6.8 KiB
PHP

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpKernel;
use Symfony\Component\BrowserKit\Client as BaseClient;
use Symfony\Component\BrowserKit\Request as DomRequest;
use Symfony\Component\BrowserKit\Response as DomResponse;
use Symfony\Component\BrowserKit\Cookie as DomCookie;
use Symfony\Component\BrowserKit\History;
use Symfony\Component\BrowserKit\CookieJar;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Client simulates a browser and makes requests to a Kernel object.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @api
*/
class Client extends BaseClient
{
protected $kernel;
/**
* Constructor.
*
* @param HttpKernelInterface $kernel An HttpKernel instance
* @param array $server The server parameters (equivalent of $_SERVER)
* @param History $history A History instance to store the browser history
* @param CookieJar $cookieJar A CookieJar instance to store the cookies
*/
public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null)
{
// These class properties must be set before calling the parent constructor, as it may depend on it.
$this->kernel = $kernel;
$this->followRedirects = false;
parent::__construct($server, $history, $cookieJar);
}
/**
* {@inheritdoc}
*
* @return Request|null A Request instance
*/
public function getRequest()
{
return parent::getRequest();
}
/**
* {@inheritdoc}
*
* @return Response|null A Response instance
*/
public function getResponse()
{
return parent::getResponse();
}
/**
* Makes a request.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
protected function doRequest($request)
{
$response = $this->kernel->handle($request);
if ($this->kernel instanceof TerminableInterface) {
$this->kernel->terminate($request, $response);
}
return $response;
}
/**
* Returns the script to execute when the request must be insulated.
*
* @param Request $request A Request instance
*
* @return string
*/
protected function getScript($request)
{
$kernel = str_replace("'", "\\'", serialize($this->kernel));
$request = str_replace("'", "\\'", serialize($request));
$r = new \ReflectionClass('\\Symfony\\Component\\ClassLoader\\ClassLoader');
$requirePath = str_replace("'", "\\'", $r->getFileName());
$symfonyPath = str_replace("'", "\\'", realpath(__DIR__.'/../../..'));
$code = <<<EOF
<?php
require_once '$requirePath';
\$loader = new Symfony\Component\ClassLoader\ClassLoader();
\$loader->addPrefix('Symfony', '$symfonyPath');
\$loader->register();
\$kernel = unserialize('$kernel');
\$request = unserialize('$request');
EOF;
return $code.$this->getHandleScript();
}
protected function getHandleScript()
{
return <<<'EOF'
$response = $kernel->handle($request);
if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
$kernel->terminate($request, $response);
}
echo serialize($response);
EOF;
}
/**
* Converts the BrowserKit request to a HttpKernel request.
*
* @param DomRequest $request A DomRequest instance
*
* @return Request A Request instance
*/
protected function filterRequest(DomRequest $request)
{
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
$httpRequest->files->set($key, $value);
}
return $httpRequest;
}
/**
* Filters an array of files.
*
* This method created test instances of UploadedFile so that the move()
* method can be called on those instances.
*
* If the size of a file is greater than the allowed size (from php.ini) then
* an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
*
* @see Symfony\Component\HttpFoundation\File\UploadedFile
*
* @param array $files An array of files
*
* @return array An array with all uploaded files marked as already moved
*/
protected function filterFiles(array $files)
{
$filtered = array();
foreach ($files as $key => $value) {
if (is_array($value)) {
$filtered[$key] = $this->filterFiles($value);
} elseif ($value instanceof UploadedFile) {
if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
$filtered[$key] = new UploadedFile(
'',
$value->getClientOriginalName(),
$value->getClientMimeType(),
0,
UPLOAD_ERR_INI_SIZE,
true
);
} else {
$filtered[$key] = new UploadedFile(
$value->getPathname(),
$value->getClientOriginalName(),
$value->getClientMimeType(),
$value->getClientSize(),
$value->getError(),
true
);
}
}
}
return $filtered;
}
/**
* Converts the HttpKernel response to a BrowserKit response.
*
* @param Response $response A Response instance
*
* @return DomResponse A DomResponse instance
*/
protected function filterResponse($response)
{
$headers = $response->headers->all();
if ($response->headers->getCookies()) {
$cookies = array();
foreach ($response->headers->getCookies() as $cookie) {
$cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
}
$headers['Set-Cookie'] = $cookies;
}
// this is needed to support StreamedResponse
ob_start();
$response->sendContent();
$content = ob_get_clean();
return new DomResponse($content, $response->getStatusCode(), $headers);
}
}