Skip to content

Commit 411e864

Browse files
Replace HTTPlug factories by PSR-17
1 parent dbddb18 commit 411e864

File tree

19 files changed

+135
-37
lines changed

19 files changed

+135
-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

+2-4
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@
1919
"require": {
2020
"php": "^7.4 || ^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
},

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

+93-11
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
use Geocoder\Exception\QuotaExceeded;
1818
use Geocoder\Provider\AbstractProvider;
1919
use Http\Message\MessageFactory;
20-
use Http\Discovery\MessageFactoryDiscovery;
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,18 +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-
/**
41-
* @param ClientInterface $client
42-
* @param MessageFactory|null $factory
43-
*/
44-
public function __construct(ClientInterface $client, MessageFactory $factory = null)
45+
public function __construct(ClientInterface $client)
4546
{
4647
$this->client = $client;
47-
$this->messageFactory = $factory ?: MessageFactoryDiscovery::find();
48+
$this->messageFactory = $client instanceof RequestFactoryInterface && $client instanceof StreamFactoryInterface ? $client : new Psr17Factory();
4849
}
4950

5051
/**
@@ -70,7 +71,28 @@ protected function getUrlContents(string $url): string
7071
*/
7172
protected function getRequest(string $url): RequestInterface
7273
{
73-
return $this->getMessageFactory()->createRequest('GET', $url);
74+
return $this->createRequest('GET', $url);
75+
}
76+
77+
protected function createRequest(string $method, string $uri, array $headers = [], string $body = null): RequestInterface
78+
{
79+
$request = $this->messageFactory->createRequest($method, $uri);
80+
81+
foreach ($headers as $name => $value) {
82+
$request = $request->withAddedHeader($name, $value);
83+
}
84+
85+
if (null === $body) {
86+
return $request;
87+
}
88+
89+
$stream = $this->messageFactory->createStream($body);
90+
91+
if ($stream->isSeekable()) {
92+
$stream->seek(0);
93+
}
94+
95+
return $request->withBody($stream);
7496
}
7597

7698
/**
@@ -114,10 +136,70 @@ protected function getHttpClient(): ClientInterface
114136
}
115137

116138
/**
117-
* @return MessageFactory
139+
* @deprecated Use createRequest instead
118140
*/
119141
protected function getMessageFactory(): MessageFactory
120142
{
121-
return $this->messageFactory;
143+
$factory = $this->messageFactory instanceof ResponseFactoryInterface ? $this->messageFactory : new Psr17Factory();
144+
145+
return new class($factory) implements MessageFactory {
146+
private $factory;
147+
148+
public function __construct($factory)
149+
{
150+
$this->factory = $factory;
151+
}
152+
153+
public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1'): RequestInterface
154+
{
155+
$request = $this->factory->createRequest($method, $uri);
156+
157+
foreach ($headers as $name => $value) {
158+
$request = $request->withAddedHeader($name, $value);
159+
}
160+
161+
if (null !== $body) {
162+
$request = $request->withBody($this->createStream($body));
163+
}
164+
165+
return $request->withProtocolVersion($protocolVersion);
166+
}
167+
168+
public function createResponse($statusCode = 200, $reasonPhrase = null, array $headers = [], $body = null, $protocolVersion = '1.1'): ResponseInterface
169+
{
170+
$response = $this->factory->createResponse($statusCode, $reasonPhrase);
171+
172+
foreach ($headers as $name => $value) {
173+
$response = $response->withAddedHeader($name, $value);
174+
}
175+
176+
if (null !== $body) {
177+
$response = $response->withBody($this->createStream($body));
178+
}
179+
180+
return $response->withProtocolVersion($protocolVersion);
181+
}
182+
183+
private function createStream($content = ''): StreamInterface
184+
{
185+
if ($content instanceof StreamInterface) {
186+
return $content;
187+
}
188+
189+
if (\is_string($content ?? '')) {
190+
$stream = $this->factory->createStream($content ?? '');
191+
} elseif (\is_resource($content)) {
192+
$stream = $this->factory->createStreamFromResource($content);
193+
} else {
194+
throw new \InvalidArgumentException(sprintf('"%s()" expects string, resource or StreamInterface, "%s" given.', __METHOD__, get_debug_type($content)));
195+
}
196+
197+
if ($stream->isSeekable()) {
198+
$stream->seek(0);
199+
}
200+
201+
return $stream;
202+
}
203+
};
122204
}
123205
}

src/Http/composer.json

+8-6
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@
1515
],
1616
"require": {
1717
"php": "^7.4 || ^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-http/discovery": "^1.17",
19+
"psr/http-client-implementation": "^1.0",
20+
"psr/http-factory-implementation": "^1.0",
2421
"willdurand/geocoder": "^4.0"
2522
},
2623
"require-dev": {
@@ -48,5 +45,10 @@
4845
"scripts": {
4946
"test": "vendor/bin/phpunit",
5047
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
48+
},
49+
"config": {
50+
"allow-plugins": {
51+
"php-http/discovery": false
52+
}
5153
}
5254
}

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
@@ -116,7 +116,7 @@ public function getTypes(): array
116116

117117
protected function getRequest(string $url): RequestInterface
118118
{
119-
return $this->getMessageFactory()->createRequest(
119+
return $this->createRequest(
120120
'POST',
121121
$url,
122122
$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-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Geocoder\Query\GeocodeQuery;
1919
use Geocoder\Provider\AlgoliaPlaces\AlgoliaPlaces;
2020
use Http\Client\Curl\Client as HttplugClient;
21+
use Psr\Http\Client\ClientInterface;
2122

2223
/**
2324
* @author Sébastien Barré <[email protected]>
@@ -32,7 +33,7 @@ protected function getCacheDir()
3233
/**
3334
* Get a real HTTP client. If a cache dir is set to a path it will use cached responses.
3435
*
35-
* @return HttpClient
36+
* @return ClientInterface
3637
*/
3738
protected function getHttpClient($apiKey = null, $appCode = null)
3839
{

src/Provider/AlgoliaPlaces/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"require": {
1515
"php": "^7.4 || ^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
@@ -244,7 +244,7 @@ private function executePostQuery(string $endpoint, array $params)
244244
$url .= '?key='.$appKey;
245245

246246
$requestBody = json_encode($params);
247-
$request = $this->getMessageFactory()->createRequest('POST', $url, [], $requestBody);
247+
$request = $this->createRequest('POST', $url, [], $requestBody);
248248

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

src/Provider/MapQuest/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
],
1414
"require": {
1515
"php": "^7.4 || ^8.0",
16-
"geocoder-php/common-http": "^4.0",
16+
"geocoder-php/common-http": "^4.4",
1717
"willdurand/geocoder": "^4.0"
1818
},
1919
"provide": {

src/Provider/Yandex/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ composer require geocoder-php/yandex-provider
2121
The API now requires an API key. [See here for more information](https://yandex.ru/blog/mapsapi/novye-pravila-dostupa-k-api-kart?from=tech_pp).
2222

2323
```php
24-
$httpClient = new \GuzzleHttp\Client();
24+
$httpClient = new \Http\Discovery\Psr18Client();
2525
$provider = new \Geocoder\Provider\Yandex\Yandex($httpClient, null, '<your-api-key>);
2626

2727
$result = $geocoder->geocodeQuery(GeocodeQuery::create('ул.Ленина, 19, Минск 220030, Республика Беларусь'));

0 commit comments

Comments
 (0)