Skip to content
Closed
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
59 changes: 17 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,24 @@ Uses [GitHub API v3](http://developer.github.com/v3/). The object API is very si

## Requirements

* PHP >= 5.3.2 with [cURL](http://php.net/manual/en/book.curl.php) extension,
* [Guzzle](https://github.com/guzzle/guzzle) library,
* (optional) PHPUnit to run tests.
* PHP >= 5.4
* (optional) [php-httplug/guzzle5-adapter](https://github.com/php-http/guzzle5-adapter) to use with a guzzle 5 http client
* (optional) [php-httplug/guzzle6-adapter](https://github.com/php-http/guzzle6-adapter) to use with a guzzle 6 http client

## Autoload

The new version of `php-github-api` using [Composer](http://getcomposer.org).
The first step to use `php-github-api` is to download composer:

```bash
$ 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-github-api` follows the PSR-0 convention names for its classes, which means you can easily integrate `php-github-api` classes loading in your own autoloader.
> `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.

## Using Laravel?

Expand All @@ -56,38 +46,23 @@ Now we can use autoloader from Composer by:
// This file is generated by Composer
require_once 'vendor/autoload.php';

$client = new \Github\Client();
$repositories = $client->api('user')->repositories('ornicar');
```

From `$client` object, you can access to all GitHub.

## Cache usage

```php
<?php

// 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'))
new \Github\HttpClient\HttplugClient(
new \Http\Adapter\Guzzle6\Client( // Only available when you require the php-httplug/guzzle6-adapter lib
new \GuzzleHttp\Client()
),
new \Github\Factory\RequestFactory()
)
);

// Or select directly which cache you want to use
$client = new \Github\HttpClient\CachedHttpClient();
$client->setCache(
// 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);
$users = $client->api('user')->all();
```

Using cache, the client will get cached responses if resources haven't changed since last time,
**without** reaching the `X-Rate-Limit` [imposed by github](http://developer.github.com/v3/#rate-limiting).
From `$client` object, you can access to all GitHub.

## Cache usage

TBD

## Documentation

Expand Down
14 changes: 8 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@
}
],
"require": {
"php": ">=5.3.2",
"ext-curl": "*",
"guzzle/guzzle": "~3.7"
"php": ">=5.4",
"php-http/httplug": "1.0.0-RC1",
"php-http/promise": "1.0.0-RC1",
"zendframework/zend-diactoros": "^1.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"sllh/php-cs-fixer-styleci-bridge": "~1.3"
"phpspec/phpspec": "^2.4",
"php-http/guzzle6-adapter": "^0.4.1"
},
"suggest": {
"knplabs/gaufrette": "Needed for optional Gaufrette cache"
},
"autoload": {
"psr-4": { "Github\\": "lib/Github/" }
"psr-4": { "Github\\": "src/Github/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.5.x-dev"
"dev-master": "2.0.x-dev"
}
}
}
59 changes: 59 additions & 0 deletions spec/Github/HttpClient/HttplugClientSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace spec\Github\HttpClient;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Http\Client\HttpClient;
use Github\Factory\RequestFactory;

class HttplugClientSpec extends ObjectBehavior
{
function let(HttpClient $adapter, RequestFactory $factory)
{
$this->beConstructedWith($adapter, $factory);
}

function it_is_a_http_client()
{
$this->shouldBeAnInstanceOf('Github\HttpClient\HttpClientInterface');
}

function it_sends_GET_request(
RequestInterface $request,
ResponseInterface $response,
$adapter,
$factory
) {
$headers = [
'Accept' => 'application/vnd.github.v3+json',
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',
'X-Debug-Token' => '13fe23ab',
];

$factory->createRequest('GET', 'https://api.github.com/endpoint?page=1', $headers)->willReturn($request);
$adapter->sendRequest($request)->willReturn($response);

$this->get('/endpoint', ['page' => 1], ['X-Debug-Token' => '13fe23ab'])->shouldReturn($response);
}

function it_sends_POST_request(
RequestInterface $request,
ResponseInterface $response,
$adapter,
$factory
) {
$headers = [
'Accept' => 'application/vnd.github.v3+json',
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',
'X-Debug-Token' => '13fe23ab',
];

$factory->createRequest('POST', 'https://api.github.com/endpoint', $headers, 'body')->willReturn($request);
$adapter->sendRequest($request)->willReturn($response);

$this->post('/endpoint', 'body', ['X-Debug-Token' => '13fe23ab'])->shouldReturn($response);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions src/Github/Factory/RequestFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Github\Factory;

use Zend\Diactoros\Request;

class RequestFactory
{
public function createRequest($method, $uri, array $headers, $body = 'php://temp')
{
return new Request($uri, $method, $body, $headers);
}
}
131 changes: 131 additions & 0 deletions src/Github/HttpClient/HttplugClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

namespace Github\HttpClient;

use Http\Adapter\HttpAdapter;
use Github\Factory\RequestFactory;
use Http\Client\HttpClient;

final class HttplugClient implements HttpClientInterface
{
/** @var HttpAdapter */
private $adapter;

/** @var RequestFactory */
private $factory;

private $options = array(
'base_url' => 'https://api.github.com/',

'user_agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',

'api_limit' => 5000,
'api_version' => 'v3',

'cache_dir' => null
);

/**
* @param HttpAdapter $adapter
*/
public function __construct(
HttpClient $adapter,
RequestFactory $factory
) {
$this->adapter = $adapter;
$this->factory = $factory;
}

/**
* {@inheritdoc}
*/
public function get($path, array $parameters = array(), array $headers = array())
{
return $this->request(
sprintf(
'%s/%s?%s',
rtrim($this->options['base_url'], '/'),
ltrim($path, '/'),
http_build_query($parameters)
),
null,
'GET',
$headers
);
}

/**
* {@inheritdoc}
*/
public function post($path, $body = null, array $headers = array())
{
return $this->request(
sprintf('%s%s', rtrim($this->options['base_url'], '/'), $path),
$body,
'POST',
$headers
);
}

/**
* {@inheritdoc}
*/
public function patch($path, $body = null, array $headers = array())
{
}

/**
* {@inheritdoc}
*/
public function put($path, $body, array $headers = array())
{
}

/**
* {@inheritdoc}
*/
public function delete($path, $body = null, array $headers = array())
{
}

/**
* {@inheritdoc}
*/
public function request($path, $body, $httpMethod = 'GET', array $headers = array())
{
$headers = array_merge([
'Accept' => sprintf('application/vnd.github.%s+json', $this->options['api_version']),
'User-Agent' => sprintf('%s', $this->options['user_agent']),
], $headers);

if (null !== $body) {
$request = $this->factory->createRequest($httpMethod, $path, $headers, $body);
} else {
$request = $this->factory->createRequest($httpMethod, $path, $headers);
}

// TODO (2016-01-22 14:19 by Gildas): try catch
return $this->adapter->sendRequest($request);
}

/**
* {@inheritdoc}
*/
public function setOption($name, $value)
{
}

/**
* {@inheritdoc}
*/
public function setHeaders(array $headers)
{
}

/**
* {@inheritdoc}
*/
public function authenticate($tokenOrLogin, $password, $authMethod)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

namespace Github\HttpClient\Message;

use Guzzle\Http\Message\Response;
use Github\Exception\ApiLimitExceedException;
use Psr\Http\Message\ResponseInterface;

class ResponseMediator
{
public static function getContent(Response $response)
public static function getContent(ResponseInterface $response)
{
$body = $response->getBody(true);
$body = $response->getBody();
$content = json_decode($body, true);

if (JSON_ERROR_NONE !== json_last_error()) {
Expand All @@ -19,7 +19,7 @@ public static function getContent(Response $response)
return $content;
}

public static function getPagination(Response $response)
public static function getPagination(ResponseInterface $response)
{
$header = (string) $response->getHeader('Link');

Expand All @@ -39,14 +39,14 @@ public static function getPagination(Response $response)
return $pagination;
}

public static function getApiLimit(Response $response)
public static function getApiLimit(ResponseInterface $response)
{
$remainingCalls = (string) $response->getHeader('X-RateLimit-Remaining');

if (null !== $remainingCalls && 1 > $remainingCalls) {
throw new ApiLimitExceedException($remainingCalls);
}

return $remainingCalls;
}
}