Skip to content

Commit

Permalink
Decouple from Guzzle by using HTTPlug
Browse files Browse the repository at this point in the history
  • Loading branch information
Nyholm committed Jul 18, 2016
1 parent eea342d commit fcfc29c
Show file tree
Hide file tree
Showing 48 changed files with 1,001 additions and 1,882 deletions.
1 change: 0 additions & 1 deletion .styleci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
preset: psr2

enabled:
- long_array_syntax
- return
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
language: php

php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
Expand Down
29 changes: 8 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Uses [GitHub API v3](http://developer.github.com/v3/). The object API is very si

## Features

* Follows PSR-0 conventions and coding standard: autoload friendly
* Follows PSR-4 conventions and coding standard: autoload friendly
* Light and fast thanks to lazy loading of API classes
* Extensively tested and documented

## Requirements

* PHP >= 5.3.2 with [cURL](http://php.net/manual/en/book.curl.php) extension,
* PHP >= 5.5
* [Guzzle](https://github.com/guzzle/guzzle) library,
* (optional) PHPUnit to run tests.

Expand All @@ -28,21 +28,12 @@ The first step to use `php-github-api` is to download composer:
$ curl -s http://getcomposer.org/installer | php
```

Then we have to install our dependencies using:
Then run the following command to require the library:
```bash
$ php composer.phar install
```
Now we can use autoloader from Composer by:

```json
{
"require": {
"knplabs/github-api": "~1.4"
}
}
$ php composer.phar require knplabs/github-api php-http/guzzle6-adapter
```

> `php-github-api` follows the PSR-4 convention names for its classes, which means you can easily integrate `php-github-api` classes loading in your own autoloader.
Why `php-http/guzzle6-adapter`? We are decoupled form any HTTP messaging client with help by [HTTPlug](http://httplug.io/). Read about clients in our [docs](doc/customize.md).

## Using Laravel?

Expand Down Expand Up @@ -70,19 +61,15 @@ From `$client` object, you can access to all GitHub.
// This file is generated by Composer
require_once 'vendor/autoload.php';

$client = new \Github\Client(
new \Github\HttpClient\CachedHttpClient(array('cache_dir' => '/tmp/github-api-cache'))
);
$client = new \Github\Client();
$client->useCache();

// Or select directly which cache you want to use
$client = new \Github\HttpClient\CachedHttpClient();
$client->setCache(
$client->useCache(
// Built in one, or any cache implementing this interface:
// Github\HttpClient\Cache\CacheInterface
new \Github\HttpClient\Cache\FilesystemCache('/tmp/github-api-cache')
);

$client = new \Github\Client($client);
```

Using cache, the client will get cached responses if resources haven't changed since last time,
Expand Down
10 changes: 7 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
}
],
"require": {
"php": ">=5.3.2",
"ext-curl": "*",
"guzzle/guzzle": "~3.7"
"php": "^5.5|^7.0",
"php-http/httplug": "^1.0",
"php-http/discovery": "^1.0",
"php-http/client-implementation": "^1.0",
"php-http/client-common": "^1.1"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"php-http/guzzle6-adapter": "~1.0",
"guzzlehttp/psr7": "^1.2",
"sllh/php-cs-fixer-styleci-bridge": "~1.3"
},
"suggest": {
Expand Down
59 changes: 21 additions & 38 deletions doc/customize.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,43 @@
## Customize `php-github-api` and testing
[Back to the navigation](README.md)

### Configure the http client

Wanna change, let's say, the http client User Agent?
### Inject a new HTTP client instance

```php
$client->getHttpClient()->setOption('user_agent', 'My new User Agent');
```

See all available options in `Github/HttpClient/HttpClient.php`

### Guzzle events
`php-github-api` relies on `php-http/discovery` to find an installed HTTP client. You may specify a HTTP client
yourself by calling `\Github\Client::setHttpClient`. A HTTP client must implement `Http\Client\HttpClient`. A list of
community provided clients is found here: https://packagist.org/providers/php-http/client-implementation

If you need to perform any special action on request/response use guzzle events:
You can inject a HTTP client through `Github\Client#setHttpClient()` method:

```php
use Guzzle\Common\Event;
use Github\HttpClient\Message\ResponseMediator;

$client->getHttpClient()->addListener('request.success', function(Event $event) {
$remaining = ResponseMediator::getApiLimit($event['response']);

var_dump($remaining);
});

$client->user()->show('cursedcoder');
$client = new Github\Client();
$client->setHttpClient(new Http\Adapter\Guzzle6\Client());
```

see list of events http://guzzle3.readthedocs.org/http-client/request.html#plugins-and-events
### Configure the HTTP client

### Inject a new http client instance

`php-github-api` provides a curl-based implementation of a http client.
If you want to use your own http client implementation, inject it to the `Github\Client` instance:
Wanna change, let's say, the HTTP client User Agent? You need to create a Plugin that modifies the
request. Read more about [HTTPlug plugins here](http://docs.php-http.org/en/latest/plugins/introduction.html#how-it-works).

```php
use Github\HttpClient\HttpClient;
use Http\Client\Common\Plugin;
use Psr\Http\Message\RequestInterface;

// create a custom http client
class MyHttpClient extends HttpClient
class CustomUserAgentPlugin implements Plugin
{
public function request($url, array $parameters = array(), $httpMethod = 'GET', array $headers = array())
/**
* {@inheritdoc}
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
// send the request and return the raw response
$request->withHeader('user-agent', 'Foobar');

return $next($request);
}
}
```

> Your http client implementation may not extend `Github\HttpClient\HttpClient`, but only implement `Github\HttpClient\HttpClientInterface`.

You can now inject your http client through `Github\Client#setHttpClient()` method:

```php
$client = new Github\Client();
$client->setHttpClient(new MyHttpClient());
$githubClient->addPlugin(new CustomUserAgentPlugin());
```

### Run Test Suite
Expand Down
35 changes: 19 additions & 16 deletions lib/Github/Api/AbstractApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function setPerPage($perPage)
* @param array $parameters GET parameters.
* @param array $requestHeaders Request Headers.
*
* @return \Guzzle\Http\EntityBodyInterface|mixed|string
* @return array|string
*/
protected function get($path, array $parameters = array(), $requestHeaders = array())
{
Expand All @@ -73,7 +73,12 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr
if (array_key_exists('ref', $parameters) && is_null($parameters['ref'])) {
unset($parameters['ref']);
}
$response = $this->client->getHttpClient()->get($path, $parameters, $requestHeaders);

if (count($parameters) > 0) {
$path .= '?'.http_build_query($parameters);
}

$response = $this->client->getHttpClient()->get($path, $requestHeaders);

return ResponseMediator::getContent($response);
}
Expand All @@ -85,17 +90,15 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr
* @param array $parameters HEAD parameters.
* @param array $requestHeaders Request headers.
*
* @return \Guzzle\Http\Message\Response
* @return \Psr\Http\Message\ResponseInterface
*/
protected function head($path, array $parameters = array(), $requestHeaders = array())
{
if (array_key_exists('ref', $parameters) && is_null($parameters['ref'])) {
unset($parameters['ref']);
}

$response = $this->client->getHttpClient()->request($path, null, 'HEAD', $requestHeaders, array(
'query' => $parameters
));
$response = $this->client->getHttpClient()->head($path.'?'.http_build_query($parameters), $requestHeaders);

return $response;
}
Expand All @@ -120,17 +123,17 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar
* Send a POST request with raw data.
*
* @param string $path Request path.
* @param $body Request body.
* @param string $body Request body.
* @param array $requestHeaders Request headers.
*
* @return \Guzzle\Http\EntityBodyInterface|mixed|string
* @return array|string
*/
protected function postRaw($path, $body, $requestHeaders = array())
{
$response = $this->client->getHttpClient()->post(
$path,
$body,
$requestHeaders
$requestHeaders,
$body
);

return ResponseMediator::getContent($response);
Expand All @@ -147,8 +150,8 @@ protected function patch($path, array $parameters = array(), $requestHeaders = a
{
$response = $this->client->getHttpClient()->patch(
$path,
$this->createJsonBody($parameters),
$requestHeaders
$requestHeaders,
$this->createJsonBody($parameters)
);

return ResponseMediator::getContent($response);
Expand All @@ -165,8 +168,8 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr
{
$response = $this->client->getHttpClient()->put(
$path,
$this->createJsonBody($parameters),
$requestHeaders
$requestHeaders,
$this->createJsonBody($parameters)
);

return ResponseMediator::getContent($response);
Expand All @@ -183,8 +186,8 @@ protected function delete($path, array $parameters = array(), $requestHeaders =
{
$response = $this->client->getHttpClient()->delete(
$path,
$this->createJsonBody($parameters),
$requestHeaders
$requestHeaders,
$this->createJsonBody($parameters)
);

return ResponseMediator::getContent($response);
Expand Down
62 changes: 62 additions & 0 deletions lib/Github/Api/AcceptHeaderTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Github\Api;

/**
* A trait to make sure we add accept headers on all requests.
*
* @author Tobias Nyholm <[email protected]>
*/
trait AcceptHeaderTrait
{
protected $acceptHeaderValue = null;

protected function get($path, array $parameters = array(), $requestHeaders = array())
{
return parent::get($path, $parameters, $this->mergeHeaders($requestHeaders));
}

protected function head($path, array $parameters = array(), $requestHeaders = array())
{
return parent::head($path, $parameters, $this->mergeHeaders($requestHeaders));
}

protected function post($path, array $parameters = array(), $requestHeaders = array())
{
return parent::post($path, $parameters, $this->mergeHeaders($requestHeaders));
}

protected function postRaw($path, $body, $requestHeaders = array())
{
return parent::postRaw($path, $body, $this->mergeHeaders($requestHeaders));
}

protected function patch($path, array $parameters = array(), $requestHeaders = array())
{
return parent::patch($path, $parameters, $this->mergeHeaders($requestHeaders));
}

protected function put($path, array $parameters = array(), $requestHeaders = array())
{
return parent::put($path, $parameters, $this->mergeHeaders($requestHeaders));
}

protected function delete($path, array $parameters = array(), $requestHeaders = array())
{
return parent::delete($path, $parameters, $this->mergeHeaders($requestHeaders));
}

/**
* Append a new accept header on all requests
* @return array
*/
private function mergeHeaders(array $headers = array())
{
$default = array();
if ($this->acceptHeaderValue) {
$default = array('Accept' => $this->acceptHeaderValue);
}

return array_merge($default, $headers);
}
}
2 changes: 1 addition & 1 deletion lib/Github/Api/Enterprise/ManagementConsole.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function keys($hash)
* @param string $uri the request URI
* @param string $hash md5 hash of your license
*
* @return \Guzzle\Http\EntityBodyInterface|mixed|string
* @return array|string
*/
protected function getWithLicenseHash($uri, $hash)
{
Expand Down
10 changes: 6 additions & 4 deletions lib/Github/Api/GitData/Blobs.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@
namespace Github\Api\GitData;

use Github\Api\AbstractApi;
use Github\Api\AcceptHeaderTrait;
use Github\Exception\MissingArgumentException;

/**
* @link http://developer.github.com/v3/git/blobs/
* @author Joseph Bielawski <[email protected]>
* @author Tobias Nyholm <[email protected]>
*/
class Blobs extends AbstractApi
{
use AcceptHeaderTrait;

/**
* Configure the Acccept header depending on the blob type.
*
* @param string|null $bodyType
*/
public function configure($bodyType = null)
{
if ('raw' == $bodyType) {
$this->client->setHeaders(array(
'Accept' => sprintf('application/vnd.github.%s.raw', $this->client->getOption('api_version'))
));
if ('raw' === $bodyType) {
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.raw', $this->client->getOption('api_version'));
}
}

Expand Down
Loading

0 comments on commit fcfc29c

Please sign in to comment.