Skip to content

Commit acd5cc7

Browse files
Replace HTTPlug factories by PSR-17
1 parent 722fc19 commit acd5cc7

File tree

19 files changed

+142
-37
lines changed

19 files changed

+142
-37
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## 4.4.0 (2023-??-??)
4+
5+
* Added: Method `AbstractHttpProvider::createRequest()`
6+
* Deprecated: Method `AbstractHttpProvider::getMessageFactory()`
7+
38
## 4.3.0 (2022-07-30)
49

510
* Removed: Support for PHP 7.3

composer.json

+4-6
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@
1919
"require": {
2020
"php": "^8.0",
2121
"igorw/get-in": "^1.0",
22-
"php-http/discovery": "^1.4",
23-
"php-http/message-factory": "^1.0.2",
22+
"php-http/discovery": "^1.17",
2423
"php-http/promise": "^1.0",
25-
"psr/http-client": "^1.0",
2624
"psr/http-client-implementation": "^1.0",
27-
"psr/http-message-implementation": "^1.0",
25+
"psr/http-factory-implementation": "^1.0",
2826
"psr/log": "^1.0 || ^2.0 || ^3.0",
2927
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
3028
},
@@ -37,13 +35,13 @@
3735
"nyholm/nsa": "^1.1",
3836
"nyholm/psr7": "^1.0",
3937
"php-cs-fixer/shim": "^3.22",
40-
"php-http/curl-client": "^2.2",
4138
"php-http/message": "^1.0",
4239
"php-http/mock-client": "^1.0",
4340
"phpstan/extension-installer": "^1.3",
4441
"phpstan/phpstan": "^1.10",
4542
"phpstan/phpstan-phpunit": "^1.3",
4643
"phpunit/phpunit": "^9.5",
44+
"symfony/http-client": "^5.4 || ^6.3",
4745
"symfony/stopwatch": "~2.5 || ~5.0"
4846
},
4947
"suggest": {
@@ -72,7 +70,7 @@
7270
"config": {
7371
"allow-plugins": {
7472
"phpstan/extension-installer": true,
75-
"php-http/discovery": true
73+
"php-http/discovery": false
7674
},
7775
"sort-packages": true
7876
},

src/Common/composer.json

+5
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,10 @@
4343
"scripts": {
4444
"test": "vendor/bin/phpunit",
4545
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
46+
},
47+
"config": {
48+
"allow-plugins": {
49+
"php-http/discovery": false
50+
}
4651
}
4752
}

src/Http/Provider/AbstractHttpProvider.php

+95-6
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
use Geocoder\Exception\InvalidServerResponse;
1717
use Geocoder\Exception\QuotaExceeded;
1818
use Geocoder\Provider\AbstractProvider;
19-
use Http\Discovery\MessageFactoryDiscovery;
2019
use Http\Message\MessageFactory;
20+
use Http\Discovery\Psr17Factory;
2121
use Psr\Http\Client\ClientInterface;
22+
use Psr\Http\Message\RequestFactoryInterface;
2223
use Psr\Http\Message\RequestInterface;
24+
use Psr\Http\Message\ResponseFactoryInterface;
25+
use Psr\Http\Message\ResponseInterface;
26+
use Psr\Http\Message\StreamFactoryInterface;
27+
use Psr\Http\Message\StreamInterface;
2328

2429
/**
2530
* @author William Durand <[email protected]>
@@ -33,14 +38,14 @@ abstract class AbstractHttpProvider extends AbstractProvider
3338
private $client;
3439

3540
/**
36-
* @var MessageFactory
41+
* @var RequestFactoryInterface&StreamFactoryInterface
3742
*/
3843
private $messageFactory;
3944

40-
public function __construct(ClientInterface $client, MessageFactory $factory = null)
45+
public function __construct(ClientInterface $client)
4146
{
4247
$this->client = $client;
43-
$this->messageFactory = $factory ?: MessageFactoryDiscovery::find();
48+
$this->messageFactory = $client instanceof RequestFactoryInterface && $client instanceof StreamFactoryInterface ? $client : new Psr17Factory();
4449
}
4550

