Skip to content

Commit 4839bd9

Browse files
authored
Merge pull request KnpLabs#480 from Nyholm/client-builder
Add client builder
2 parents 34a022d + d7cde53 commit 4839bd9

File tree

10 files changed

+336
-218
lines changed

10 files changed

+336
-218
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee
1818
### Changed
1919

2020
- `ApiLimitExceedException::__construct` has a new second parameter for the remaining API calls.
21+
- First parameter of `Github\Client` has changed type from `\Http\Client\HttpClient` to
22+
`Github\HttpClient\Builder`. A factory class was also added. To upgrade you need to change:
23+
24+
```php
25+
// Old way does not work:
26+
$github = new Github\Client($httpClient);
27+
28+
// New way will work:
29+
$github = new Github\Client(new Github\HttpClient\Builder($httpClient));
30+
$github = Github\Client::createWithHttpClient($httpClient);
31+
```
32+
2133

2234
## 2.0.0-rc4
2335

doc/api_version.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ For example:
88
$client = new Github\Client();
99
echo $client->getApiVersion(); // prints "v3"
1010

11-
$client = new Github\Client($httpClient, 'v2');
11+
$client = new Github\Client(new Github\HttpClient\Builder($httpClient), 'v2');
1212
echo $client->getApiVersion(); // prints "v2"
1313
```

doc/customize.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
yourself by calling `\Github\Client::setHttpClient`. A HTTP client must implement `Http\Client\HttpClient`. A list of
99
community provided clients is found here: https://packagist.org/providers/php-http/client-implementation
1010

11-
You can inject a HTTP client through `Github\Client#setHttpClient()` method:
11+
You can inject a HTTP client through the `Github\Client` constructor:
1212

1313
```php
14-
$client = new Github\Client();
15-
$client->setHttpClient(new Http\Adapter\Guzzle6\Client());
14+
$client = Github\Client::createWithHttpClient(new Http\Adapter\Guzzle6\Client());
1615
```
1716

1817
### Configure the HTTP client
@@ -37,7 +36,10 @@ class CustomUserAgentPlugin implements Plugin
3736
}
3837
}
3938

40-
$githubClient->addPlugin(new CustomUserAgentPlugin());
39+
$httpBuilder = new Github\HttpClient\Builder(new Http\Adapter\Guzzle6\Client());
40+
$httpBuilder->addPlugin(new CustomUserAgentPlugin());
41+
42+
$client = new Github\Client($httpBuilder);
4143
```
4244

4345
### Run Test Suite

doc/security.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ The following sample code authenticates as an installation using [lcobucci/jwt](
5454
to generate a JSON Web Token (JWT).
5555

5656
```php
57-
$github = new Github\Client(new GuzzleClient(), 'machine-man-preview');
57+
$builder = new Github\HttpClient\Builder(new GuzzleClient());
58+
$github = new Github\Client($builder, 'machine-man-preview');
5859

5960
$jwt = (new Builder)
6061
->setIssuer($integrationId)

lib/Github/Client.php

Lines changed: 52 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,15 @@
55
use Github\Api\ApiInterface;
66
use Github\Exception\InvalidArgumentException;
77
use Github\Exception\BadMethodCallException;
8+
use Github\HttpClient\Builder;
89
use Github\HttpClient\Plugin\Authentication;
910
use Github\HttpClient\Plugin\GithubExceptionThrower;
1011
use Github\HttpClient\Plugin\History;
1112
use Github\HttpClient\Plugin\PathPrepend;
1213
use Http\Client\Common\HttpMethodsClient;
1314
use Http\Client\Common\Plugin;
14-
use Http\Client\Common\PluginClient;
1515
use Http\Client\HttpClient;
16-
use Http\Discovery\HttpClientDiscovery;
17-
use Http\Discovery\MessageFactoryDiscovery;
18-
use Http\Discovery\StreamFactoryDiscovery;
1916
use Http\Discovery\UriFactoryDiscovery;
20-
use Http\Message\MessageFactory;
21-
use Nyholm\Psr7\Factory\StreamFactory;
2217
use Psr\Cache\CacheItemPoolInterface;
2318

2419
/**
@@ -98,45 +93,9 @@ class Client
9893
private $apiVersion;
9994

10095
/**
101-
* The object that sends HTTP messages
102-
*
103-
* @var HttpClient
104-
*/
105-
private $httpClient;
106-
107-
/**
108-
* A HTTP client with all our plugins
109-
*
110-
* @var PluginClient
111-
*/
112-
private $pluginClient;
113-
114-
/**
115-
* @var MessageFactory
116-
*/
117-
private $messageFactory;
118-
119-
/**
120-
* @var StreamFactory
96+
* @var Builder
12197
*/
122-
private $streamFactory;
123-
124-
/**
125-
* @var Plugin[]
126-
*/
127-
private $plugins = [];
128-
129-
/**
130-
* True if we should create a new Plugin client at next request.
131-
* @var bool
132-
*/
133-
private $httpClientModified = true;
134-
135-
/**
136-
* Http headers
137-
* @var array
138-
*/
139-
private $headers = [];
98+
private $httpClientBuilder;
14099

