abstract class Client in Zircon Profile 8.0
Same name in this branch
- 8.0 vendor/symfony/http-kernel/Client.php \Symfony\Component\HttpKernel\Client
- 8.0 vendor/symfony/browser-kit/Client.php \Symfony\Component\BrowserKit\Client
- 8.0 vendor/fabpot/goutte/Goutte/Client.php \Goutte\Client
- 8.0 vendor/guzzlehttp/guzzle/src/Client.php \GuzzleHttp\Client
- 8.0 vendor/behat/mink-goutte-driver/src/Goutte/Client.php \Behat\Mink\Driver\Goutte\Client
Same name and namespace in other branches
- 8 vendor/symfony/browser-kit/Client.php \Symfony\Component\BrowserKit\Client
Client simulates a browser.
To make the actual request, you need to implement the doRequest() method.
If you want to be able to run requests in their own process (insulated flag), you need to also implement the getScript() method.
@author Fabien Potencier <fabien@symfony.com>
Hierarchy
- class \Symfony\Component\BrowserKit\Client
Expanded class hierarchy of Client
5 files declare their use of Client
- BrowserKitDriver.php in vendor/
behat/ mink-browserkit-driver/ src/ BrowserKitDriver.php - Client.php in vendor/
symfony/ http-kernel/ Client.php - Client.php in vendor/
fabpot/ goutte/ Goutte/ Client.php - ClientTest.php in vendor/
symfony/ browser-kit/ Tests/ ClientTest.php - ErrorHandlingTest.php in vendor/
behat/ mink-browserkit-driver/ tests/ Custom/ ErrorHandlingTest.php
File
- vendor/
symfony/ browser-kit/ Client.php, line 29
Namespace
Symfony\Component\BrowserKitView source
abstract class Client {
protected $history;
protected $cookieJar;
protected $server = array();
protected $internalRequest;
protected $request;
protected $internalResponse;
protected $response;
protected $crawler;
protected $insulated = false;
protected $redirect;
protected $followRedirects = true;
private $maxRedirects = -1;
private $redirectCount = 0;
private $isMainRequest = true;
/**
* Constructor.
*
* @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(array $server = array(), History $history = null, CookieJar $cookieJar = null) {
$this
->setServerParameters($server);
$this->history = $history ?: new History();
$this->cookieJar = $cookieJar ?: new CookieJar();
}
/**
* Sets whether to automatically follow redirects or not.
*
* @param bool $followRedirect Whether to follow redirects
*/
public function followRedirects($followRedirect = true) {
$this->followRedirects = (bool) $followRedirect;
}
/**
* Sets the maximum number of requests that crawler can follow.
*
* @param int $maxRedirects
*/
public function setMaxRedirects($maxRedirects) {
$this->maxRedirects = $maxRedirects < 0 ? -1 : $maxRedirects;
$this->followRedirects = -1 != $this->maxRedirects;
}
/**
* Sets the insulated flag.
*
* @param bool $insulated Whether to insulate the requests or not
*
* @throws \RuntimeException When Symfony Process Component is not installed
*/
public function insulate($insulated = true) {
if ($insulated && !class_exists('Symfony\\Component\\Process\\Process')) {
throw new \RuntimeException('Unable to isolate requests as the Symfony Process Component is not installed.');
}
$this->insulated = (bool) $insulated;
}
/**
* Sets server parameters.
*
* @param array $server An array of server parameters
*/
public function setServerParameters(array $server) {
$this->server = array_merge(array(
'HTTP_HOST' => 'localhost',
'HTTP_USER_AGENT' => 'Symfony2 BrowserKit',
), $server);
}
/**
* Sets single server parameter.
*
* @param string $key A key of the parameter
* @param string $value A value of the parameter
*/
public function setServerParameter($key, $value) {
$this->server[$key] = $value;
}
/**
* Gets single server parameter for specified key.
*
* @param string $key A key of the parameter to get
* @param string $default A default value when key is undefined
*
* @return string A value of the parameter
*/
public function getServerParameter($key, $default = '') {
return isset($this->server[$key]) ? $this->server[$key] : $default;
}
/**
* Returns the History instance.
*
* @return History A History instance
*/
public function getHistory() {
return $this->history;
}
/**
* Returns the CookieJar instance.
*
* @return CookieJar A CookieJar instance
*/
public function getCookieJar() {
return $this->cookieJar;
}
/**
* Returns the current Crawler instance.
*
* @return Crawler|null A Crawler instance
*/
public function getCrawler() {
return $this->crawler;
}
/**
* Returns the current BrowserKit Response instance.
*
* @return Response|null A BrowserKit Response instance
*/
public function getInternalResponse() {
return $this->internalResponse;
}
/**
* Returns the current origin response instance.
*
* The origin response is the response instance that is returned
* by the code that handles requests.
*
* @return object|null A response instance
*
* @see doRequest()
*/
public function getResponse() {
return $this->response;
}
/**
* Returns the current BrowserKit Request instance.
*
* @return Request|null A BrowserKit Request instance
*/
public function getInternalRequest() {
return $this->internalRequest;
}
/**
* Returns the current origin Request instance.
*
* The origin request is the request instance that is sent
* to the code that handles requests.
*
* @return object|null A Request instance
*
* @see doRequest()
*/
public function getRequest() {
return $this->request;
}
/**
* Clicks on a given link.
*
* @param Link $link A Link instance
*
* @return Crawler
*/
public function click(Link $link) {
if ($link instanceof Form) {
return $this
->submit($link);
}
return $this
->request($link
->getMethod(), $link
->getUri());
}
/**
* Submits a form.
*
* @param Form $form A Form instance
* @param array $values An array of form field values
*
* @return Crawler
*/
public function submit(Form $form, array $values = array()) {
$form
->setValues($values);
return $this
->request($form
->getMethod(), $form
->getUri(), $form
->getPhpValues(), $form
->getPhpFiles());
}
/**
* Calls a URI.
*
* @param string $method The request method
* @param string $uri The URI to fetch
* @param array $parameters The Request parameters
* @param array $files The files
* @param array $server The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does)
* @param string $content The raw body data
* @param bool $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload())
*
* @return Crawler
*/
public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true) {
if ($this->isMainRequest) {
$this->redirectCount = 0;
}
else {
++$this->redirectCount;
}
$uri = $this
->getAbsoluteUri($uri);
if (!empty($server['HTTP_HOST'])) {
$uri = preg_replace('{^(https?\\://)' . preg_quote($this
->extractHost($uri)) . '}', '${1}' . $server['HTTP_HOST'], $uri);
}
if (isset($server['HTTPS'])) {
$uri = preg_replace('{^' . parse_url($uri, PHP_URL_SCHEME) . '}', $server['HTTPS'] ? 'https' : 'http', $uri);
}
$server = array_merge($this->server, $server);
if (!$this->history
->isEmpty()) {
$server['HTTP_REFERER'] = $this->history
->current()
->getUri();
}
$server['HTTP_HOST'] = $this
->extractHost($uri);
$server['HTTPS'] = 'https' == parse_url($uri, PHP_URL_SCHEME);
$this->internalRequest = new Request($uri, $method, $parameters, $files, $this->cookieJar
->allValues($uri), $server, $content);
$this->request = $this
->filterRequest($this->internalRequest);
if (true === $changeHistory) {
$this->history
->add($this->internalRequest);
}
if ($this->insulated) {
$this->response = $this
->doRequestInProcess($this->request);
}
else {
$this->response = $this
->doRequest($this->request);
}
$this->internalResponse = $this
->filterResponse($this->response);
$this->cookieJar
->updateFromResponse($this->internalResponse, $uri);
$status = $this->internalResponse
->getStatus();
if ($status >= 300 && $status < 400) {
$this->redirect = $this->internalResponse
->getHeader('Location');
}
else {
$this->redirect = null;
}
if ($this->followRedirects && $this->redirect) {
return $this->crawler = $this
->followRedirect();
}
return $this->crawler = $this
->createCrawlerFromContent($this->internalRequest
->getUri(), $this->internalResponse
->getContent(), $this->internalResponse
->getHeader('Content-Type'));
}
/**
* Makes a request in another process.
*
* @param object $request An origin request instance
*
* @return object An origin response instance
*
* @throws \RuntimeException When processing returns exit code
*/
protected function doRequestInProcess($request) {
$process = new PhpProcess($this
->getScript($request), null, null);
$process
->run();
if (!$process
->isSuccessful() || !preg_match('/^O\\:\\d+\\:/', $process
->getOutput())) {
throw new \RuntimeException(sprintf('OUTPUT: %s ERROR OUTPUT: %s', $process
->getOutput(), $process
->getErrorOutput()));
}
return unserialize($process
->getOutput());
}
/**
* Makes a request.
*
* @param object $request An origin request instance
*
* @return object An origin response instance
*/
protected abstract function doRequest($request);
/**
* Returns the script to execute when the request must be insulated.
*
* @param object $request An origin request instance
*
* @throws \LogicException When this abstract class is not implemented
*/
protected function getScript($request) {
throw new \LogicException('To insulate requests, you need to override the getScript() method.');
}
/**
* Filters the BrowserKit request to the origin one.
*
* @param Request $request The BrowserKit Request to filter
*
* @return object An origin request instance
*/
protected function filterRequest(Request $request) {
return $request;
}
/**
* Filters the origin response to the BrowserKit one.
*
* @param object $response The origin response to filter
*
* @return Response An BrowserKit Response instance
*/
protected function filterResponse($response) {
return $response;
}
/**
* Creates a crawler.
*
* This method returns null if the DomCrawler component is not available.
*
* @param string $uri A URI
* @param string $content Content for the crawler to use
* @param string $type Content type
*
* @return Crawler|null
*/
protected function createCrawlerFromContent($uri, $content, $type) {
if (!class_exists('Symfony\\Component\\DomCrawler\\Crawler')) {
return;
}
$crawler = new Crawler(null, $uri);
$crawler
->addContent($content, $type);
return $crawler;
}
/**
* Goes back in the browser history.
*
* @return Crawler
*/
public function back() {
return $this
->requestFromRequest($this->history
->back(), false);
}
/**
* Goes forward in the browser history.
*
* @return Crawler
*/
public function forward() {
return $this
->requestFromRequest($this->history
->forward(), false);
}
/**
* Reloads the current browser.
*
* @return Crawler
*/
public function reload() {
return $this
->requestFromRequest($this->history
->current(), false);
}
/**
* Follow redirects?
*
* @return Crawler
*
* @throws \LogicException If request was not a redirect
*/
public function followRedirect() {
if (empty($this->redirect)) {
throw new \LogicException('The request was not redirected.');
}
if (-1 !== $this->maxRedirects) {
if ($this->redirectCount > $this->maxRedirects) {
throw new \LogicException(sprintf('The maximum number (%d) of redirections was reached.', $this->maxRedirects));
}
}
$request = $this->internalRequest;
if (in_array($this->internalResponse
->getStatus(), array(
302,
303,
))) {
$method = 'get';
$files = array();
$content = null;
}
else {
$method = $request
->getMethod();
$files = $request
->getFiles();
$content = $request
->getContent();
}
if ('get' === strtolower($method)) {
// Don't forward parameters for GET request as it should reach the redirection URI
$parameters = array();
}
else {
$parameters = $request
->getParameters();
}
$server = $request
->getServer();
$server = $this
->updateServerFromUri($server, $this->redirect);
$this->isMainRequest = false;
$response = $this
->request($method, $this->redirect, $parameters, $files, $server, $content);
$this->isMainRequest = true;
return $response;
}
/**
* Restarts the client.
*
* It flushes history and all cookies.
*/
public function restart() {
$this->cookieJar
->clear();
$this->history
->clear();
}
/**
* Takes a URI and converts it to absolute if it is not already absolute.
*
* @param string $uri A URI
*
* @return string An absolute URI
*/
protected function getAbsoluteUri($uri) {
// already absolute?
if (0 === strpos($uri, 'http://') || 0 === strpos($uri, 'https://')) {
return $uri;
}
if (!$this->history
->isEmpty()) {
$currentUri = $this->history
->current()
->getUri();
}
else {
$currentUri = sprintf('http%s://%s/', isset($this->server['HTTPS']) ? 's' : '', isset($this->server['HTTP_HOST']) ? $this->server['HTTP_HOST'] : 'localhost');
}
// protocol relative URL
if (0 === strpos($uri, '//')) {
return parse_url($currentUri, PHP_URL_SCHEME) . ':' . $uri;
}
// anchor?
if (!$uri || '#' == $uri[0]) {
return preg_replace('/#.*?$/', '', $currentUri) . $uri;
}
if ('/' !== $uri[0]) {
$path = parse_url($currentUri, PHP_URL_PATH);
if ('/' !== substr($path, -1)) {
$path = substr($path, 0, strrpos($path, '/') + 1);
}
$uri = $path . $uri;
}
return preg_replace('#^(.*?//[^/]+)\\/.*$#', '$1', $currentUri) . $uri;
}
/**
* Makes a request from a Request object directly.
*
* @param Request $request A Request instance
* @param bool $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload())
*
* @return Crawler
*/
protected function requestFromRequest(Request $request, $changeHistory = true) {
return $this
->request($request
->getMethod(), $request
->getUri(), $request
->getParameters(), $request
->getFiles(), $request
->getServer(), $request
->getContent(), $changeHistory);
}
private function updateServerFromUri($server, $uri) {
$server['HTTP_HOST'] = $this
->extractHost($uri);
$scheme = parse_url($uri, PHP_URL_SCHEME);
$server['HTTPS'] = null === $scheme ? $server['HTTPS'] : 'https' == $scheme;
unset($server['HTTP_IF_NONE_MATCH'], $server['HTTP_IF_MODIFIED_SINCE']);
return $server;
}
private function extractHost($uri) {
$host = parse_url($uri, PHP_URL_HOST);
if ($port = parse_url($uri, PHP_URL_PORT)) {
return $host . ':' . $port;
}
return $host;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
private | property | ||
Client:: |
private | property | ||
Client:: |
protected | property | ||
Client:: |
private | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
protected | property | ||
Client:: |
public | function | Goes back in the browser history. | |
Client:: |
public | function | Clicks on a given link. | |
Client:: |
protected | function | Creates a crawler. | |
Client:: |
abstract protected | function | Makes a request. | 4 |
Client:: |
protected | function | Makes a request in another process. | |
Client:: |
private | function | ||
Client:: |
protected | function | Filters the BrowserKit request to the origin one. | 1 |
Client:: |
protected | function | Filters the origin response to the BrowserKit one. | 3 |
Client:: |
public | function | Follow redirects? | |
Client:: |
public | function | Sets whether to automatically follow redirects or not. | |
Client:: |
public | function | Goes forward in the browser history. | |
Client:: |
protected | function | Takes a URI and converts it to absolute if it is not already absolute. | |
Client:: |
public | function | Returns the CookieJar instance. | |
Client:: |
public | function | Returns the current Crawler instance. | |
Client:: |
public | function | Returns the History instance. | |
Client:: |
public | function | Returns the current BrowserKit Request instance. | |
Client:: |
public | function | Returns the current BrowserKit Response instance. | |
Client:: |
public | function | Returns the current origin Request instance. | 1 |
Client:: |
public | function | Returns the current origin response instance. | 1 |
Client:: |
protected | function | Returns the script to execute when the request must be insulated. | 3 |
Client:: |
public | function | Gets single server parameter for specified key. | |
Client:: |
public | function | Sets the insulated flag. | |
Client:: |
public | function | Reloads the current browser. | |
Client:: |
public | function | Calls a URI. | |
Client:: |
protected | function | Makes a request from a Request object directly. | |
Client:: |
public | function | Restarts the client. | |
Client:: |
public | function | Sets the maximum number of requests that crawler can follow. | |
Client:: |
public | function | Sets single server parameter. | |
Client:: |
public | function | Sets server parameters. | |
Client:: |
public | function | Submits a form. | |
Client:: |
private | function | ||
Client:: |
public | function | Constructor. | 1 |