4651
/**
@@ -57,7 +62,28 @@ protected function getUrlContents(string $url): string
5762

5863
protected function getRequest(string $url): RequestInterface
5964
{
60-
return $this->getMessageFactory()->createRequest('GET', $url);
65+
return $this->createRequest('GET', $url);
66+
}
67+
68+
protected function createRequest(string $method, string $uri, array $headers = [], string $body = null): RequestInterface
69+
{
70+
$request = $this->messageFactory->createRequest($method, $uri);
71+
72+
foreach ($headers as $name => $value) {
73+
$request = $request->withAddedHeader($name, $value);
74+
}
75+
76+
if (null === $body) {
77+
return $request;
78+
}
79+
80+
$stream = $this->messageFactory->createStream($body);
81+
82+
if ($stream->isSeekable()) {
83+
$stream->seek(0);
84+
}
85+
86+
return $request->withBody($stream);
6187
}
6288

6389
/**
@@ -94,8 +120,71 @@ protected function getHttpClient(): ClientInterface
94120
return $this->client;
95121
}
96122

123+
/**
124+
* @deprecated Use createRequest instead
125+
*/
97126
protected function getMessageFactory(): MessageFactory
98127
{
99-
return $this->messageFactory;
128+
$factory = $this->messageFactory instanceof ResponseFactoryInterface ? $this->messageFactory : new Psr17Factory();
129+
130+
return new class($factory) implements MessageFactory {
131+
private $factory;
132+
133+
public function __construct($factory)
134+
{
135+
$this->factory = $factory;
136+
}
137+
138+
public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1'): RequestInterface
139+
{
140+
$request = $this->factory->createRequest($method, $uri);
141+
142+
foreach ($headers as $name => $value) {
143+
$request = $request->withAddedHeader($name, $value);
144+
}
145+
146+
if (null !== $body) {
147+
$request = $request->withBody($this->createStream($body));
148+
}
149+
150+
return $request->withProtocolVersion($protocolVersion);
151+
}
152+
153+
public function createResponse($statusCode = 200, $reasonPhrase = null, array $headers = [], $body = null, $protocolVersion = '1.1'): ResponseInterface
154+
{
155+
$response = $this->factory->createResponse($statusCode, $reasonPhrase);
156+
157+
foreach ($headers as $name => $value) {
158+
$response = $response->withAddedHeader($name, $value);
159+
}
160+
161+
if (null !== $body) {
162+
$response = $response->withBody($this->createStream($body));
163+
}
164+
165+
return $response->withProtocolVersion($protocolVersion);
166+
}
167+
168+
private function createStream($content = ''): StreamInterface
169+
{
170+
if ($content instanceof StreamInterface) {
171+
return $content;
172+
}
173+
174+
if (\is_string($content ?? '')) {
175+
$stream = $this->factory->createStream($content ?? '');
176+
} elseif (\is_resource($content)) {
177+
$stream = $this->factory->createStreamFromResource($content);
178+
} else {
179+
throw new \InvalidArgumentException(sprintf('"%s()" expects string, resource or StreamInterface, "%s" given.', __METHOD__, get_debug_type($content)));
180+
}
181+
182+
if ($stream->isSeekable()) {
183+
$stream->seek(0);
184+
}
185+
186+
return $stream;
187+
}
188+
};
100189
}
101190
}

src/Http/composer.json

+10-7
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
],
1616
"require": {
1717
"php": "^8.0",
18-
"php-http/client-implementation": "^1.0",
19-
"php-http/discovery": "^1.6",
20-
"php-http/httplug": "^1.0 || ^2.0",
21-
"php-http/message-factory": "^1.0.2",
22-
"psr/http-message": "^1.0 || ^2.0",
23-
"psr/http-message-implementation": "^1.0",
18+
"php": "^7.4 || ^8.0",
19+
"php-http/discovery": "^1.17",
20+
"psr/http-client-implementation": "^1.0",
21+
"psr/http-factory-implementation": "^1.0",
2422
"willdurand/geocoder": "^4.0"
2523
},
2624
"require-dev": {
@@ -48,5 +46,10 @@
4846
"scripts": {
4947
"test": "vendor/bin/phpunit",
5048
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
49+
},
50+
"config": {
51+
"allow-plugins": {
52+
"php-http/discovery": false
53+
}
5154
}
52-
}
55+
}