141100
/**
142101
* @var History
@@ -146,33 +105,46 @@ class Client
146105
/**
147106
* Instantiate a new GitHub client.
148107
*
149-
* @param HttpClient|null $httpClient
150-
* @param string|null $apiVersion
151-
* @param string|null $enterpriseUrl
108+
* @param Builder|null $httpClientBuilder
109+
* @param string|null $apiVersion
110+
* @param string|null $enterpriseUrl
152111
*/
153-
public function __construct(HttpClient $httpClient = null, $apiVersion = null, $enterpriseUrl = null)
112+
public function __construct(Builder $httpClientBuilder = null, $apiVersion = null, $enterpriseUrl = null)
154113
{
155-
$this->httpClient = $httpClient ?: HttpClientDiscovery::find();
156-
$this->messageFactory = MessageFactoryDiscovery::find();
157-
$this->streamFactory = StreamFactoryDiscovery::find();
158-
159114
$this->responseHistory = new History();
160-
$this->addPlugin(new GithubExceptionThrower());
161-
$this->addPlugin(new Plugin\HistoryPlugin($this->responseHistory));
162-
$this->addPlugin(new Plugin\RedirectPlugin());
163-
$this->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://api.github.com')));
164-
$this->addPlugin(new Plugin\HeaderDefaultsPlugin(array(
165-
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',
115+
$this->httpClientBuilder = $builder = $httpClientBuilder ?: new Builder();
116+
117+
$builder->addPlugin(new GithubExceptionThrower());
118+
$builder->addPlugin(new Plugin\HistoryPlugin($this->responseHistory));
119+
$builder->addPlugin(new Plugin\RedirectPlugin());
120+
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://api.github.com')));
121+
$builder->addPlugin(new Plugin\HeaderDefaultsPlugin(array(
122+
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',
123+
'Accept' => sprintf('application/vnd.github.%s+json', $this->getApiVersion()),
166124
)));
167125

168126
$this->apiVersion = $apiVersion ?: 'v3';
169-
$this->addHeaders(['Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion)]);
127+
$builder->addHeaders(['Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion)]);
170128

171129
if ($enterpriseUrl) {
172130
$this->setEnterpriseUrl($enterpriseUrl);
173131
}
174132
}
175133

134+
/**
135+
* Create a Github\Client using a HttpClient.
136+
*
137+
* @param HttpClient $httpClient
138+
*
139+
* @return Client
140+
*/
141+
public static function createWithHttpClient(HttpClient $httpClient)
142+
{
143+
$builder = new Builder($httpClient);
144+
145+
return new self($builder);
146+
}
147+
176148
/**
177149
* @param string $name
178150
*
@@ -313,15 +285,15 @@ public function authenticate($tokenOrLogin, $password = null, $authMethod = null
313285

314286
if (null === $authMethod && in_array($password, array(self::AUTH_URL_TOKEN, self::AUTH_URL_CLIENT_ID, self::AUTH_HTTP_PASSWORD, self::AUTH_HTTP_TOKEN, self::AUTH_JWT))) {
315287
$authMethod = $password;
316-
$password = null;
288+
$password = null;
317289
}
318290

319291
if (null === $authMethod) {
320292
$authMethod = self::AUTH_HTTP_PASSWORD;
321293
}
322294

323-
$this->removePlugin(Authentication::class);
324-
$this->addPlugin(new Authentication($tokenOrLogin, $password, $authMethod));
295+
$this->getHttpClientBuilder()->removePlugin(Authentication::class);
296+
$this->getHttpClientBuilder()->addPlugin(new Authentication($tokenOrLogin, $password, $authMethod));
325297
}
326298

327299
/**
@@ -331,64 +303,12 @@ public function authenticate($tokenOrLogin, $password = null, $authMethod = null
331303
*/
332304
private function setEnterpriseUrl($enterpriseUrl)
333305
{
334-
$this->removePlugin(Plugin\AddHostPlugin::class);
335-
$this->removePlugin(PathPrepend::class);
306+
$builder = $this->getHttpClientBuilder();
307+
$builder->removePlugin(Plugin\AddHostPlugin::class);
308+
$builder->removePlugin(PathPrepend::class);
336309

337-
$this->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri($enterpriseUrl)));
338-
$this->addPlugin(new PathPrepend(sprintf('/api/%s/', $this->getApiVersion())));
339-
}
340-
341-
/**
342-
* Add a new plugin to the end of the plugin chain.
343-
*
344-
* @param Plugin $plugin
345-
*/
346-
public function addPlugin(Plugin $plugin)
347-
{
348-
$this->plugins[] = $plugin;
349-
$this->httpClientModified = true;
350-
}
351-
352-
/**
353-
* Remove a plugin by its fully qualified class name (FQCN).
354-
*
355-
* @param string $fqcn
356-
*/
357-
public function removePlugin($fqcn)
358-
{
359-
foreach ($this->plugins as $idx => $plugin) {
360-
if ($plugin instanceof $fqcn) {
361-
unset($this->plugins[$idx]);
362-
$this->httpClientModified = true;
363-
}
364-
}
365-
}
366-
367-
/**
368-
* @return HttpMethodsClient
369-
*/
370-
public function getHttpClient()
371-
{
372-
if ($this->httpClientModified) {
373-
$this->httpClientModified = false;
374-
$this->pushBackCachePlugin();
375-
376-
$this->pluginClient = new HttpMethodsClient(
377-
new PluginClient($this->httpClient, $this->plugins),
378-
$this->messageFactory
379-
);
380-
}
381-
382-
return $this->pluginClient;
383-
}
384-
385-
/**
386-
* @param HttpClient $httpClient
387-
*/
388-
public function setHttpClient(HttpClient $httpClient)
389-
{
390-
$this->httpClientModified = true;
391-
$this->httpClient = $httpClient;
310+
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri($enterpriseUrl)));
311+
$builder->addPlugin(new PathPrepend(sprintf('/api/%s/', $this->getApiVersion())));
392312
}
393313

394314
/**
@@ -399,30 +319,6 @@ public function getApiVersion()
399319
return $this->apiVersion;
400320
}
401321

402-
/**
403-
* Clears used headers.
404-
*/
405-
public function clearHeaders()
406-
{
407-
$this->headers = array(
408-
'Accept' => sprintf('application/vnd.github.%s+json', $this->getApiVersion()),
409-
);
410-
411-
$this->removePlugin(Plugin\HeaderAppendPlugin::class);
412-
$this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers));
413-
}
414-
415-
/**
416-
* @param array $headers
417-
*/
418-
public function addHeaders(array $headers)
419-
{
420-
$this->headers = array_merge($this->headers, $headers);
421-
422-
$this->removePlugin(Plugin\HeaderAppendPlugin::class);
423-
$this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers));
424-
}
425-
426322
/**
427323
* Add a cache plugin to cache responses locally.
428324
*
@@ -431,16 +327,15 @@ public function addHeaders(array $headers)
431327
*/
432328
public function addCache(CacheItemPoolInterface $cachePool, array $config = [])
433329
{
434-
$this->removeCache();
435-
$this->addPlugin(new Plugin\CachePlugin($cachePool, $this->streamFactory, $config));
330+
$this->getHttpClientBuilder()->addCache($cachePool, $config);
436331
}
437332

