Skip to content

Decouple from Guzzle #389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will let us use the short array suntax. See this comment: #389 (comment)

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",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes bundled with Guzzle 6, no need to require it separately IMO

"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 <tobias.nyholm@gmail.com>
*/
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 <stloyd@gmail.com>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
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