From 0fc8872edfaf9fc05aa5395066c1936bd14d8b03 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sat, 18 Jul 2026 18:55:02 +0400 Subject: [PATCH 1/5] [#563] Refactor HttpClient request factory --- .../Factories/HttpClientFactory.php | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/HttpClient/Factories/HttpClientFactory.php b/src/HttpClient/Factories/HttpClientFactory.php index d03205be..946ca452 100644 --- a/src/HttpClient/Factories/HttpClientFactory.php +++ b/src/HttpClient/Factories/HttpClientFactory.php @@ -10,11 +10,9 @@ namespace Quantum\HttpClient\Factories; -use Quantum\App\Exceptions\BaseException; -use Quantum\Di\Exceptions\DiException; use Quantum\HttpClient\HttpClient; -use Quantum\Di\Di; -use ReflectionException; +use Curl\MultiCurl; +use Curl\Curl; /** * Class HttpClientFactory @@ -22,31 +20,18 @@ */ class HttpClientFactory { - private ?HttpClient $instance = null; - - /** - * @throws DiException|BaseException|ReflectionException - */ - public static function get(): HttpClient + public static function createRequest(string $url, ?Curl $client = null): HttpClient { - if (!Di::isRegistered(self::class)) { - Di::register(self::class); - } - - return Di::get(self::class)->resolve(); + return (new HttpClient())->createRequest($url, $client); } - public function resolve(): HttpClient + public static function createMultiRequest(?MultiCurl $client = null): HttpClient { - if (!$this->instance) { - $this->instance = $this->createInstance(); - } - - return $this->instance; + return (new HttpClient())->createMultiRequest($client); } - private function createInstance(): HttpClient + public static function createAsyncMultiRequest(callable $success, callable $error, ?MultiCurl $client = null): HttpClient { - return new HttpClient(); + return (new HttpClient())->createAsyncMultiRequest($success, $error, $client); } } From 578ae71aac4d1f6474476cea9f0e21576fe9b7ac Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sat, 18 Jul 2026 18:58:49 +0400 Subject: [PATCH 2/5] [#563] Remove unused HttpClient type enum --- src/HttpClient/Enums/HttpClientType.php | 27 ------------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/HttpClient/Enums/HttpClientType.php diff --git a/src/HttpClient/Enums/HttpClientType.php b/src/HttpClient/Enums/HttpClientType.php deleted file mode 100644 index a57c3916..00000000 --- a/src/HttpClient/Enums/HttpClientType.php +++ /dev/null @@ -1,27 +0,0 @@ - Date: Sat, 18 Jul 2026 19:07:53 +0400 Subject: [PATCH 3/5] [#563] Add HttpClient request helpers --- .../Factories/HttpClientFactory.php | 14 ++++---- src/HttpClient/Helpers/http_client.php | 34 +++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/HttpClient/Helpers/http_client.php diff --git a/src/HttpClient/Factories/HttpClientFactory.php b/src/HttpClient/Factories/HttpClientFactory.php index 946ca452..51e09ca8 100644 --- a/src/HttpClient/Factories/HttpClientFactory.php +++ b/src/HttpClient/Factories/HttpClientFactory.php @@ -11,8 +11,6 @@ namespace Quantum\HttpClient\Factories; use Quantum\HttpClient\HttpClient; -use Curl\MultiCurl; -use Curl\Curl; /** * Class HttpClientFactory @@ -20,18 +18,18 @@ */ class HttpClientFactory { - public static function createRequest(string $url, ?Curl $client = null): HttpClient + public static function createRequest(string $url): HttpClient { - return (new HttpClient())->createRequest($url, $client); + return (new HttpClient())->createRequest($url); } - public static function createMultiRequest(?MultiCurl $client = null): HttpClient + public static function createMultiRequest(): HttpClient { - return (new HttpClient())->createMultiRequest($client); + return (new HttpClient())->createMultiRequest(); } - public static function createAsyncMultiRequest(callable $success, callable $error, ?MultiCurl $client = null): HttpClient + public static function createAsyncMultiRequest(callable $success, callable $error): HttpClient { - return (new HttpClient())->createAsyncMultiRequest($success, $error, $client); + return (new HttpClient())->createAsyncMultiRequest($success, $error); } } diff --git a/src/HttpClient/Helpers/http_client.php b/src/HttpClient/Helpers/http_client.php new file mode 100644 index 00000000..ed4226c3 --- /dev/null +++ b/src/HttpClient/Helpers/http_client.php @@ -0,0 +1,34 @@ + Date: Sat, 18 Jul 2026 19:29:28 +0400 Subject: [PATCH 4/5] [#563] Update HttpClient factory helper tests --- .../Factories/HttpClientFactoryTest.php | 53 +++++++++---------- .../Helpers/HttpClientHelperFunctionsTest.php | 49 +++++++++++++++++ 2 files changed, 75 insertions(+), 27 deletions(-) create mode 100644 tests/Unit/HttpClient/Helpers/HttpClientHelperFunctionsTest.php diff --git a/tests/Unit/HttpClient/Factories/HttpClientFactoryTest.php b/tests/Unit/HttpClient/Factories/HttpClientFactoryTest.php index 771f6cfa..933b241b 100644 --- a/tests/Unit/HttpClient/Factories/HttpClientFactoryTest.php +++ b/tests/Unit/HttpClient/Factories/HttpClientFactoryTest.php @@ -3,49 +3,48 @@ namespace Quantum\Tests\Unit\HttpClient\Factories; use Quantum\HttpClient\Factories\HttpClientFactory; +use Quantum\HttpClient\Adapters\MultiCurlAdapter; +use Quantum\HttpClient\Adapters\CurlAdapter; use Quantum\Tests\Unit\AppTestCase; use Quantum\HttpClient\HttpClient; -use Quantum\Di\Di; class HttpClientFactoryTest extends AppTestCase { - public function setUp(): void + public function testHttpClientFactoryCreatesSingleRequest(): void { - parent::setUp(); + $httpClient1 = HttpClientFactory::createRequest('https://example.com'); + $httpClient2 = HttpClientFactory::createRequest('https://example.org'); - $this->resetHttpClientFactory(); + $this->assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertInstanceOf(CurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); } - public function testHttpClientFactoryInstance(): void + public function testHttpClientFactoryCreatesMultiRequest(): void { - $this->assertInstanceOf(HttpClient::class, HttpClientFactory::get()); - } - - public function testHttpClientFactoryReturnsSameInstance(): void - { - $httpClient1 = HttpClientFactory::get(); - $httpClient2 = HttpClientFactory::get(); + $httpClient1 = HttpClientFactory::createMultiRequest(); + $httpClient2 = HttpClientFactory::createMultiRequest(); - $this->assertSame($httpClient1, $httpClient2); + $this->assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertTrue($httpClient1->isMultiRequest()); + $this->assertInstanceOf(MultiCurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); } - public function testHttpClientFactoryResolveReturnsSameInstance(): void + public function testHttpClientFactoryCreatesAsyncMultiRequest(): void { - $factory = Di::get(HttpClientFactory::class); + $success = static function (): void { + }; - $httpClient1 = $factory->resolve(); - $httpClient2 = $factory->resolve(); + $error = static function (): void { + }; - $this->assertSame($httpClient1, $httpClient2); - } - - private function resetHttpClientFactory(): void - { - if (!Di::isRegistered(HttpClientFactory::class)) { - Di::register(HttpClientFactory::class); - } + $httpClient1 = HttpClientFactory::createAsyncMultiRequest($success, $error); + $httpClient2 = HttpClientFactory::createAsyncMultiRequest($success, $error); - $factory = Di::get(HttpClientFactory::class); - $this->setPrivateProperty($factory, 'instance', null); + $this->assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertTrue($httpClient1->isMultiRequest()); + $this->assertInstanceOf(MultiCurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); } } diff --git a/tests/Unit/HttpClient/Helpers/HttpClientHelperFunctionsTest.php b/tests/Unit/HttpClient/Helpers/HttpClientHelperFunctionsTest.php new file mode 100644 index 00000000..b4663273 --- /dev/null +++ b/tests/Unit/HttpClient/Helpers/HttpClientHelperFunctionsTest.php @@ -0,0 +1,49 @@ +assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertInstanceOf(CurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); + } + + public function testHttpMultiRequestHelperCreatesMultiRequest(): void + { + $httpClient1 = httpMultiRequest(); + $httpClient2 = httpMultiRequest(); + + $this->assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertTrue($httpClient1->isMultiRequest()); + $this->assertInstanceOf(MultiCurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); + } + + public function testHttpAsyncMultiRequestHelperCreatesAsyncMultiRequest(): void + { + $success = static function (): void { + }; + + $error = static function (): void { + }; + + $httpClient1 = httpAsyncMultiRequest($success, $error); + $httpClient2 = httpAsyncMultiRequest($success, $error); + + $this->assertInstanceOf(HttpClient::class, $httpClient1); + $this->assertTrue($httpClient1->isMultiRequest()); + $this->assertInstanceOf(MultiCurlAdapter::class, $httpClient1->getAdapter()); + $this->assertNotSame($httpClient1, $httpClient2); + } +} From 34b554c60ca0d2e0844182df040cdfbed18b1465 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Sat, 18 Jul 2026 19:51:21 +0400 Subject: [PATCH 5/5] [#563] Align HttpClient adapter start contract --- src/HttpClient/Adapters/CurlAdapter.php | 7 ++----- src/HttpClient/Adapters/MultiCurlAdapter.php | 7 ++----- src/HttpClient/Contracts/HttpClientAdapterInterface.php | 3 +-- tests/Unit/HttpClient/Adapters/CurlAdapterTest.php | 3 ++- tests/Unit/HttpClient/Adapters/MultiCurlAdapterTest.php | 3 ++- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/HttpClient/Adapters/CurlAdapter.php b/src/HttpClient/Adapters/CurlAdapter.php index 0efa7f8e..b21bb2e0 100644 --- a/src/HttpClient/Adapters/CurlAdapter.php +++ b/src/HttpClient/Adapters/CurlAdapter.php @@ -82,12 +82,9 @@ public function buildPostData($data) return $this->client->buildPostData($data); } - /** - * @return mixed - */ - public function start() + public function start(): void { - return $this->client->exec(); + $this->client->exec(); } /** diff --git a/src/HttpClient/Adapters/MultiCurlAdapter.php b/src/HttpClient/Adapters/MultiCurlAdapter.php index 825b8512..8ace7e4c 100644 --- a/src/HttpClient/Adapters/MultiCurlAdapter.php +++ b/src/HttpClient/Adapters/MultiCurlAdapter.php @@ -54,12 +54,9 @@ public function error(callable $callback): MultiCurlAdapterInterface return $this; } - /** - * @return mixed - */ - public function start() + public function start(): void { - return $this->client->start(); + $this->client->start(); } /** diff --git a/src/HttpClient/Contracts/HttpClientAdapterInterface.php b/src/HttpClient/Contracts/HttpClientAdapterInterface.php index be48c272..f1ddbcd3 100644 --- a/src/HttpClient/Contracts/HttpClientAdapterInterface.php +++ b/src/HttpClient/Contracts/HttpClientAdapterInterface.php @@ -18,9 +18,8 @@ interface HttpClientAdapterInterface { /** * Starts request execution - * @return mixed */ - public function start(); + public function start(): void; /** * Sets request header diff --git a/tests/Unit/HttpClient/Adapters/CurlAdapterTest.php b/tests/Unit/HttpClient/Adapters/CurlAdapterTest.php index af0cac78..497f1909 100644 --- a/tests/Unit/HttpClient/Adapters/CurlAdapterTest.php +++ b/tests/Unit/HttpClient/Adapters/CurlAdapterTest.php @@ -36,7 +36,8 @@ public function testCurlAdapterDelegatesRequestMethods(): void $this->assertSame($adapter, $adapter->setOpt(CURLOPT_TIMEOUT, 10)); $this->assertSame($adapter, $adapter->setOpts([CURLOPT_CONNECTTIMEOUT => 5])); $this->assertSame('a=1', $adapter->buildPostData(['a' => 1])); - $this->assertSame('ok', $adapter->start()); + + $adapter->start(); } public function testCurlAdapterDelegatesResponseMethods(): void diff --git a/tests/Unit/HttpClient/Adapters/MultiCurlAdapterTest.php b/tests/Unit/HttpClient/Adapters/MultiCurlAdapterTest.php index f950bb45..64793e4c 100644 --- a/tests/Unit/HttpClient/Adapters/MultiCurlAdapterTest.php +++ b/tests/Unit/HttpClient/Adapters/MultiCurlAdapterTest.php @@ -40,7 +40,8 @@ public function testMultiCurlAdapterDelegatesRequestMethods(): void $this->assertSame($adapter, $adapter->setOpts([CURLOPT_CONNECTTIMEOUT => 5])); $this->assertInstanceOf(CurlAdapter::class, $adapter->addGet('https://example.com', ['a' => 1])); $this->assertInstanceOf(CurlAdapter::class, $adapter->addPost('https://example.com', 'payload', true)); - $this->assertNull($adapter->start()); + + $adapter->start(); } public function testMultiCurlAdapterRegistersCallbacks(): void