438333
/**
439-
* Remove the cache plugin
334+
* Remove the cache plugin.
440335
*/
441336
public function removeCache()
442337
{
443-
$this->removePlugin(Plugin\CachePlugin::class);
338+
$this->getHttpClientBuilder()->removeCache();
444339
}
445340

446341
/**
@@ -460,7 +355,6 @@ public function __call($name, $args)
460355
}
461356

462357
/**
463-
*
464358
* @return null|\Psr\Http\Message\ResponseInterface
465359
*/
466360
public function getLastResponse()
@@ -469,20 +363,18 @@ public function getLastResponse()
469363
}
470364

471365
/**
472-
* Make sure to move the cache plugin to the end of the chain
366+
* @return HttpMethodsClient
473367
*/
474-
private function pushBackCachePlugin()
368+
public function getHttpClient()
475369
{
476-
$cachePlugin = null;
477-
foreach ($this->plugins as $i => $plugin) {
478-
if ($plugin instanceof Plugin\CachePlugin) {
479-
$cachePlugin = $plugin;
480-
unset($this->plugins[$i]);
481-
482-
$this->plugins[] = $cachePlugin;
370+
return $this->getHttpClientBuilder()->getHttpClient();
371+
}
483372

484-
return;
485-
}
486-
}
373+
/**
374+
* @return Builder
375+
*/
376+
protected function getHttpClientBuilder()
377+
{
378+
return $this->httpClientBuilder;
487379
}
488380
}

0 commit comments

Comments
 (0)