2015-08-17 17:00:26 -07:00
< ? 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 >
2017-04-13 15:53:35 +01:00
*
* @ method Request | null getRequest () A Request instance
* @ method Response | null getResponse () A Response instance
2015-08-17 17:00:26 -07:00
*/
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 );
}
/**
* 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 ());
2015-09-04 13:20:09 -07:00
$symfonyPath = str_replace ( " ' " , " \\ ' " , dirname ( dirname ( dirname ( __DIR__ ))));
2015-08-17 17:00:26 -07:00
$errorReporting = error_reporting ();
$code = <<< EOF
< ? php
2016-04-20 09:56:34 -07:00
error_reporting ( $errorReporting );
2015-08-17 17:00:26 -07:00
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 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 );
}
}