Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@
"php": "^7.2|^8",
"php-http/client-implementation": "^1",
Comment on lines +45 to 46

Copilot AI Jan 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description suggests this is not a big BC break, but composer.json now requires PHP ^8 (dropping ^7.2|^8). If this is intentional, it should be called out explicitly as a BC break (and aligned with the project’s release/UPGRADE notes). If not intentional, restore the previous PHP constraint.

Copilot uses AI. Check for mistakes.
"php-http/message": "^1.5",
"php-http/message-factory": "^1.1",
"php-http/discovery": "^1.14",
"symfony/http-foundation": "^2.1|^3|^4|^5|^6|^7|^8",
"moneyphp/money": "^3.1|^4.0.3"
"moneyphp/money": "^3.1|^4.0.3",
"psr/http-factory": "^1"
},
"require-dev": {
"omnipay/tests": "^4.1",
"php-http/mock-client": "^1.6",
"php-http/guzzle7-adapter": "^1",
"squizlabs/php_codesniffer": "^3.8.1",
"http-interop/http-factory-guzzle": "^1.1"
"http-interop/http-factory-guzzle": "^1.1",
"php-http/message-factory": "^1.1"
},
Comment on lines 53 to 60

Copilot AI Jan 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

composer.json moves php-http/message-factory to require-dev, but production code (e.g., src/Common/Http/AbstractClient.php and src/Common/Http/Client.php) still references Http\Message\RequestFactory in imports and type declarations. If users install without require-dev, PHP will fatal when loading these classes. Either keep php-http/message-factory in require, or remove the hard type dependency (e.g., accept an untyped legacy factory and only interact with it behind an interface_exists/class_exists check).

Copilot uses AI. Check for mistakes.
"extra": {
"branch-alias": {
Expand Down
31 changes: 20 additions & 11 deletions src/Common/Http/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace Omnipay\Common\Http;

use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Message\RequestFactory;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Omnipay\Common\Http\Exception\NetworkException;
use Omnipay\Common\Http\Exception\RequestException;
use Psr\Http\Message\RequestInterface;
Expand All @@ -16,21 +14,24 @@ class Client implements ClientInterface
{
/**
* The Http Client which implements `public function sendRequest(RequestInterface $request)`
* Note: Will be changed to PSR-18 when released
*
* @var HttpClient
* @var \Psr\Http\Client\ClientInterface|\Http\Client\HttpClient
*/
private $httpClient;

/**
* @var RequestFactory
* @var \Psr\Http\Message\RequestFactoryInterface|\Http\Message\RequestFactory
*/
private $requestFactory;

public function __construct($httpClient = null, ?RequestFactory $requestFactory = null)
/**
* @param \Psr\Http\Client\ClientInterface|\Http\Client\HttpClient|null $httpClient
* @param \Psr\Http\Message\RequestFactoryInterface|\Http\Message\RequestFactory|null $requestFactory
*/
public function __construct($httpClient = null, $requestFactory = null)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively we could broaden them, so ?RequestFactory|RequestFactoryInterface`

{
$this->httpClient = $httpClient ?: HttpClientDiscovery::find();
$this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find();
$this->httpClient = $httpClient ?: Psr18ClientDiscovery::find();
$this->requestFactory = $requestFactory ?: Psr17FactoryDiscovery::findRequestFactory();
}

/**
Expand All @@ -49,7 +50,15 @@ public function request(
$body = null,
$protocolVersion = '1.1'
) {
$request = $this->requestFactory->createRequest($method, $uri, $headers, $body, $protocolVersion);
$request = $this->requestFactory->createRequest($method, $uri)->withProtocolVersion($protocolVersion);

foreach ($headers as $name => $value) {
$request = $request->withHeader($name, $value);
}

if (null !== $body) {
$request = $request->withBody($body);
}

return $this->sendRequest($request);
}
Expand Down
38 changes: 24 additions & 14 deletions tests/Common/Http/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Http\Message\RequestFactory;
use Omnipay\Common\Http\Exception\RequestException;
use Omnipay\Tests\TestCase;
use Psr\Http\Message\RequestFactoryInterface;

class ClientTest extends TestCase
{
Expand All @@ -26,9 +27,6 @@ public function testSend()
$mockFactory->shouldReceive('createRequest')->withArgs([
'GET',
'/path',
[],
null,
'1.1',
])->andReturn($request);

$mockClient->shouldReceive('sendRequest')
Expand All @@ -37,13 +35,34 @@ public function testSend()
->once();

$this->assertSame($response, $client->request('GET', '/path'));
}

public function testSendPsrFactory()
{
$mockClient = m::mock(\Psr\Http\Client\ClientInterface::class);
$mockFactory = m::mock(RequestFactoryInterface::class);
$client = new Client($mockClient, $mockFactory);

$request = new Request('GET', '/path');
$response = new Response();

$mockFactory->shouldReceive('createRequest')->withArgs([
'GET',
'/path',
])->andReturn($request);

$mockClient->shouldReceive('sendRequest')
->with($request)
->andReturn($response)
->once();

$this->assertSame($response, $client->request('GET', '/path'));
}

public function testSendException()
{
$mockClient = m::mock(HttpClient::class);
$mockFactory = m::mock(RequestFactory::class);
$mockClient = m::mock(\Psr\Http\Client\ClientInterface::class);
$mockFactory = m::mock(RequestFactoryInterface::class);
$client = new Client($mockClient, $mockFactory);

$request = new Request('GET', '/path');
Expand All @@ -52,9 +71,6 @@ public function testSendException()
$mockFactory->shouldReceive('createRequest')->withArgs([
'GET',
'/path',
[],
null,
'1.1',
])->andReturn($request);

$mockClient->shouldReceive('sendRequest')
Expand All @@ -79,9 +95,6 @@ public function testSendNetworkException()
$mockFactory->shouldReceive('createRequest')->withArgs([
'GET',
'/path',
[],
null,
'1.1',
])->andReturn($request);

$mockClient->shouldReceive('sendRequest')
Expand All @@ -106,9 +119,6 @@ public function testSendExceptionGetRequest()
$mockFactory->shouldReceive('createRequest')->withArgs([
'GET',
'/path',
[],
null,
'1.1',
])->andReturn($request);

$exception = new \Exception('Something went wrong');
Expand Down