src/Plugin/composer.json

+5
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,10 @@
4242
"scripts": {
4343
"test": "vendor/bin/phpunit",
4444
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
45+
},
46+
"config": {
47+
"allow-plugins": {
48+
"php-http/discovery": false
49+
}
4550
}
4651
}

src/Provider/AlgoliaPlaces/AlgoliaPlaces.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function getTypes(): array
115115

116116
protected function getRequest(string $url): RequestInterface
117117
{
118-
return $this->getMessageFactory()->createRequest(
118+
return $this->createRequest(
119119
'POST',
120120
$url,
121121
$this->buildHeaders(),

src/Provider/AlgoliaPlaces/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ You should set a locale on the query. If it is missing, results may not be as co
3434
use Geocoder\Query\GeocodeQuery;
3535
use Geocoder\Query\ReverseQuery;
3636

37-
$httpClient = new \GuzzleHttp\Client();
37+
$httpClient = new \Http\Discovery\Psr18Client();
3838

3939
// Unauthenticated
4040
$provider = new \Geocoder\Provider\AlgoliaPlaces\AlgoliaPlaces($httpClient);

src/Provider/AlgoliaPlaces/Tests/AlgoliaPlacesTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Geocoder\Location;
1818
use Geocoder\Provider\AlgoliaPlaces\AlgoliaPlaces;
1919
use Geocoder\Query\GeocodeQuery;
20-
use Http\Client\Curl\Client as HttplugClient;
20+
use Http\Discovery\Psr18Client;
2121
use Psr\Http\Client\ClientInterface;
2222

2323
/**
@@ -35,7 +35,7 @@ protected function getCacheDir(): string
3535
*/
3636
protected function getHttpClient(string $apiKey = null, string $appCode = null): ClientInterface
3737
{
38-
return new CachedResponseClient(new HttplugClient(), $this->getCacheDir(), $apiKey, $appCode);
38+
return new CachedResponseClient(new Psr18Client(), $this->getCacheDir(), $apiKey, $appCode);
3939
}
4040

4141
public function testGeocodeQueryWithLocale(): void

src/Provider/AlgoliaPlaces/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"require": {
1515
"php": "^8.0",
1616
"ext-json": "*",
17-
"geocoder-php/common-http": "^4.1",
17+
"geocoder-php/common-http": "^4.4",
1818
"willdurand/geocoder": "^4.0"
1919
},
2020
"provide": {

src/Provider/ArcGISOnline/Readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Since a token is required for the `geocodeAddresses` API, the
3333
### Without a token
3434

3535
```php
36-
$httpClient = new \GuzzleHttp\Client();
36+
$httpClient = new \Http\Discovery\Psr18Client();
3737

3838
$provider = new \Geocoder\Provider\ArcGISList\ArcGISList($httpClient);
3939

@@ -45,7 +45,7 @@ $result = $geocoder->geocodeQuery(GeocodeQuery::create('Buckingham Palace, Londo
4545

4646
```php
4747

48-
$httpClient = new \GuzzleHttp\Client();
48+
$httpClient = new \Http\Discovery\Psr18Client();
4949

5050
// Your token is required.
5151
$provider = \Geocoder\Provider\ArcGISList\ArcGISList::token($httpClient, 'your-token');

src/Provider/AzureMaps/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ composer require geocoder-php/azure-maps-provider
1919
## Usage
2020

2121
```php
22-
$httpClient = new \GuzzleHttp\Client();
22+
$httpClient = new \Http\Discovery\Psr18Client();
2323

2424
// You must provide a subscription key
2525
$provider = new \Geocoder\Provider\AzureMaps\AzureMaps($httpClient, 'your-subscription-key');

src/Provider/Cache/Readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ By default, the result is cached forever.
2424
You can set a cache expiry by passing an integer representing the number of seconds as the third parameter.
2525

2626
```php
27-
$httpClient = new \GuzzleHttp\Client();
27+
$httpClient = new \Http\Discovery\Psr18Client();
2828
$provider = new \Geocoder\Provider\GoogleMaps\GoogleMaps($httpClient);
2929

3030
$psr6Cache = new ArrayCachePool(); // Requires `cache/array-adapter` package

src/Provider/FreeGeoIp/Readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Provider Website: https://freegeoip.app
1414

1515
## Usage
1616
```php
17-
$httpClient = new \GuzzleHttp\Client();
17+
$httpClient = new \Http\Discovery\Psr18Client();
1818

1919
// Use the default provider (https://freegeoip.app)
2020
$provider = new Geocoder\Provider\FreeGeoIp\FreeGeoIp($httpClient);

src/Provider/GoogleMaps/Readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This is the Google Maps provider from the PHP Geocoder. This is a **READ ONLY**
1313
## Usage
1414

1515
```php
16-
$httpClient = new \GuzzleHttp\Client();
16+
$httpClient = new \Http\Discovery\Psr18Client();
1717

1818
// You must provide an API key
1919
$provider = new \Geocoder\Provider\GoogleMaps\GoogleMaps($httpClient, null, 'your-api-key');
@@ -31,7 +31,7 @@ can use the static `business` method on the provider to create a client:
3131

3232
```php
3333

34-
$httpClient = new \GuzzleHttp\Client();
34+
$httpClient = new \Http\Discovery\Psr18Client();
3535

3636
// Client ID is required. Private key is optional.
3737
$provider = \Geocoder\Provider\GoogleMaps\GoogleMaps::business($httpClient, 'your-client-id', 'your-private-key');

src/Provider/Here/Readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ composer require geocoder-php/here-provider
2424
New applications on the Here platform use the `api_key` authentication method.
2525

2626
```php
27-
$httpClient = new \GuzzleHttp\Client();
27+
$httpClient = new \Http\Discovery\Psr18Client();
2828

2929
// You must provide an API key
3030
$provider = \Geocoder\Provider\Here\Here::createUsingApiKey($httpClient, 'your-api-key');
@@ -35,7 +35,7 @@ $result = $geocoder->geocodeQuery(GeocodeQuery::create('Buckingham Palace, Londo
3535
If you're using the legacy `app_code` authentication method, use the constructor on the provider like so:
3636

3737
```php
38-
$httpClient = new \GuzzleHttp\Client();
38+
$httpClient = new \Http\Discovery\Psr18Client();
3939

4040
// You must provide both the app_id and app_code
4141
$provider = new \Geocoder\Provider\Here\Here($httpClient, 'app-id', 'app-code');

src/Provider/MapQuest/MapQuest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ private function executePostQuery(string $endpoint, array $params): AddressColle
253253
$url .= '?key='.$appKey;
254254

255255
$requestBody = json_encode($params);
256-
$request = $this->getMessageFactory()->createRequest('POST', $url, [], $requestBody);
256+
$request = $this->createRequest('POST', $url, [], $requestBody);
257257

258258
$response = $this->getHttpClient()->sendRequest($request);
259259
$content = $this->parseHttpResponse($response, $url);

src/Provider/MapQuest/composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
],
1414
"require": {
1515
"php": "^8.0",
16-
"geocoder-php/common-http": "^4.0",
16+
"geocoder-php/common-http": "^4.4",
1717
"willdurand/geocoder": "^4.0"
1818
},
1919
"provide": {
@@ -44,4 +44,4 @@
4444
"test": "vendor/bin/phpunit",
4545
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
4646
}
47-
}
47+
}

0 commit comments

Comments
 (0)