Chris
6 years ago
352 changed files with 31863 additions and 2538 deletions
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
class Application extends Model |
||||
|
{ |
||||
|
// |
||||
|
} |
File diff suppressed because it is too large
@ -0,0 +1,91 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
return [ |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Default Connection Name |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Here you may specify which of the connections below you wish to use as |
||||
|
| your default connection for all work. Of course, you may use many |
||||
|
| connections at once using the manager class. |
||||
|
| |
||||
|
*/ |
||||
|
|
||||
|
'default' => 'main', |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| GitHub Connections |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Here are each of the connections setup for your application. Example |
||||
|
| configuration has been included, but you may add as many connections as |
||||
|
| you would like. Note that the 5 supported authentication methods are: |
||||
|
| "application", "jwt", "none", "password", and "token". |
||||
|
| |
||||
|
*/ |
||||
|
|
||||
|
'connections' => [ |
||||
|
|
||||
|
'main' => [ |
||||
|
'token' => 'your-token', |
||||
|
'method' => 'token', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'app' => [ |
||||
|
'clientId' => 'your-client-id', |
||||
|
'clientSecret' => 'your-client-secret', |
||||
|
'method' => 'application', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'jwt' => [ |
||||
|
'token' => 'your-jwt-token', |
||||
|
'method' => 'jwt', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'other' => [ |
||||
|
'username' => 'your-username', |
||||
|
'password' => 'your-password', |
||||
|
'method' => 'password', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'none' => [ |
||||
|
'method' => 'none', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
], |
||||
|
|
||||
|
]; |
@ -0,0 +1,39 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
|
||||
|
class CreateApplicationsTable extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function up() |
||||
|
{ |
||||
|
Schema::create('applications', function (Blueprint $table) { |
||||
|
$table->increments('id'); |
||||
|
$table->string('name')->unique(); |
||||
|
$table->string('sha'); |
||||
|
$table->string('icon')->nullable(); |
||||
|
$table->string('website')->nullable(); |
||||
|
$table->string('license')->nullable(); |
||||
|
$table->mediumText('description')->nullable(); |
||||
|
$table->boolean('enhanced')->default(false); |
||||
|
|
||||
|
$table->timestamps(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function down() |
||||
|
{ |
||||
|
Schema::dropIfExists('applications'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
/vendor |
||||
|
/composer.lock |
@ -0,0 +1,26 @@ |
|||||
|
language: php |
||||
|
|
||||
|
php: |
||||
|
# - 5.3 # requires old distro, see below |
||||
|
- 5.4 |
||||
|
- 5.5 |
||||
|
- 5.6 |
||||
|
- 7.0 |
||||
|
- 7.1 |
||||
|
- hhvm # ignore errors, see below |
||||
|
|
||||
|
# lock distro so new future defaults will not break the build |
||||
|
dist: trusty |
||||
|
|
||||
|
matrix: |
||||
|
include: |
||||
|
- php: 5.3 |
||||
|
dist: precise |
||||
|
allow_failures: |
||||
|
- php: hhvm |
||||
|
|
||||
|
install: |
||||
|
- composer install --no-interaction |
||||
|
|
||||
|
script: |
||||
|
- vendor/bin/phpunit --coverage-text |
@ -0,0 +1,54 @@ |
|||||
|
# Changelog |
||||
|
|
||||
|
## 1.4.0 (2017-08-18) |
||||
|
|
||||
|
* Feature / Fix: The `fun()` function does not pass filter parameter `null` |
||||
|
to underlying `stream_filter_append()` by default |
||||
|
(#15 by @Nyholm) |
||||
|
|
||||
|
Certain filters (such as `convert.quoted-printable-encode`) do not accept |
||||
|
a filter parameter at all. If no explicit filter parameter is given, we no |
||||
|
longer pass a default `null` value. |
||||
|
|
||||
|
```php |
||||
|
$encode = Filter\fun('convert.quoted-printable-encode'); |
||||
|
assert('t=C3=A4st' === $encode('täst')); |
||||
|
``` |
||||
|
|
||||
|
* Add examples and improve documentation |
||||
|
(#13 and #20 by @clue and #18 by @Nyholm) |
||||
|
|
||||
|
* Improve test suite by adding PHPUnit to require-dev, |
||||
|
fix HHVM build for now again and ignore future HHVM build errors, |
||||
|
lock Travis distro so new future defaults will not break the build |
||||
|
and test on PHP 7.1 |
||||
|
(#12, #14 and #19 by @clue and #16 by @Nyholm) |
||||
|
|
||||
|
## 1.3.0 (2015-11-08) |
||||
|
|
||||
|
* Feature: Support accessing built-in filters as callbacks |
||||
|
(#5 by @clue) |
||||
|
|
||||
|
```php |
||||
|
$fun = Filter\fun('zlib.deflate'); |
||||
|
|
||||
|
$ret = $fun('hello') . $fun('world') . $fun(); |
||||
|
assert('helloworld' === gzinflate($ret)); |
||||
|
``` |
||||
|
|
||||
|
## 1.2.0 (2015-10-23) |
||||
|
|
||||
|
* Feature: Invoke close event when closing filter (flush buffer) |
||||
|
(#9 by @clue) |
||||
|
|
||||
|
## 1.1.0 (2015-10-22) |
||||
|
|
||||
|
* Feature: Abort filter operation when catching an Exception |
||||
|
(#10 by @clue) |
||||
|
|
||||
|
* Feature: Additional safeguards to prevent filter state corruption |
||||
|
(#7 by @clue) |
||||
|
|
||||
|
## 1.0.0 (2015-10-18) |
||||
|
|
||||
|
* First tagged release |
@ -0,0 +1,21 @@ |
|||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Christian Lück |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is furnished |
||||
|
to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,297 @@ |
|||||
|
# clue/stream-filter [![Build Status](https://travis-ci.org/clue/php-stream-filter.svg?branch=master)](https://travis-ci.org/clue/php-stream-filter) |
||||
|
|
||||
|
A simple and modern approach to stream filtering in PHP |
||||
|
|
||||
|
**Table of contents** |
||||
|
|
||||
|
* [Why?](#why) |
||||
|
* [Usage](#usage) |
||||
|
* [append()](#append) |
||||
|
* [prepend()](#prepend) |
||||
|
* [fun()](#fun) |
||||
|
* [remove()](#remove) |
||||
|
* [Install](#install) |
||||
|
* [Tests](#tests) |
||||
|
* [License](#license) |
||||
|
|
||||
|
## Why? |
||||
|
|
||||
|
PHP's stream filtering system is great! |
||||
|
|
||||
|
It offers very powerful stream filtering options and comes with a useful set of built-in filters. |
||||
|
These filters can be used to easily and efficiently perform various transformations on-the-fly, such as: |
||||
|
|
||||
|
* read from a gzip'ed input file, |
||||
|
* transcode from ISO-8859-1 (Latin1) to UTF-8, |
||||
|
* write to a bzip output file |
||||
|
* and much more. |
||||
|
|
||||
|
But let's face it: |
||||
|
Its API is [*difficult to work with*](http://php.net/manual/en/php-user-filter.filter.php) |
||||
|
and its documentation is [*subpar*](http://stackoverflow.com/questions/27103269/what-is-a-bucket-brigade). |
||||
|
This combined means its powerful features are often neglected. |
||||
|
|
||||
|
This project aims to make these features more accessible to a broader audience. |
||||
|
* **Lightweight, SOLID design** - |
||||
|
Provides a thin abstraction that is [*just good enough*](http://en.wikipedia.org/wiki/Principle_of_good_enough) |
||||
|
and does not get in your way. |
||||
|
Custom filters require trivial effort. |
||||
|
* **Good test coverage** - |
||||
|
Comes with an automated tests suite and is regularly tested in the *real world* |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
This lightweight library consists only of a few simple functions. |
||||
|
All functions reside under the `Clue\StreamFilter` namespace. |
||||
|
|
||||
|
The below examples assume you use an import statement similar to this: |
||||
|
|
||||
|
```php |
||||
|
use Clue\StreamFilter as Filter; |
||||
|
|
||||
|
Filter\append(…); |
||||
|
``` |
||||
|
|
||||
|
Alternatively, you can also refer to them with their fully-qualified name: |
||||
|
|
||||
|
```php |
||||
|
\Clue\StreamFilter\append(…); |
||||
|
``` |
||||
|
|
||||
|
### append() |
||||
|
|
||||
|
The `append($stream, $callback, $read_write = STREAM_FILTER_ALL)` function can be used to |
||||
|
append a filter callback to the given stream. |
||||
|
|
||||
|
Each stream can have a list of filters attached. |
||||
|
This function appends a filter to the end of this list. |
||||
|
|
||||
|
This function returns a filter resource which can be passed to [`remove()`](#remove). |
||||
|
If the given filter can not be added, it throws an `Exception`. |
||||
|
|
||||
|
The `$stream` can be any valid stream resource, such as: |
||||
|
|
||||
|
```php |
||||
|
$stream = fopen('demo.txt', 'w+'); |
||||
|
``` |
||||
|
|
||||
|
The `$callback` should be a valid callable function which accepts an individual chunk of data |
||||
|
and should return the updated chunk: |
||||
|
|
||||
|
```php |
||||
|
$filter = Filter\append($stream, function ($chunk) { |
||||
|
// will be called each time you read or write a $chunk to/from the stream |
||||
|
return $chunk; |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
As such, you can also use native PHP functions or any other `callable`: |
||||
|
|
||||
|
```php |
||||
|
Filter\append($stream, 'strtoupper'); |
||||
|
|
||||
|
// will write "HELLO" to the underlying stream |
||||
|
fwrite($stream, 'hello'); |
||||
|
``` |
||||
|
|
||||
|
If the `$callback` accepts invocation without parameters, then this signature |
||||
|
will be invoked once ending (flushing) the filter: |
||||
|
|
||||
|
```php |
||||
|
Filter\append($stream, function ($chunk = null) { |
||||
|
if ($chunk === null) { |
||||
|
// will be called once ending the filter |
||||
|
return 'end'; |
||||
|
} |
||||
|
// will be called each time you read or write a $chunk to/from the stream |
||||
|
return $chunk; |
||||
|
}); |
||||
|
|
||||
|
fclose($stream); |
||||
|
``` |
||||
|
|
||||
|
> Note: Legacy PHP versions (PHP < 5.4) do not support passing additional data |
||||
|
from the end signal handler if the stream is being closed. |
||||
|
|
||||
|
If your callback throws an `Exception`, then the filter process will be aborted. |
||||
|
In order to play nice with PHP's stream handling, the `Exception` will be |
||||
|
transformed to a PHP warning instead: |
||||
|
|
||||
|
```php |
||||
|
Filter\append($stream, function ($chunk) { |
||||
|
throw new \RuntimeException('Unexpected chunk'); |
||||
|
}); |
||||
|
|
||||
|
// raises an E_USER_WARNING with "Error invoking filter: Unexpected chunk" |
||||
|
fwrite($stream, 'hello'); |
||||
|
``` |
||||
|
|
||||
|
The optional `$read_write` parameter can be used to only invoke the `$callback` when either writing to the stream or only when reading from the stream: |
||||
|
|
||||
|
```php |
||||
|
Filter\append($stream, function ($chunk) { |
||||
|
// will be called each time you write to the stream |
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
Filter\append($stream, function ($chunk) { |
||||
|
// will be called each time you read from the stream |
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_READ); |
||||
|
``` |
||||
|
|
||||
|
> Note that once a filter has been added to stream, the stream can no longer be passed to |
||||
|
> [`stream_select()`](http://php.net/manual/en/function.stream-select.php) |
||||
|
> (and family). |
||||
|
> |
||||
|
> > Warning: stream_select(): cannot cast a filtered stream on this system in {file} on line {line} |
||||
|
> |
||||
|
> This is due to limitations of PHP's stream filter support, as it can no longer reliably |
||||
|
> tell when the underlying stream resource is actually ready. |
||||
|
> As an alternative, consider calling `stream_select()` on the unfiltered stream and |
||||
|
> then pass the unfiltered data through the [`fun()`](#fun) function. |
||||
|
|
||||
|
### prepend() |
||||
|
|
||||
|
The `prepend($stream, $callback, $read_write = STREAM_FILTER_ALL)` function can be used to |
||||
|
prepend a filter callback to the given stream. |
||||
|
|
||||
|
Each stream can have a list of filters attached. |
||||
|
This function prepends a filter to the start of this list. |
||||
|
|
||||
|
This function returns a filter resource which can be passed to [`remove()`](#remove). |
||||
|
If the given filter can not be added, it throws an `Exception`. |
||||
|
|
||||
|
```php |
||||
|
$filter = Filter\prepend($stream, function ($chunk) { |
||||
|
// will be called each time you read or write a $chunk to/from the stream |
||||
|
return $chunk; |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
Except for the position in the list of filters, this function behaves exactly |
||||
|
like the [`append()`](#append) function. |
||||
|
For more details about its behavior, see also the [`append()`](#append) function. |
||||
|
|
||||
|
### fun() |
||||
|
|
||||
|
The `fun($filter, $parameters = null)` function can be used to |
||||
|
create a filter function which uses the given built-in `$filter`. |
||||
|
|
||||
|
PHP comes with a useful set of [built-in filters](http://php.net/manual/en/filters.php). |
||||
|
Using `fun()` makes accessing these as easy as passing an input string to filter |
||||
|
and getting the filtered output string. |
||||
|
|
||||
|
```php |
||||
|
$fun = Filter\fun('string.rot13'); |
||||
|
|
||||
|
assert('grfg' === $fun('test')); |
||||
|
assert('test' === $fun($fun('test')); |
||||
|
``` |
||||
|
|
||||
|
Please note that not all filter functions may be available depending on installed |
||||
|
PHP extensions and the PHP version in use. |
||||
|
In particular, [HHVM](http://hhvm.com/) may not offer the same filter functions |
||||
|
or parameters as Zend PHP. |
||||
|
Accessing an unknown filter function will result in a `RuntimeException`: |
||||
|
|
||||
|
```php |
||||
|
Filter\fun('unknown'); // throws RuntimeException |
||||
|
``` |
||||
|
|
||||
|
Some filters may accept or require additional filter parameters – most |
||||
|
filters do not require filter parameters. |
||||
|
If given, the optional `$parameters` argument will be passed to the |
||||
|
underlying filter handler as-is. |
||||
|
In particular, note how *not passing* this parameter at all differs from |
||||
|
explicitly passing a `null` value (which many filters do not accept). |
||||
|
Please refer to the individual filter definition for more details. |
||||
|
For example, the `string.strip_tags` filter can be invoked like this: |
||||
|
|
||||
|
```php |
||||
|
$fun = Filter\fun('string.strip_tags', '<a><b>'); |
||||
|
|
||||
|
$ret = $fun('<b>h<br>i</b>'); |
||||
|
assert('<b>hi</b>' === $ret); |
||||
|
``` |
||||
|
|
||||
|
Under the hood, this function allocates a temporary memory stream, so it's |
||||
|
recommended to clean up the filter function after use. |
||||
|
Also, some filter functions (in particular the |
||||
|
[zlib compression filters](http://php.net/manual/en/filters.compression.php)) |
||||
|
may use internal buffers and may emit a final data chunk on close. |
||||
|
The filter function can be closed by invoking without any arguments: |
||||
|
|
||||
|
```php |
||||
|
$fun = Filter\fun('zlib.deflate'); |
||||
|
|
||||
|
$ret = $fun('hello') . $fun('world') . $fun(); |
||||
|
assert('helloworld' === gzinflate($ret)); |
||||
|
``` |
||||
|
|
||||
|
The filter function must not be used anymore after it has been closed. |
||||
|
Doing so will result in a `RuntimeException`: |
||||
|
|
||||
|
```php |
||||
|
$fun = Filter\fun('string.rot13'); |
||||
|
$fun(); |
||||
|
|
||||
|
$fun('test'); // throws RuntimeException |
||||
|
``` |
||||
|
|
||||
|
> Note: If you're using the zlib compression filters, then you should be wary |
||||
|
about engine inconsistencies between different PHP versions and HHVM. |
||||
|
These inconsistencies exist in the underlying PHP engines and there's little we |
||||
|
can do about this in this library. |
||||
|
[Our test suite](tests/) contains several test cases that exhibit these issues. |
||||
|
If you feel some test case is missing or outdated, we're happy to accept PRs! :) |
||||
|
|
||||
|
### remove() |
||||
|
|
||||
|
The `remove($filter)` function can be used to |
||||
|
remove a filter previously added via [`append()`](#append) or [`prepend()`](#prepend). |
||||
|
|
||||
|
```php |
||||
|
$filter = Filter\append($stream, function () { |
||||
|
// … |
||||
|
}); |
||||
|
Filter\remove($filter); |
||||
|
``` |
||||
|
|
||||
|
## Install |
||||
|
|
||||
|
The recommended way to install this library is [through Composer](https://getcomposer.org). |
||||
|
[New to Composer?](https://getcomposer.org/doc/00-intro.md) |
||||
|
|
||||
|
This will install the latest supported version: |
||||
|
|
||||
|
```bash |
||||
|
$ composer require clue/stream-filter:^1.4 |
||||
|
``` |
||||
|
|
||||
|
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. |
||||
|
|
||||
|
This project aims to run on any platform and thus does not require any PHP |
||||
|
extensions and supports running on legacy PHP 5.3 through current PHP 7+ and |
||||
|
HHVM. |
||||
|
It's *highly recommended to use PHP 7+* for this project. |
||||
|
Older PHP versions may suffer from a number of inconsistencies documented above. |
||||
|
|
||||
|
## Tests |
||||
|
|
||||
|
To run the test suite, you first need to clone this repo and then install all |
||||
|
dependencies [through Composer](http://getcomposer.org): |
||||
|
|
||||
|
```bash |
||||
|
$ composer install |
||||
|
``` |
||||
|
|
||||
|
To run the test suite, go to the project root and run: |
||||
|
|
||||
|
```bash |
||||
|
$ php vendor/bin/phpunit |
||||
|
``` |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
MIT |
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"name": "clue/stream-filter", |
||||
|
"description": "A simple and modern approach to stream filtering in PHP", |
||||
|
"keywords": ["stream", "callback", "filter", "php_user_filter", "stream_filter_append", "stream_filter_register", "bucket brigade"], |
||||
|
"homepage": "https://github.com/clue/php-stream-filter", |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "Christian Lück", |
||||
|
"email": "christian@lueck.tv" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": ">=5.3" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"phpunit/phpunit": "^5.0 || ^4.8" |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { "Clue\\StreamFilter\\": "src/" }, |
||||
|
"files": [ "src/functions.php" ] |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// $ echo test | php examples/base64_encode.php | php examples/base64_decode.php |
||||
|
|
||||
|
require __DIR__ . '/../vendor/autoload.php'; |
||||
|
|
||||
|
// decoding requires buffering in chunks of 4 bytes each |
||||
|
$buffer = ''; |
||||
|
Clue\StreamFilter\append(STDIN, function ($chunk = null) use (&$buffer) { |
||||
|
if ($chunk === null) { |
||||
|
if (strlen($buffer) % 4 !== 0) { |
||||
|
throw new \UnexpectedValueException('Invalid length'); |
||||
|
} |
||||
|
$chunk = $buffer; |
||||
|
} else { |
||||
|
$buffer .= $chunk; |
||||
|
$len = strlen($buffer) - (strlen($buffer) % 4); |
||||
|
$chunk = (string)substr($buffer, 0, $len); |
||||
|
$buffer = (string)substr($buffer, $len); |
||||
|
} |
||||
|
|
||||
|
$ret = base64_decode($chunk, true); |
||||
|
if ($ret === false) { |
||||
|
throw new \UnexpectedValueException('Not a valid base64 encoded chunk'); |
||||
|
} |
||||
|
return $ret; |
||||
|
}, STREAM_FILTER_READ); |
||||
|
|
||||
|
fpassthru(STDIN); |
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// $ echo test | php examples/base64_encode.php | base64 --decode |
||||
|
|
||||
|
require __DIR__ . '/../vendor/autoload.php'; |
||||
|
|
||||
|
// encoding requires buffering in chunks of 3 bytes each |
||||
|
$buffer = ''; |
||||
|
Clue\StreamFilter\append(STDIN, function ($chunk = null) use (&$buffer) { |
||||
|
if ($chunk === null) { |
||||
|
return base64_encode($buffer); |
||||
|
} |
||||
|
$buffer .= $chunk; |
||||
|
$len = strlen($buffer) - (strlen($buffer) % 3); |
||||
|
$chunk = substr($buffer, 0, $len); |
||||
|
$buffer = substr($buffer, $len); |
||||
|
|
||||
|
return base64_encode($chunk); |
||||
|
}, STREAM_FILTER_READ); |
||||
|
|
||||
|
fpassthru(STDIN); |
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// $ echo test | php examples/uppercase.php |
||||
|
|
||||
|
require __DIR__ . '/../vendor/autoload.php'; |
||||
|
|
||||
|
Clue\StreamFilter\append(STDIN, 'strtoupper'); |
||||
|
|
||||
|
fpassthru(STDIN); |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
|
||||
|
<phpunit bootstrap="vendor/autoload.php" |
||||
|
colors="true" |
||||
|
convertErrorsToExceptions="true" |
||||
|
convertNoticesToExceptions="true" |
||||
|
convertWarningsToExceptions="true" |
||||
|
> |
||||
|
<testsuites> |
||||
|
<testsuite> |
||||
|
<directory>./tests/</directory> |
||||
|
</testsuite> |
||||
|
</testsuites> |
||||
|
<filter> |
||||
|
<whitelist> |
||||
|
<directory>./src/</directory> |
||||
|
</whitelist> |
||||
|
</filter> |
||||
|
</phpunit> |
@ -0,0 +1,120 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Clue\StreamFilter; |
||||
|
|
||||
|
use php_user_filter; |
||||
|
use InvalidArgumentException; |
||||
|
use ReflectionFunction; |
||||
|
use Exception; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @internal |
||||
|
* @see append() |
||||
|
* @see prepend() |
||||
|
*/ |
||||
|
class CallbackFilter extends php_user_filter |
||||
|
{ |
||||
|
private $callback; |
||||
|
private $closed = true; |
||||
|
private $supportsClose = false; |
||||
|
|
||||
|
public function onCreate() |
||||
|
{ |
||||
|
$this->closed = false; |
||||
|
|
||||
|
if (!is_callable($this->params)) { |
||||
|
throw new InvalidArgumentException('No valid callback parameter given to stream_filter_(append|prepend)'); |
||||
|
} |
||||
|
$this->callback = $this->params; |
||||
|
|
||||
|
// callback supports end event if it accepts invocation without arguments |
||||
|
$ref = new ReflectionFunction($this->callback); |
||||
|
$this->supportsClose = ($ref->getNumberOfRequiredParameters() === 0); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public function onClose() |
||||
|
{ |
||||
|
$this->closed = true; |
||||
|
|
||||
|
// callback supports closing and is not already closed |
||||
|
if ($this->supportsClose) { |
||||
|
$this->supportsClose = false; |
||||
|
// invoke without argument to signal end and discard resulting buffer |
||||
|
try { |
||||
|
call_user_func($this->callback); |
||||
|
} catch (Exception $ignored) { |
||||
|
// this might be called during engine shutdown, so it's not safe |
||||
|
// to raise any errors or exceptions here |
||||
|
// trigger_error('Error closing filter: ' . $ignored->getMessage(), E_USER_WARNING); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$this->callback = null; |
||||
|
} |
||||
|
|
||||
|
public function filter($in, $out, &$consumed, $closing) |
||||
|
{ |
||||
|
// concatenate whole buffer from input brigade |
||||
|
$data = ''; |
||||
|
while ($bucket = stream_bucket_make_writeable($in)) { |
||||
|
$consumed += $bucket->datalen; |
||||
|
$data .= $bucket->data; |
||||
|
} |
||||
|
|
||||
|
// skip processing callback that already ended |
||||
|
if ($this->closed) { |
||||
|
return PSFS_FEED_ME; |
||||
|
} |
||||
|
|
||||
|
// only invoke filter function if buffer is not empty |
||||
|
// this may skip flushing a closing filter |
||||
|
if ($data !== '') { |
||||
|
try { |
||||
|
$data = call_user_func($this->callback, $data); |
||||
|
} catch (Exception $e) { |
||||
|
// exception should mark filter as closed |
||||
|
$this->onClose(); |
||||
|
trigger_error('Error invoking filter: ' . $e->getMessage(), E_USER_WARNING); |
||||
|
|
||||
|
return PSFS_ERR_FATAL; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// mark filter as closed after processing closing chunk |
||||
|
if ($closing) { |
||||
|
$this->closed = true; |
||||
|
|
||||
|
// callback supports closing and is not already closed |
||||
|
if ($this->supportsClose) { |
||||
|
$this->supportsClose = false; |
||||
|
|
||||
|
// invoke without argument to signal end and append resulting buffer |
||||
|
try { |
||||
|
$data .= call_user_func($this->callback); |
||||
|
} catch (Exception $e) { |
||||
|
trigger_error('Error ending filter: ' . $e->getMessage(), E_USER_WARNING); |
||||
|
|
||||
|
return PSFS_ERR_FATAL; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($data !== '') { |
||||
|
// create a new bucket for writing the resulting buffer to the output brigade |
||||
|
// reusing an existing bucket turned out to be bugged in some environments (ancient PHP versions and HHVM) |
||||
|
$bucket = @stream_bucket_new($this->stream, $data); |
||||
|
|
||||
|
// legacy PHP versions (PHP < 5.4) do not support passing data from the event signal handler |
||||
|
// because closing the stream invalidates the stream and its stream bucket brigade before |
||||
|
// invoking the filter close handler. |
||||
|
if ($bucket !== false) { |
||||
|
stream_bucket_append($out, $bucket); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return PSFS_PASS_ON; |
||||
|
} |
||||
|
} |
@ -0,0 +1,146 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Clue\StreamFilter; |
||||
|
|
||||
|
use RuntimeException; |
||||
|
|
||||
|
/** |
||||
|
* append a callback filter to the given stream |
||||
|
* |
||||
|
* @param resource $stream |
||||
|
* @param callable $callback |
||||
|
* @param int $read_write |
||||
|
* @return resource filter resource which can be used for `remove()` |
||||
|
* @throws Exception on error |
||||
|
* @uses stream_filter_append() |
||||
|
*/ |
||||
|
function append($stream, $callback, $read_write = STREAM_FILTER_ALL) |
||||
|
{ |
||||
|
$ret = @stream_filter_append($stream, register(), $read_write, $callback); |
||||
|
|
||||
|
if ($ret === false) { |
||||
|
$error = error_get_last() + array('message' => ''); |
||||
|
throw new RuntimeException('Unable to append filter: ' . $error['message']); |
||||
|
} |
||||
|
|
||||
|
return $ret; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* prepend a callback filter to the given stream |
||||
|
* |
||||
|
* @param resource $stream |
||||
|
* @param callable $callback |
||||
|
* @param int $read_write |
||||
|
* @return resource filter resource which can be used for `remove()` |
||||
|
* @throws Exception on error |
||||
|
* @uses stream_filter_prepend() |
||||
|
*/ |
||||
|
function prepend($stream, $callback, $read_write = STREAM_FILTER_ALL) |
||||
|
{ |
||||
|
$ret = @stream_filter_prepend($stream, register(), $read_write, $callback); |
||||
|
|
||||
|
if ($ret === false) { |
||||
|
$error = error_get_last() + array('message' => ''); |
||||
|
throw new RuntimeException('Unable to prepend filter: ' . $error['message']); |
||||
|
} |
||||
|
|
||||
|
return $ret; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Creates filter fun (function) which uses the given built-in $filter |
||||
|
* |
||||
|
* Some filters may accept or require additional filter parameters – most |
||||
|
* filters do not require filter parameters. |
||||
|
* If given, the optional `$parameters` argument will be passed to the |
||||
|
* underlying filter handler as-is. |
||||
|
* In particular, note how *not passing* this parameter at all differs from |
||||
|
* explicitly passing a `null` value (which many filters do not accept). |
||||
|
* Please refer to the individual filter definition for more details. |
||||
|
* |
||||
|
* @param string $filter built-in filter name. See stream_get_filters() or http://php.net/manual/en/filters.php |
||||
|
* @param mixed $parameters (optional) parameters to pass to the built-in filter as-is |
||||
|
* @return callable a filter callback which can be append()'ed or prepend()'ed |
||||
|
* @throws RuntimeException on error |
||||
|
* @link http://php.net/manual/en/filters.php |
||||
|
* @see stream_get_filters() |
||||
|
* @see append() |
||||
|
*/ |
||||
|
function fun($filter, $parameters = null) |
||||
|
{ |
||||
|
$fp = fopen('php://memory', 'w'); |
||||
|
if (func_num_args() === 1) { |
||||
|
$filter = @stream_filter_append($fp, $filter, STREAM_FILTER_WRITE); |
||||
|
} else { |
||||
|
$filter = @stream_filter_append($fp, $filter, STREAM_FILTER_WRITE, $parameters); |
||||
|
} |
||||
|
|
||||
|
if ($filter === false) { |
||||
|
fclose($fp); |
||||
|
$error = error_get_last() + array('message' => ''); |
||||
|
throw new RuntimeException('Unable to access built-in filter: ' . $error['message']); |
||||
|
} |
||||
|
|
||||
|
// append filter function which buffers internally |
||||
|
$buffer = ''; |
||||
|
append($fp, function ($chunk) use (&$buffer) { |
||||
|
$buffer .= $chunk; |
||||
|
|
||||
|
// always return empty string in order to skip actually writing to stream resource |
||||
|
return ''; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
$closed = false; |
||||
|
|
||||
|
return function ($chunk = null) use ($fp, $filter, &$buffer, &$closed) { |
||||
|
if ($closed) { |
||||
|
throw new \RuntimeException('Unable to perform operation on closed stream'); |
||||
|
} |
||||
|
if ($chunk === null) { |
||||
|
$closed = true; |
||||
|
$buffer = ''; |
||||
|
fclose($fp); |
||||
|
return $buffer; |
||||
|
} |
||||
|
// initialize buffer and invoke filters by attempting to write to stream |
||||
|
$buffer = ''; |
||||
|
fwrite($fp, $chunk); |
||||
|
|
||||
|
// buffer now contains everything the filter function returned |
||||
|
return $buffer; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* remove a callback filter from the given stream |
||||
|
* |
||||
|
* @param resource $filter |
||||
|
* @return boolean true on success or false on error |
||||
|
* @throws Exception on error |
||||
|
* @uses stream_filter_remove() |
||||
|
*/ |
||||
|
function remove($filter) |
||||
|
{ |
||||
|
if (@stream_filter_remove($filter) === false) { |
||||
|
throw new RuntimeException('Unable to remove given filter'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* registers the callback filter and returns the resulting filter name |
||||
|
* |
||||
|
* There should be little reason to call this function manually. |
||||
|
* |
||||
|
* @return string filter name |
||||
|
* @uses CallbackFilter |
||||
|
*/ |
||||
|
function register() |
||||
|
{ |
||||
|
static $registered = null; |
||||
|
if ($registered === null) { |
||||
|
$registered = 'stream-callback'; |
||||
|
stream_filter_register($registered, __NAMESPACE__ . '\CallbackFilter'); |
||||
|
} |
||||
|
return $registered; |
||||
|
} |
@ -0,0 +1,386 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Clue\StreamFilter; |
||||
|
|
||||
|
class FilterTest extends PHPUnit_Framework_TestCase |
||||
|
{ |
||||
|
public function testAppendSimpleCallback() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
return strtoupper($chunk); |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
fwrite($stream, 'world'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('HELLOWORLD', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendNativePhpFunction() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, 'strtoupper'); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
fwrite($stream, 'world'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('HELLOWORLD', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendChangingChunkSize() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
return str_replace(array('a','e','i','o','u'), '', $chunk); |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
fwrite($stream, 'world'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('hllwrld', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendReturningEmptyStringWillNotPassThrough() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
return ''; |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
fwrite($stream, 'world'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendEndEventCanBeBufferedOnClose() |
||||
|
{ |
||||
|
if (PHP_VERSION < 5.4) $this->markTestSkipped('Not supported on legacy PHP'); |
||||
|
|
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk = null) { |
||||
|
if ($chunk === null) { |
||||
|
// this signals the end event |
||||
|
return '!'; |
||||
|
} |
||||
|
return $chunk . ' '; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
$buffered = ''; |
||||
|
StreamFilter\append($stream, function ($chunk) use (&$buffered) { |
||||
|
$buffered .= $chunk; |
||||
|
return ''; |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
fwrite($stream, 'world'); |
||||
|
|
||||
|
fclose($stream); |
||||
|
|
||||
|
$this->assertEquals('hello world !', $buffered); |
||||
|
} |
||||
|
|
||||
|
public function testAppendEndEventWillBeCalledOnRemove() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
$ended = false; |
||||
|
$filter = StreamFilter\append($stream, function ($chunk = null) use (&$ended) { |
||||
|
if ($chunk === null) { |
||||
|
$ended = true; |
||||
|
} |
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
$this->assertEquals(0, $ended); |
||||
|
StreamFilter\remove($filter); |
||||
|
$this->assertEquals(1, $ended); |
||||
|
} |
||||
|
|
||||
|
public function testAppendEndEventWillBeCalledOnClose() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
$ended = false; |
||||
|
StreamFilter\append($stream, function ($chunk = null) use (&$ended) { |
||||
|
if ($chunk === null) { |
||||
|
$ended = true; |
||||
|
} |
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
$this->assertEquals(0, $ended); |
||||
|
fclose($stream); |
||||
|
$this->assertEquals(1, $ended); |
||||
|
} |
||||
|
|
||||
|
public function testAppendWriteOnly() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
$invoked = 0; |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) use (&$invoked) { |
||||
|
++$invoked; |
||||
|
|
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
fwrite($stream, 'a'); |
||||
|
fwrite($stream, 'b'); |
||||
|
fwrite($stream, 'c'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals(3, $invoked); |
||||
|
$this->assertEquals('abc', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendReadOnly() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
$invoked = 0; |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) use (&$invoked) { |
||||
|
++$invoked; |
||||
|
|
||||
|
return $chunk; |
||||
|
}, STREAM_FILTER_READ); |
||||
|
|
||||
|
fwrite($stream, 'a'); |
||||
|
fwrite($stream, 'b'); |
||||
|
fwrite($stream, 'c'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals(0, $invoked); |
||||
|
$this->assertEquals('abc', stream_get_contents($stream)); |
||||
|
$this->assertEquals(1, $invoked); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testOrderCallingAppendAfterPrepend() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
return '[' . $chunk . ']'; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
StreamFilter\prepend($stream, function ($chunk) { |
||||
|
return '(' . $chunk . ')'; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('[(hello)]', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testRemoveFilter() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
$first = StreamFilter\append($stream, function ($chunk) { |
||||
|
return $chunk . '?'; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
return $chunk . '!'; |
||||
|
}, STREAM_FILTER_WRITE); |
||||
|
|
||||
|
StreamFilter\remove($first); |
||||
|
|
||||
|
fwrite($stream, 'hello'); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('hello!', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendFunDechunk() |
||||
|
{ |
||||
|
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (dechunk filter does not exist)'); |
||||
|
|
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, StreamFilter\fun('dechunk'), STREAM_FILTER_WRITE); |
||||
|
|
||||
|
fwrite($stream, "2\r\nhe\r\n"); |
||||
|
fwrite($stream, "3\r\nllo\r\n"); |
||||
|
fwrite($stream, "0\r\n\r\n"); |
||||
|
rewind($stream); |
||||
|
|
||||
|
$this->assertEquals('hello', stream_get_contents($stream)); |
||||
|
|
||||
|
fclose($stream); |
||||
|
} |
||||
|
|
||||
|
public function testAppendThrows() |
||||
|
{ |
||||
|
$this->createErrorHandler($errors); |
||||
|
|
||||
|
$stream = $this->createStream(); |
||||
|
$this->createErrorHandler($errors); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk) { |
||||
|
throw new \DomainException($chunk); |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'test'); |
||||
|
|
||||
|
$this->removeErrorHandler(); |
||||
|
$this->assertCount(1, $errors); |
||||
|
$this->assertContains('test', $errors[0]); |
||||
|
} |
||||
|
|
||||
|
public function testAppendThrowsDuringEnd() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
$this->createErrorHandler($errors); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk = null) { |
||||
|
if ($chunk === null) { |
||||
|
throw new \DomainException('end'); |
||||
|
} |
||||
|
return $chunk; |
||||
|
}); |
||||
|
|
||||
|
fclose($stream); |
||||
|
|
||||
|
$this->removeErrorHandler(); |
||||
|
|
||||
|
// We can only assert we're not seeing an exception here… |
||||
|
// * php 5.3-5.6 sees one error here |
||||
|
// * php 7 does not see any error here |
||||
|
// * hhvm sees the same error twice |
||||
|
// |
||||
|
// If you're curious: |
||||
|
// |
||||
|
// var_dump($errors); |
||||
|
// $this->assertCount(1, $errors); |
||||
|
// $this->assertContains('end', $errors[0]); |
||||
|
} |
||||
|
|
||||
|
public function testAppendThrowsShouldTriggerEnd() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
$this->createErrorHandler($errors); |
||||
|
|
||||
|
$ended = false; |
||||
|
StreamFilter\append($stream, function ($chunk = null) use (&$ended) { |
||||
|
if ($chunk === null) { |
||||
|
$ended = true; |
||||
|
return ''; |
||||
|
} |
||||
|
throw new \DomainException($chunk); |
||||
|
}); |
||||
|
|
||||
|
$this->assertEquals(false, $ended); |
||||
|
fwrite($stream, 'test'); |
||||
|
$this->assertEquals(true, $ended); |
||||
|
|
||||
|
$this->removeErrorHandler(); |
||||
|
$this->assertCount(1, $errors); |
||||
|
$this->assertContains('test', $errors[0]); |
||||
|
} |
||||
|
|
||||
|
public function testAppendThrowsShouldTriggerEndButIgnoreExceptionDuringEnd() |
||||
|
{ |
||||
|
//$this->markTestIncomplete(); |
||||
|
$stream = $this->createStream(); |
||||
|
$this->createErrorHandler($errors); |
||||
|
|
||||
|
StreamFilter\append($stream, function ($chunk = null) { |
||||
|
if ($chunk === null) { |
||||
|
$chunk = 'end'; |
||||
|
//return ''; |
||||
|
} |
||||
|
throw new \DomainException($chunk); |
||||
|
}); |
||||
|
|
||||
|
fwrite($stream, 'test'); |
||||
|
|
||||
|
$this->removeErrorHandler(); |
||||
|
$this->assertCount(1, $errors); |
||||
|
$this->assertContains('test', $errors[0]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException RuntimeException |
||||
|
*/ |
||||
|
public function testAppendInvalidStreamIsRuntimeError() |
||||
|
{ |
||||
|
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid stream)'); |
||||
|
StreamFilter\append(false, function () { }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException RuntimeException |
||||
|
*/ |
||||
|
public function testPrependInvalidStreamIsRuntimeError() |
||||
|
{ |
||||
|
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid stream)'); |
||||
|
StreamFilter\prepend(false, function () { }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException RuntimeException |
||||
|
*/ |
||||
|
public function testRemoveInvalidFilterIsRuntimeError() |
||||
|
{ |
||||
|
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (does not reject invalid filters)'); |
||||
|
StreamFilter\remove(false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException InvalidArgumentException |
||||
|
*/ |
||||
|
public function testInvalidCallbackIsInvalidArgument() |
||||
|
{ |
||||
|
$stream = $this->createStream(); |
||||
|
|
||||
|
StreamFilter\append($stream, 'a-b-c'); |
||||
|
} |
||||
|
|
||||
|
private function createStream() |
||||
|
{ |
||||
|
return fopen('php://memory', 'r+'); |
||||
|
} |
||||
|
|
||||
|
private function createErrorHandler(&$errors) |
||||
|
{ |
||||
|
$errors = array(); |
||||
|
set_error_handler(function ($_, $message) use (&$errors) { |
||||
|
$errors []= $message; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private function removeErrorHandler() |
||||
|
{ |
||||
|
restore_error_handler(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Clue\StreamFilter as Filter; |
||||
|
|
||||
|
class FunTest extends PHPUnit_Framework_TestCase |
||||
|
{ |
||||
|
public function testFunInRot13() |
||||
|
{ |
||||
|
$rot = Filter\fun('string.rot13'); |
||||
|
|
||||
|
$this->assertEquals('grfg', $rot('test')); |
||||
|
$this->assertEquals('test', $rot($rot('test'))); |
||||
|
$this->assertEquals(null, $rot()); |
||||
|
} |
||||
|
|
||||
|
public function testFunInQuotedPrintable() |
||||
|
{ |
||||
|
$encode = Filter\fun('convert.quoted-printable-encode'); |
||||
|
$decode = Filter\fun('convert.quoted-printable-decode'); |
||||
|
|
||||
|
$this->assertEquals('t=C3=A4st', $encode('täst')); |
||||
|
$this->assertEquals('täst', $decode($encode('täst'))); |
||||
|
$this->assertEquals(null, $encode()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException RuntimeException |
||||
|
*/ |
||||
|
public function testFunWriteAfterCloseRot13() |
||||
|
{ |
||||
|
$rot = Filter\fun('string.rot13'); |
||||
|
|
||||
|
$this->assertEquals(null, $rot()); |
||||
|
$rot('test'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @expectedException RuntimeException |
||||
|
*/ |
||||
|
public function testFunInvalid() |
||||
|
{ |
||||
|
Filter\fun('unknown'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,79 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Clue\StreamFilter; |
||||
|
|
||||
|
class BuiltInZlibTest extends PHPUnit_Framework_TestCase |
||||
|
{ |
||||
|
public function testFunZlibDeflateHelloWorld() |
||||
|
{ |
||||
|
$deflate = StreamFilter\fun('zlib.deflate'); |
||||
|
|
||||
|
$data = $deflate('hello') . $deflate(' ') . $deflate('world') . $deflate(); |
||||
|
|
||||
|
$this->assertEquals(gzdeflate('hello world'), $data); |
||||
|
} |
||||
|
|
||||
|
public function testFunZlibDeflateEmpty() |
||||
|
{ |
||||
|
if (PHP_VERSION >= 7) $this->markTestSkipped('Not supported on PHP7 (empty string does not invoke filter)'); |
||||
|
|
||||
|
$deflate = StreamFilter\fun('zlib.deflate'); |
||||
|
|
||||
|
//$data = gzdeflate(''); |
||||
|
$data = $deflate(); |
||||
|
|
||||
|
$this->assertEquals("\x03\x00", $data); |
||||
|
} |
||||
|
|
||||
|
public function testFunZlibDeflateBig() |
||||
|
{ |
||||
|
$deflate = StreamFilter\fun('zlib.deflate'); |
||||
|
|
||||
|
$n = 1000; |
||||
|
$expected = str_repeat('hello', $n); |
||||
|
|
||||
|
$bytes = ''; |
||||
|
for ($i = 0; $i < $n; ++$i) { |
||||
|
$bytes .= $deflate('hello'); |
||||
|
} |
||||
|
$bytes .= $deflate(); |
||||
|
|
||||
|
$this->assertEquals($expected, gzinflate($bytes)); |
||||
|
} |
||||
|
|
||||
|
public function testFunZlibInflateHelloWorld() |
||||
|
{ |
||||
|
$inflate = StreamFilter\fun('zlib.inflate'); |
||||
|
|
||||
|
$data = $inflate(gzdeflate('hello world')) . $inflate(); |
||||
|
|
||||
|
$this->assertEquals('hello world', $data); |
||||
|
} |
||||
|
|
||||
|
public function testFunZlibInflateEmpty() |
||||
|
{ |
||||
|
$inflate = StreamFilter\fun('zlib.inflate'); |
||||
|
|
||||
|
$data = $inflate("\x03\x00") . $inflate(); |
||||
|
|
||||
|
$this->assertEquals('', $data); |
||||
|
} |
||||
|
|
||||
|
public function testFunZlibInflateBig() |
||||
|
{ |
||||
|
if (defined('HHVM_VERSION')) $this->markTestSkipped('Not supported on HHVM (final chunk will not be emitted)'); |
||||
|
|
||||
|
$inflate = StreamFilter\fun('zlib.inflate'); |
||||
|
|
||||
|
$expected = str_repeat('hello', 10); |
||||
|
$bytes = gzdeflate($expected); |
||||
|
|
||||
|
$ret = ''; |
||||
|
foreach (str_split($bytes, 2) as $chunk) { |
||||
|
$ret .= $inflate($chunk); |
||||
|
} |
||||
|
$ret .= $inflate(); |
||||
|
|
||||
|
$this->assertEquals($expected, $ret); |
||||
|
} |
||||
|
} |
@ -1,21 +1,56 @@ |
|||||
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ |
||||
|
Upstream-Name: Composer |
||||
|
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be> |
||||
|
Source: https://github.com/composer/composer |
||||
|
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano |
Files: * |
||||
|
Copyright: 2016, Nils Adermann <naderman@naderman.de> |
||||
|
2016, Jordi Boggiano <j.boggiano@seld.be> |
||||
|
License: Expat |
||||
|
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
Files: src/Composer/Util/TlsHelper.php |
||||
of this software and associated documentation files (the "Software"), to deal |
Copyright: 2016, Nils Adermann <naderman@naderman.de> |
||||
in the Software without restriction, including without limitation the rights |
2016, Jordi Boggiano <j.boggiano@seld.be> |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
2013, Evan Coury <me@evancoury.com> |
||||
copies of the Software, and to permit persons to whom the Software is furnished |
License: Expat and BSD-2-Clause |
||||
to do so, subject to the following conditions: |
|
||||
|
|
||||
The above copyright notice and this permission notice shall be included in all |
License: BSD-2-Clause |
||||
copies or substantial portions of the Software. |
Redistribution and use in source and binary forms, with or without modification, |
||||
|
are permitted provided that the following conditions are met: |
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
. |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* Redistributions of source code must retain the above copyright notice, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
this list of conditions and the following disclaimer. |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
. |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
* Redistributions in binary form must reproduce the above copyright notice, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
this list of conditions and the following disclaimer in the documentation |
||||
THE SOFTWARE. |
and/or other materials provided with the distribution. |
||||
|
. |
||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR |
||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
|
||||
|
License: Expat |
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is furnished |
||||
|
to do so, subject to the following conditions: |
||||
|
. |
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
. |
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
File diff suppressed because it is too large
@ -0,0 +1,22 @@ |
|||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015-2018 PHP HTTP Team <team@php-http.org> |
||||
|
Copyright (c) 2018 Graham Campbell <graham@alt-three.com> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,43 @@ |
|||||
|
{ |
||||
|
"name": "graham-campbell/cache-plugin", |
||||
|
"description": "Provides A Simple HTTP Cache Plugin With Good Defaults", |
||||
|
"keywords": ["http", "cache plugin", "cache-plugin", "Cache", "Cache Plugin", "Cache-Plugin", "Graham Campbell", "GrahamCampbell"], |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "Graham Campbell", |
||||
|
"email": "graham@alt-three.com" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": "^7.0", |
||||
|
"psr/cache": "^1.0", |
||||
|
"php-http/cache-plugin": "^1.5", |
||||
|
"php-http/client-common": "^1.7", |
||||
|
"php-http/message-factory": "^1.0" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"graham-campbell/analyzer": "^2.0", |
||||
|
"phpunit/phpunit": "^6.5|^7.0" |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\CachePlugin\\": "src/" |
||||
|
} |
||||
|
}, |
||||
|
"autoload-dev": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\Tests\\CachePlugin\\": "tests/" |
||||
|
} |
||||
|
}, |
||||
|
"config": { |
||||
|
"preferred-install": "dist" |
||||
|
}, |
||||
|
"extra": { |
||||
|
"branch-alias": { |
||||
|
"dev-master": "1.0-dev" |
||||
|
} |
||||
|
}, |
||||
|
"minimum-stability": "dev", |
||||
|
"prefer-stable": true |
||||
|
} |
@ -0,0 +1,238 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Cache Plugin. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\CachePlugin; |
||||
|
|
||||
|
use Exception; |
||||
|
use Http\Client\Common\Plugin; |
||||
|
use Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator; |
||||
|
use Http\Client\Common\Plugin\Cache\Generator\HeaderCacheKeyGenerator; |
||||
|
use Http\Client\Common\Plugin\Exception\RewindStreamException; |
||||
|
use Http\Message\StreamFactory; |
||||
|
use Psr\Cache\CacheItemInterface; |
||||
|
use Psr\Cache\CacheItemPoolInterface; |
||||
|
use Psr\Http\Message\RequestInterface; |
||||
|
use Psr\Http\Message\ResponseInterface; |
||||
|
|
||||
|
/** |
||||
|
* This is the response cache plugin class. |
||||
|
* |
||||
|
* @author Tobias Nyholm <tobias.nyholm@gmail.com> |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class CachePlugin implements Plugin |
||||
|
{ |
||||
|
/** |
||||
|
* The cache item pool instance. |
||||
|
* |
||||
|
* @var \Psr\Cache\CacheItemPoolInterface |
||||
|
*/ |
||||
|
protected $pool; |
||||
|
|
||||
|
/** |
||||
|
* The steam factory instance. |
||||
|
* |
||||
|
* @var \Http\Message\StreamFactory |
||||
|
*/ |
||||
|
protected $streamFactory; |
||||
|
|
||||
|
/** |
||||
|
* The cache key generator instance. |
||||
|
* |
||||
|
* @var \Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator |
||||
|
*/ |
||||
|
protected $generator; |
||||
|
|
||||
|
/** |
||||
|
* The cache lifetime in seconds. |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $lifetime; |
||||
|
|
||||
|
/** |
||||
|
* Create a new cache plugin. |
||||
|
* |
||||
|
* @param \Psr\Cache\CacheItemPoolInterface $pool |
||||
|
* @param \Http\Message\StreamFactory $streamFactory |
||||
|
* @param \Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator|null $generator |
||||
|
* @param int|null $lifetime |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function __construct(CacheItemPoolInterface $pool, StreamFactory $streamFactory, CacheKeyGenerator $generator = null, int $lifetime = null) |
||||
|
{ |
||||
|
$this->pool = $pool; |
||||
|
$this->streamFactory = $streamFactory; |
||||
|
$this->generator = $generator ?: new HeaderCacheKeyGenerator(['Authorization', 'Cookie', 'Accept', 'Content-type']); |
||||
|
$this->lifetime = $lifetime ?: 3600 * 48; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Handle the request and return the response coming from the next callable. |
||||
|
* |
||||
|
* @param \Psr\Http\Message\RequestInterface $request |
||||
|
* @param callable $next |
||||
|
* @param callable $first |
||||
|
* |
||||
|
* @return \Http\Promise\Promise |
||||
|
*/ |
||||
|
public function handleRequest(RequestInterface $request, callable $next, callable $first) |
||||
|
{ |
||||
|
$method = strtoupper($request->getMethod()); |
||||
|
// If the request not is cachable, move to $next |
||||
|
if (!in_array($method, ['GET', 'HEAD'], true)) { |
||||
|
return $next($request); |
||||
|
} |
||||
|
|
||||
|
$cacheItem = $this->createCacheItem($request); |
||||
|
|
||||
|
if ($cacheItem->isHit() && ($etag = $this->getETag($cacheItem))) { |
||||
|
$request = $request->withHeader('If-None-Match', $etag); |
||||
|
} |
||||
|
|
||||
|
return $next($request)->then(function (ResponseInterface $response) use ($cacheItem) { |
||||
|
if (304 === $response->getStatusCode()) { |
||||
|
if (!$cacheItem->isHit()) { |
||||
|
// We do not have the item in cache. This plugin did not |
||||
|
// add If-None-Match headers. Return the response. |
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
// The cached response we have is still valid |
||||
|
$cacheItem->set($cacheItem->get())->expiresAfter($this->lifetime); |
||||
|
$this->pool->save($cacheItem); |
||||
|
|
||||
|
return $this->createResponseFromCacheItem($cacheItem); |
||||
|
} |
||||
|
|
||||
|
if ($this->isCacheable($response)) { |
||||
|
$bodyStream = $response->getBody(); |
||||
|
$body = $bodyStream->__toString(); |
||||
|
if ($bodyStream->isSeekable()) { |
||||
|
$bodyStream->rewind(); |
||||
|
} else { |
||||
|
$response = $response->withBody($this->streamFactory->createStream($body)); |
||||
|
} |
||||
|
|
||||
|
$cacheItem |
||||
|
->expiresAfter($this->lifetime) |
||||
|
->set([ |
||||
|
'response' => $response, |
||||
|
'body' => $body, |
||||
|
'etag' => $response->getHeader('ETag'), |
||||
|
]); |
||||
|
$this->pool->save($cacheItem); |
||||
|
} |
||||
|
|
||||
|
return $response; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a cache item for a request. |
||||
|
* |
||||
|
* @param \Psr\Http\Message\RequestInterface $request |
||||
|
* |
||||
|
* @return \Psr\Cache\CacheItemInterface |
||||
|
*/ |
||||
|
protected function createCacheItem(RequestInterface $request) |
||||
|
{ |
||||
|
$key = sha1($this->generator->generate($request)); |
||||
|
|
||||
|
return $this->pool->getItem($key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Verify that we can cache this response. |
||||
|
* |
||||
|
* @param \Psr\Http\Message\ResponseInterface $response |
||||
|
* |
||||
|
* @return bool |
||||
|
*/ |
||||
|
protected function isCacheable(ResponseInterface $response) |
||||
|
{ |
||||
|
if (!in_array($response->getStatusCode(), [200, 203, 300, 301, 302, 404, 410])) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return !$this->getCacheControlDirective($response, 'no-cache'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the value of a parameter in the cache control header. |
||||
|
* |
||||
|
* @param \Psr\Http\Message\ResponseInterface $response |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return bool|string |
||||
|
*/ |
||||
|
protected function getCacheControlDirective(ResponseInterface $response, string $name) |
||||
|
{ |
||||
|
foreach ($response->getHeader('Cache-Control') as $header) { |
||||
|
if (preg_match(sprintf('|%s=?([0-9]+)?|i', $name), $header, $matches)) { |
||||
|
// return the value for $name if it exists |
||||
|
if (isset($matches[1])) { |
||||
|
return $matches[1]; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a response from a cache item. |
||||
|
* |
||||
|
* @param \Psr\Cache\CacheItemInterface $cacheItem |
||||
|
* |
||||
|
* @return \Psr\Http\Message\ResponseInterface |
||||
|
*/ |
||||
|
protected function createResponseFromCacheItem(CacheItemInterface $cacheItem) |
||||
|
{ |
||||
|
$data = $cacheItem->get(); |
||||
|
|
||||
|
$response = $data['response']; |
||||
|
$stream = $this->streamFactory->createStream($data['body']); |
||||
|
|
||||
|
try { |
||||
|
$stream->rewind(); |
||||
|
} catch (Exception $e) { |
||||
|
throw new RewindStreamException('Cannot rewind stream.', 0, $e); |
||||
|
} |
||||
|
|
||||
|
$response = $response->withBody($stream); |
||||
|
|
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the ETag from the cached response. |
||||
|
* |
||||
|
* @param \Psr\Cache\CacheItemInterface $cacheItem |
||||
|
* |
||||
|
* @return string|null |
||||
|
*/ |
||||
|
protected function getETag(CacheItemInterface $cacheItem) |
||||
|
{ |
||||
|
$data = $cacheItem->get(); |
||||
|
|
||||
|
foreach ($data['etag'] as $etag) { |
||||
|
if (!empty($etag)) { |
||||
|
return $etag; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014-2018 Graham Campbell <graham@alt-three.com> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,56 @@ |
|||||
|
{ |
||||
|
"name": "graham-campbell/github", |
||||
|
"description": "GitHub Is A GitHub Bridge For Laravel 5", |
||||
|
"keywords": ["laravel", "framework", "github", "php-github-api", "PHP GitHub API", "github bridge", "bridge", "GitHub", "Laravel GitHub", "Laravel-GitHub", "Graham Campbell", "GrahamCampbell"], |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "Graham Campbell", |
||||
|
"email": "graham@alt-three.com" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": "^7.1.3", |
||||
|
"illuminate/contracts": "5.5.*|5.6.*|5.7.*", |
||||
|
"illuminate/support": "5.5.*|5.6.*|5.7.*", |
||||
|
"graham-campbell/cache-plugin": "^1.0", |
||||
|
"graham-campbell/manager": "^4.1", |
||||
|
"knplabs/github-api": "2.7.*|2.8.*|2.9.*|2.10.*" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"graham-campbell/analyzer": "^2.1", |
||||
|
"graham-campbell/testbench": "^5.1", |
||||
|
"madewithlove/illuminate-psr-cache-bridge": "^1.0", |
||||
|
"mockery/mockery": "^1.0", |
||||
|
"phpunit/phpunit": "^6.5|^7.0", |
||||
|
"php-http/guzzle6-adapter": "^1.0" |
||||
|
}, |
||||
|
"suggest": { |
||||
|
"madewithlove/illuminate-psr-cache-bridge": "Allows caching GitHub HTTP requests" |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\GitHub\\": "src/" |
||||
|
} |
||||
|
}, |
||||
|
"autoload-dev": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\Tests\\GitHub\\": "tests/" |
||||
|
} |
||||
|
}, |
||||
|
"config": { |
||||
|
"preferred-install": "dist" |
||||
|
}, |
||||
|
"extra": { |
||||
|
"branch-alias": { |
||||
|
"dev-master": "7.5-dev" |
||||
|
}, |
||||
|
"laravel": { |
||||
|
"providers": [ |
||||
|
"GrahamCampbell\\GitHub\\GitHubServiceProvider" |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"minimum-stability": "dev", |
||||
|
"prefer-stable": true |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
return [ |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Default Connection Name |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Here you may specify which of the connections below you wish to use as |
||||
|
| your default connection for all work. Of course, you may use many |
||||
|
| connections at once using the manager class. |
||||
|
| |
||||
|
*/ |
||||
|
|
||||
|
'default' => 'main', |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| GitHub Connections |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Here are each of the connections setup for your application. Example |
||||
|
| configuration has been included, but you may add as many connections as |
||||
|
| you would like. Note that the 5 supported authentication methods are: |
||||
|
| "application", "jwt", "none", "password", and "token". |
||||
|
| |
||||
|
*/ |
||||
|
|
||||
|
'connections' => [ |
||||
|
|
||||
|
'main' => [ |
||||
|
'token' => 'your-token', |
||||
|
'method' => 'token', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'app' => [ |
||||
|
'clientId' => 'your-client-id', |
||||
|
'clientSecret' => 'your-client-secret', |
||||
|
'method' => 'application', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'jwt' => [ |
||||
|
'token' => 'your-jwt-token', |
||||
|
'method' => 'jwt', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'other' => [ |
||||
|
'username' => 'your-username', |
||||
|
'password' => 'your-password', |
||||
|
'method' => 'password', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
'none' => [ |
||||
|
'method' => 'none', |
||||
|
// 'backoff' => false, |
||||
|
// 'cache' => false, |
||||
|
// 'version' => 'v3', |
||||
|
// 'enterprise' => false, |
||||
|
], |
||||
|
|
||||
|
], |
||||
|
|
||||
|
]; |
@ -0,0 +1,45 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use Github\Client; |
||||
|
|
||||
|
/** |
||||
|
* This is the abstract authenticator class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
abstract class AbstractAuthenticator |
||||
|
{ |
||||
|
/** |
||||
|
* The client to perform the authentication on. |
||||
|
* |
||||
|
* @var \Github\Client|null |
||||
|
*/ |
||||
|
protected $client; |
||||
|
|
||||
|
/** |
||||
|
* Set the client to perform the authentication on. |
||||
|
* |
||||
|
* @param \Github\Client $client |
||||
|
* |
||||
|
* @return \GrahamCampbell\GitHub\Authenticators\AuthenticatorInterface |
||||
|
*/ |
||||
|
public function with(Client $client) |
||||
|
{ |
||||
|
$this->client = $client; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use GitHub\Client; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the application authenticator class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class ApplicationAuthenticator extends AbstractAuthenticator implements AuthenticatorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Authenticate the client, and return it. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function authenticate(array $config) |
||||
|
{ |
||||
|
if (!$this->client) { |
||||
|
throw new InvalidArgumentException('The client instance was not given to the application authenticator.'); |
||||
|
} |
||||
|
|
||||
|
if (!array_key_exists('clientId', $config) || !array_key_exists('clientSecret', $config)) { |
||||
|
throw new InvalidArgumentException('The application authenticator requires a client id and secret.'); |
||||
|
} |
||||
|
|
||||
|
$this->client->authenticate($config['clientId'], $config['clientSecret'], Client::AUTH_URL_CLIENT_ID); |
||||
|
|
||||
|
return $this->client; |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the authenticator factory class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class AuthenticatorFactory |
||||
|
{ |
||||
|
/** |
||||
|
* Make a new authenticator instance. |
||||
|
* |
||||
|
* @param string $method |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \GrahamCampbell\GitHub\Authenticators\AuthenticatorInterface |
||||
|
*/ |
||||
|
public function make(string $method) |
||||
|
{ |
||||
|
switch ($method) { |
||||
|
case 'application': |
||||
|
return new ApplicationAuthenticator(); // AUTH_URL_CLIENT_ID |
||||
|
case 'jwt': |
||||
|
return new JwtAuthenticator(); // AUTH_JWT |
||||
|
case 'password': |
||||
|
return new PasswordAuthenticator(); // AUTH_HTTP_PASSWORD |
||||
|
case 'token': |
||||
|
return new TokenAuthenticator(); // AUTH_HTTP_TOKEN |
||||
|
} |
||||
|
|
||||
|
throw new InvalidArgumentException("Unsupported authentication method [$method]."); |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use Github\Client; |
||||
|
|
||||
|
/** |
||||
|
* This is the authenticator interface. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
interface AuthenticatorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Set the client to perform the authentication on. |
||||
|
* |
||||
|
* @param \Github\Client $client |
||||
|
* |
||||
|
* @return \GrahamCampbell\GitHub\Authenticators\AuthenticatorInterface |
||||
|
*/ |
||||
|
public function with(Client $client); |
||||
|
|
||||
|
/** |
||||
|
* Authenticate the client, and return it. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function authenticate(array $config); |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use GitHub\Client; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the jwt authenticator class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
* @author Lucas Michot <lucas@semalead.com> |
||||
|
*/ |
||||
|
class JwtAuthenticator extends AbstractAuthenticator implements AuthenticatorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Authenticate the client, and return it. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function authenticate(array $config) |
||||
|
{ |
||||
|
if (!$this->client) { |
||||
|
throw new InvalidArgumentException('The client instance was not given to the jwt authenticator.'); |
||||
|
} |
||||
|
|
||||
|
if (!array_key_exists('token', $config)) { |
||||
|
throw new InvalidArgumentException('The jwt authenticator requires a token.'); |
||||
|
} |
||||
|
|
||||
|
$this->client->authenticate($config['token'], Client::AUTH_JWT); |
||||
|
|
||||
|
return $this->client; |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use GitHub\Client; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the password authenticator class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class PasswordAuthenticator extends AbstractAuthenticator implements AuthenticatorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Authenticate the client, and return it. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function authenticate(array $config) |
||||
|
{ |
||||
|
if (!$this->client) { |
||||
|
throw new InvalidArgumentException('The client instance was not given to the password authenticator.'); |
||||
|
} |
||||
|
|
||||
|
if (!array_key_exists('username', $config) || !array_key_exists('password', $config)) { |
||||
|
throw new InvalidArgumentException('The password authenticator requires a username and password.'); |
||||
|
} |
||||
|
|
||||
|
$this->client->authenticate($config['username'], $config['password'], Client::AUTH_HTTP_PASSWORD); |
||||
|
|
||||
|
return $this->client; |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Authenticators; |
||||
|
|
||||
|
use GitHub\Client; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the token authenticator class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class TokenAuthenticator extends AbstractAuthenticator implements AuthenticatorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Authenticate the client, and return it. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function authenticate(array $config) |
||||
|
{ |
||||
|
if (!$this->client) { |
||||
|
throw new InvalidArgumentException('The client instance was not given to the token authenticator.'); |
||||
|
} |
||||
|
|
||||
|
if (!array_key_exists('token', $config)) { |
||||
|
throw new InvalidArgumentException('The token authenticator requires a token.'); |
||||
|
} |
||||
|
|
||||
|
$this->client->authenticate($config['token'], Client::AUTH_HTTP_TOKEN); |
||||
|
|
||||
|
return $this->client; |
||||
|
} |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Facades; |
||||
|
|
||||
|
use Illuminate\Support\Facades\Facade; |
||||
|
|
||||
|
/** |
||||
|
* This is the github facade class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class GitHub extends Facade |
||||
|
{ |
||||
|
/** |
||||
|
* Get the registered name of the component. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
protected static function getFacadeAccessor() |
||||
|
{ |
||||
|
return 'github'; |
||||
|
} |
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub; |
||||
|
|
||||
|
use Github\Client; |
||||
|
use GrahamCampbell\GitHub\Authenticators\AuthenticatorFactory; |
||||
|
use GrahamCampbell\GitHub\Http\ClientBuilder; |
||||
|
use Http\Client\Common\Plugin\RetryPlugin; |
||||
|
use Illuminate\Contracts\Cache\Factory; |
||||
|
use InvalidArgumentException; |
||||
|
use Madewithlove\IlluminatePsrCacheBridge\Laravel\CacheItemPool; |
||||
|
|
||||
|
/** |
||||
|
* This is the github factory class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class GitHubFactory |
||||
|
{ |
||||
|
/** |
||||
|
* The authenticator factory instance. |
||||
|
* |
||||
|
* @var \GrahamCampbell\GitHub\Authenticators\AuthenticatorFactory |
||||
|
*/ |
||||
|
protected $auth; |
||||
|
|
||||
|
/** |
||||
|
* The illuminate cache instance. |
||||
|
* |
||||
|
* @var \Illuminate\Contracts\Cache\Factory|null |
||||
|
*/ |
||||
|
protected $cache; |
||||
|
|
||||
|
/** |
||||
|
* Create a new github factory instance. |
||||
|
* |
||||
|
* @param \GrahamCampbell\GitHub\Authenticators\AuthenticatorFactory $auth |
||||
|
* @param \Illuminate\Contracts\Cache\Factory|null $cache |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function __construct(AuthenticatorFactory $auth, Factory $cache = null) |
||||
|
{ |
||||
|
$this->auth = $auth; |
||||
|
$this->cache = $cache; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make a new github client. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
public function make(array $config) |
||||
|
{ |
||||
|
$client = new Client($this->getBuilder($config), array_get($config, 'version'), array_get($config, 'enterprise')); |
||||
|
|
||||
|
if (!array_key_exists('method', $config)) { |
||||
|
throw new InvalidArgumentException('The github factory requires an auth method.'); |
||||
|
} |
||||
|
|
||||
|
if ($config['method'] === 'none') { |
||||
|
return $client; |
||||
|
} |
||||
|
|
||||
|
return $this->auth->make($config['method'])->with($client)->authenticate($config); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the http client builder. |
||||
|
* |
||||
|
* @param string[] $config |
||||
|
* |
||||
|
* @return \GrahamCampbell\GitHub\Http\ClientBuilder |
||||
|
*/ |
||||
|
protected function getBuilder(array $config) |
||||
|
{ |
||||
|
$builder = new ClientBuilder(); |
||||
|
|
||||
|
if ($backoff = array_get($config, 'backoff')) { |
||||
|
$builder->addPlugin(new RetryPlugin(['retries' => $backoff === true ? 2 : $backoff])); |
||||
|
} |
||||
|
|
||||
|
if ($this->cache && class_exists(CacheItemPool::class) && $cache = array_get($config, 'cache')) { |
||||
|
$builder->addCache(new CacheItemPool($this->cache->store($cache === true ? null : $cache))); |
||||
|
} |
||||
|
|
||||
|
return $builder; |
||||
|
} |
||||
|
} |
@ -0,0 +1,128 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub; |
||||
|
|
||||
|
use GrahamCampbell\Manager\AbstractManager; |
||||
|
use Illuminate\Contracts\Config\Repository; |
||||
|
|
||||
|
/** |
||||
|
* This is the github manager class. |
||||
|
* |
||||
|
* @method \Github\Api\CurrentUser currentUser() |
||||
|
* @method \Github\Api\CurrentUser me() |
||||
|
* @method \Github\Api\Enterprise ent() |
||||
|
* @method \Github\Api\Enterprise enterprise() |
||||
|
* @method \Github\Api\Miscellaneous\CodeOfConduct codeOfConduct() |
||||
|
* @method \Github\Api\Miscellaneous\Emojis emojis() |
||||
|
* @method \Github\Api\GitData git() |
||||
|
* @method \Github\Api\GitData gitData() |
||||
|
* @method \Github\Api\Gists gist() |
||||
|
* @method \Github\Api\Gists gists() |
||||
|
* @method \Github\Api\Miscellaneous\Gitignore gitignore() |
||||
|
* @method \Github\Api\Integrations integration() (deprecated) |
||||
|
* @method \Github\Api\Integrations integrations() (deprecated) |
||||
|
* @method \Github\Api\Apps apps() |
||||
|
* @method \Github\Api\Issue issue() |
||||
|
* @method \Github\Api\Issue issues() |
||||
|
* @method \Github\Api\Markdown markdown() |
||||
|
* @method \Github\Api\Notification notification() |
||||
|
* @method \Github\Api\Notification notifications() |
||||
|
* @method \Github\Api\Organization organization() |
||||
|
* @method \Github\Api\Organization organizations() |
||||
|
* @method \Github\Api\Organization\Projects orgProject() |
||||
|
* @method \Github\Api\Organization\Projects orgProjects() |
||||
|
* @method \Github\Api\Organization\Projects organizationProject() |
||||
|
* @method \Github\Api\Organization\Projects organizationProjects() |
||||
|
* @method \Github\Api\PullRequest pr() |
||||
|
* @method \Github\Api\PullRequest pullRequest() |
||||
|
* @method \Github\Api\PullRequest pullRequests() |
||||
|
* @method \Github\Api\RateLimit rateLimit() |
||||
|
* @method \Github\Api\Repo repo() |
||||
|
* @method \Github\Api\Repo repos() |
||||
|
* @method \Github\Api\Repo repository() |
||||
|
* @method \Github\Api\Repo repositories() |
||||
|
* @method \Github\Api\Search search() |
||||
|
* @method \Github\Api\Organization team() |
||||
|
* @method \Github\Api\Organization teams() |
||||
|
* @method \Github\Api\User user() |
||||
|
* @method \Github\Api\User users() |
||||
|
* @method \Github\Api\Authorizations authorization() |
||||
|
* @method \Github\Api\Authorizations authorizations() |
||||
|
* @method \Github\Api\Meta meta() |
||||
|
* @method \Github\Api\GraphQL graphql() |
||||
|
* @method \Github\Api\ApiInterface api(string $name) |
||||
|
* @method void authenticate(string $tokenOrLogin, string|null $password = null, string|null $authMethod = null) |
||||
|
* @method string getApiVersion() |
||||
|
* @method void addCache(\Psr\Cache\CacheItemPoolInterface $cachePool, array $config = []) |
||||
|
* @method void removeCache() |
||||
|
* @method \Http\Client\Common\HttpMethodsClient getHttpClient() |
||||
|
* @method \Psr\Http\Message\ResponseInterface|null getLastResponse() |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class GitHubManager extends AbstractManager |
||||
|
{ |
||||
|
/** |
||||
|
* The factory instance. |
||||
|
* |
||||
|
* @var \GrahamCampbell\GitHub\GitHubFactory |
||||
|
*/ |
||||
|
protected $factory; |
||||
|
|
||||
|
/** |
||||
|
* Create a new github manager instance. |
||||
|
* |
||||
|
* @param \Illuminate\Contracts\Config\Repository $config |
||||
|
* @param \GrahamCampbell\GitHub\GitHubFactory $factory |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function __construct(Repository $config, GitHubFactory $factory) |
||||
|
{ |
||||
|
parent::__construct($config); |
||||
|
$this->factory = $factory; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create the connection instance. |
||||
|
* |
||||
|
* @param array $config |
||||
|
* |
||||
|
* @return \Github\Client |
||||
|
*/ |
||||
|
protected function createConnection(array $config) |
||||
|
{ |
||||
|
return $this->factory->make($config); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the configuration name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
protected function getConfigName() |
||||
|
{ |
||||
|
return 'github'; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the factory instance. |
||||
|
* |
||||
|
* @return \GrahamCampbell\GitHub\GitHubFactory |
||||
|
*/ |
||||
|
public function getFactory() |
||||
|
{ |
||||
|
return $this->factory; |
||||
|
} |
||||
|
} |
@ -0,0 +1,149 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub; |
||||
|
|
||||
|
use Github\Client; |
||||
|
use GrahamCampbell\GitHub\Authenticators\AuthenticatorFactory; |
||||
|
use Illuminate\Contracts\Container\Container; |
||||
|
use Illuminate\Foundation\Application as LaravelApplication; |
||||
|
use Illuminate\Support\ServiceProvider; |
||||
|
use Laravel\Lumen\Application as LumenApplication; |
||||
|
|
||||
|
/** |
||||
|
* This is the github service provider class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class GitHubServiceProvider extends ServiceProvider |
||||
|
{ |
||||
|
/** |
||||
|
* Boot the service provider. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function boot() |
||||
|
{ |
||||
|
$this->setupConfig(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Setup the config. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function setupConfig() |
||||
|
{ |
||||
|
$source = realpath($raw = __DIR__.'/../config/github.php') ?: $raw; |
||||
|
|
||||
|
if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) { |
||||
|
$this->publishes([$source => config_path('github.php')]); |
||||
|
} elseif ($this->app instanceof LumenApplication) { |
||||
|
$this->app->configure('github'); |
||||
|
} |
||||
|
|
||||
|
$this->mergeConfigFrom($source, 'github'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register the service provider. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function register() |
||||
|
{ |
||||
|
$this->registerAuthFactory(); |
||||
|
$this->registerGitHubFactory(); |
||||
|
$this->registerManager(); |
||||
|
$this->registerBindings(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register the auth factory class. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function registerAuthFactory() |
||||
|
{ |
||||
|
$this->app->singleton('github.authfactory', function () { |
||||
|
return new AuthenticatorFactory(); |
||||
|
}); |
||||
|
|
||||
|
$this->app->alias('github.authfactory', AuthenticatorFactory::class); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register the github factory class. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function registerGitHubFactory() |
||||
|
{ |
||||
|
$this->app->singleton('github.factory', function (Container $app) { |
||||
|
$auth = $app['github.authfactory']; |
||||
|
$cache = $app['cache']; |
||||
|
|
||||
|
return new GitHubFactory($auth, $cache); |
||||
|
}); |
||||
|
|
||||
|
$this->app->alias('github.factory', GitHubFactory::class); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register the manager class. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function registerManager() |
||||
|
{ |
||||
|
$this->app->singleton('github', function (Container $app) { |
||||
|
$config = $app['config']; |
||||
|
$factory = $app['github.factory']; |
||||
|
|
||||
|
return new GitHubManager($config, $factory); |
||||
|
}); |
||||
|
|
||||
|
$this->app->alias('github', GitHubManager::class); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register the bindings. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function registerBindings() |
||||
|
{ |
||||
|
$this->app->bind('github.connection', function (Container $app) { |
||||
|
$manager = $app['github']; |
||||
|
|
||||
|
return $manager->connection(); |
||||
|
}); |
||||
|
|
||||
|
$this->app->alias('github.connection', Client::class); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the services provided by the provider. |
||||
|
* |
||||
|
* @return string[] |
||||
|
*/ |
||||
|
public function provides() |
||||
|
{ |
||||
|
return [ |
||||
|
'github.authfactory', |
||||
|
'github.factory', |
||||
|
'github', |
||||
|
'github.connection', |
||||
|
]; |
||||
|
} |
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel GitHub. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\GitHub\Http; |
||||
|
|
||||
|
use Github\HttpClient\Builder; |
||||
|
use GrahamCampbell\CachePlugin\CachePlugin; |
||||
|
use Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator; |
||||
|
use Psr\Cache\CacheItemPoolInterface; |
||||
|
use ReflectionClass; |
||||
|
|
||||
|
/** |
||||
|
* This is the client builder class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
class ClientBuilder extends Builder |
||||
|
{ |
||||
|
/** |
||||
|
* Add a cache plugin to cache responses locally. |
||||
|
* |
||||
|
* @param \Psr\Cache\CacheItemPoolInterface $cachePool |
||||
|
* @param array $config |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function addCache(CacheItemPoolInterface $cachePool, array $config = []) |
||||
|
{ |
||||
|
$this->setCachePlugin($cachePool, $config['generator'] ?? null, $config['lifetime'] ?? null); |
||||
|
|
||||
|
$this->setPropertyValue('httpClientModified', true); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Add a cache plugin to cache responses locally. |
||||
|
* |
||||
|
* @param \Psr\Cache\CacheItemPoolInterface $cachePool |
||||
|
* @param \Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator|null $generator |
||||
|
* @param int|null $lifetime |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function setCachePlugin(CacheItemPoolInterface $cachePool, CacheKeyGenerator $generator = null, int $lifetime = null) |
||||
|
{ |
||||
|
$stream = $this->getPropertyValue('streamFactory'); |
||||
|
|
||||
|
$this->setPropertyValue('cachePlugin', new CachePlugin($cachePool, $stream, $generator, $lifetime)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the value of the given private property on the builder. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
protected function getPropertyValue(string $name) |
||||
|
{ |
||||
|
return static::getProperty($name)->getValue($this); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set the value of the given private property on the builder. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* @param mixed $value |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
protected function setPropertyValue(string $name, $value) |
||||
|
{ |
||||
|
return static::getProperty($name)->setValue($this, $value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the builder reflection property for the given name. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return \ReflectionProperty |
||||
|
*/ |
||||
|
protected static function getProperty(string $name) |
||||
|
{ |
||||
|
$prop = (new ReflectionClass(Builder::class))->getProperty($name); |
||||
|
|
||||
|
$prop->setAccessible(true); |
||||
|
|
||||
|
return $prop; |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014-2018 Graham Campbell <graham@alt-three.com> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,43 @@ |
|||||
|
{ |
||||
|
"name": "graham-campbell/manager", |
||||
|
"description": "Manager Provides Some Manager Functionality For Laravel 5", |
||||
|
"keywords": ["laravel", "framework", "manager", "connector", "interface", "Manager", "Laravel Manager", "Laravel-Manager", "Graham Campbell", "GrahamCampbell"], |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "Graham Campbell", |
||||
|
"email": "graham@alt-three.com" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": "^7.1.3", |
||||
|
"illuminate/contracts": "5.5.*|5.6.*|5.7.*", |
||||
|
"illuminate/support": "5.5.*|5.6.*|5.7.*" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"graham-campbell/analyzer": "^2.1", |
||||
|
"graham-campbell/testbench-core": "^3.0", |
||||
|
"mockery/mockery": "^1.0", |
||||
|
"phpunit/phpunit": "^6.5|^7.0" |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\Manager\\": "src/" |
||||
|
} |
||||
|
}, |
||||
|
"autoload-dev": { |
||||
|
"psr-4": { |
||||
|
"GrahamCampbell\\Tests\\Manager\\": "tests/" |
||||
|
} |
||||
|
}, |
||||
|
"config": { |
||||
|
"preferred-install": "dist" |
||||
|
}, |
||||
|
"extra": { |
||||
|
"branch-alias": { |
||||
|
"dev-master": "4.1-dev" |
||||
|
} |
||||
|
}, |
||||
|
"minimum-stability": "dev", |
||||
|
"prefer-stable": true |
||||
|
} |
@ -0,0 +1,243 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel Manager. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\Manager; |
||||
|
|
||||
|
use Closure; |
||||
|
use Illuminate\Contracts\Config\Repository; |
||||
|
use InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* This is the abstract manager class. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
abstract class AbstractManager implements ManagerInterface |
||||
|
{ |
||||
|
/** |
||||
|
* The config instance. |
||||
|
* |
||||
|
* @var \Illuminate\Contracts\Config\Repository |
||||
|
*/ |
||||
|
protected $config; |
||||
|
|
||||
|
/** |
||||
|
* The active connection instances. |
||||
|
* |
||||
|
* @var object[] |
||||
|
*/ |
||||
|
protected $connections = []; |
||||
|
|
||||
|
/** |
||||
|
* The custom connection resolvers. |
||||
|
* |
||||
|
* @var callable[] |
||||
|
*/ |
||||
|
protected $extensions = []; |
||||
|
|
||||
|
/** |
||||
|
* Create a new manager instance. |
||||
|
* |
||||
|
* @param \Illuminate\Contracts\Config\Repository $config |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function __construct(Repository $config) |
||||
|
{ |
||||
|
$this->config = $config; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a connection instance. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
public function connection(string $name = null) |
||||
|
{ |
||||
|
$name = $name ?: $this->getDefaultConnection(); |
||||
|
|
||||
|
if (!isset($this->connections[$name])) { |
||||
|
$this->connections[$name] = $this->makeConnection($name); |
||||
|
} |
||||
|
|
||||
|
return $this->connections[$name]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reconnect to the given connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
public function reconnect(string $name = null) |
||||
|
{ |
||||
|
$name = $name ?: $this->getDefaultConnection(); |
||||
|
|
||||
|
$this->disconnect($name); |
||||
|
|
||||
|
return $this->connection($name); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Disconnect from the given connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function disconnect(string $name = null) |
||||
|
{ |
||||
|
$name = $name ?: $this->getDefaultConnection(); |
||||
|
|
||||
|
unset($this->connections[$name]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create the connection instance. |
||||
|
* |
||||
|
* @param array $config |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
abstract protected function createConnection(array $config); |
||||
|
|
||||
|
/** |
||||
|
* Make the connection instance. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
protected function makeConnection(string $name) |
||||
|
{ |
||||
|
$config = $this->getConnectionConfig($name); |
||||
|
|
||||
|
if (isset($this->extensions[$name])) { |
||||
|
return $this->extensions[$name]($config); |
||||
|
} |
||||
|
|
||||
|
if ($driver = array_get($config, 'driver')) { |
||||
|
if (isset($this->extensions[$driver])) { |
||||
|
return $this->extensions[$driver]($config); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $this->createConnection($config); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the configuration name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
abstract protected function getConfigName(); |
||||
|
|
||||
|
/** |
||||
|
* Get the configuration for a connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getConnectionConfig(string $name = null) |
||||
|
{ |
||||
|
$name = $name ?: $this->getDefaultConnection(); |
||||
|
|
||||
|
$connections = $this->config->get($this->getConfigName().'.connections'); |
||||
|
|
||||
|
if (!is_array($config = array_get($connections, $name)) && !$config) { |
||||
|
throw new InvalidArgumentException("Connection [$name] not configured."); |
||||
|
} |
||||
|
|
||||
|
$config['name'] = $name; |
||||
|
|
||||
|
return $config; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the default connection name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getDefaultConnection() |
||||
|
{ |
||||
|
return $this->config->get($this->getConfigName().'.default'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set the default connection name. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setDefaultConnection(string $name) |
||||
|
{ |
||||
|
$this->config->set($this->getConfigName().'.default', $name); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Register an extension connection resolver. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* @param callable $resolver |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function extend(string $name, callable $resolver) |
||||
|
{ |
||||
|
if ($resolver instanceof Closure) { |
||||
|
$this->extensions[$name] = $resolver->bindTo($this, $this); |
||||
|
} else { |
||||
|
$this->extensions[$name] = $resolver; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return all of the created connections. |
||||
|
* |
||||
|
* @return object[] |
||||
|
*/ |
||||
|
public function getConnections() |
||||
|
{ |
||||
|
return $this->connections; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the config instance. |
||||
|
* |
||||
|
* @return \Illuminate\Contracts\Config\Repository |
||||
|
*/ |
||||
|
public function getConfig() |
||||
|
{ |
||||
|
return $this->config; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Dynamically pass methods to the default connection. |
||||
|
* |
||||
|
* @param string $method |
||||
|
* @param array $parameters |
||||
|
* |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public function __call(string $method, array $parameters) |
||||
|
{ |
||||
|
return $this->connection()->$method(...$parameters); |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel Manager. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\Manager; |
||||
|
|
||||
|
/** |
||||
|
* This is the connector interface. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
interface ConnectorInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Establish a connection. |
||||
|
* |
||||
|
* @param array $config |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
public function connect(array $config); |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Laravel Manager. |
||||
|
* |
||||
|
* (c) Graham Campbell <graham@alt-three.com> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace GrahamCampbell\Manager; |
||||
|
|
||||
|
/** |
||||
|
* This is the manager interface. |
||||
|
* |
||||
|
* @author Graham Campbell <graham@alt-three.com> |
||||
|
*/ |
||||
|
interface ManagerInterface |
||||
|
{ |
||||
|
/** |
||||
|
* Get a connection instance. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
public function connection(string $name = null); |
||||
|
|
||||
|
/** |
||||
|
* Reconnect to the given connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return object |
||||
|
*/ |
||||
|
public function reconnect(string $name = null); |
||||
|
|
||||
|
/** |
||||
|
* Disconnect from the given connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function disconnect(string $name = null); |
||||
|
|
||||
|
/** |
||||
|
* Get the configuration for a connection. |
||||
|
* |
||||
|
* @param string|null $name |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getConnectionConfig(string $name = null); |
||||
|
|
||||
|
/** |
||||
|
* Get the default connection name. |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getDefaultConnection(); |
||||
|
|
||||
|
/** |
||||
|
* Set the default connection name. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setDefaultConnection(string $name); |
||||
|
|
||||
|
/** |
||||
|
* Register an extension connection resolver. |
||||
|
* |
||||
|
* @param string $name |
||||
|
* @param callable $resolver |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function extend(string $name, callable $resolver); |
||||
|
|
||||
|
/** |
||||
|
* Return all of the created connections. |
||||
|
* |
||||
|
* @return object[] |
||||
|
*/ |
||||
|
public function getConnections(); |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
root = true |
||||
|
|
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
|
indent_style = space |
||||
|
indent_size = 4 |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
[*.yml] |
||||
|
indent_style = space |
||||
|
indent_size = 2 |
@ -0,0 +1,14 @@ |
|||||
|
<?php |
||||
|
|
||||
|
$finder = PhpCsFixer\Finder::create() |
||||
|
->in(__DIR__); |
||||
|
|
||||
|
$config = PhpCsFixer\Config::create() |
||||
|
->setRiskyAllowed(true) |
||||
|
->setRules([ |
||||
|
|
||||
|
]) |
||||
|
->setFinder($finder) |
||||
|
; |
||||
|
|
||||
|
return $config; |
@ -0,0 +1,5 @@ |
|||||
|
preset: recommended |
||||
|
|
||||
|
disabled: |
||||
|
- align_double_arrow |
||||
|
- no_multiline_whitespace_before_semicolons |
@ -0,0 +1,249 @@ |
|||||
|
# Change Log |
||||
|
|
||||
|
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release. |
||||
|
|
||||
|
## 2.10.1 |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Convert the assignee parameter to array to avoid getting a 422 error on github (#738) |
||||
|
- Fix GraphQL test warnings when they do not assert anything (#735) |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- Check for BC breaks during the travis build (#734) |
||||
|
|
||||
|
## 2.10.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Support for "before" parameter on Notification API (#724) |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- Allow unspecified `event` when creating review (#723) |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Adjust: installationn access token endpoint (#731) |
||||
|
- Fixed "get single label" example and add correct example for getting issue's labels (#732) |
||||
|
- Add comment about `Key` constructor argument (#722) |
||||
|
|
||||
|
## 2.9.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- API endpoint `Github\Api\Repo::transfer()` |
||||
|
- API endpoint `Github\Api\Notification::markThreadRead()` |
||||
|
- API endpoint `Github\Api\Search::topics()` |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Make sure to always reset the "per page" in `Github\ResultPager::fetchAll()`. |
||||
|
|
||||
|
## 2.8.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Allow our HTTP plugins to show up in the Symfony web profiler page. (#687) |
||||
|
- Repository documentation to current user (#671) |
||||
|
- Add collaborator permission call (#678) |
||||
|
- Add missing parameters for User/CurrentUser Repositories (#684) |
||||
|
- Pimp the readme with badge poser (#686) |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Typo in assignee documentation |
||||
|
- Missing use statement in security example |
||||
|
- Fixed phpdoc typo (#695) |
||||
|
- Replace use of deprecated api to the correct one in the security docs (#697) |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- Updated requirements in readme (#689) |
||||
|
|
||||
|
## 2.7.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Phpunit 6 compatibility |
||||
|
- `Github\Api\AbstractApi::setPage()` to allow you to set the page on all endpoints. |
||||
|
- Support for query parameters and request headers on `Github\Api\User::following` and `Github\Api\User::followers` |
||||
|
- API endpoint `Github\Api\CurrentUser\Emails::allPublic()` |
||||
|
- API endpoint `Github\Api\Search::commits()` |
||||
|
- API endpoint `Github\Api\Miscellaneous\CodeOfConduct` |
||||
|
- API endpoint `Github\Api\Repo::topics()` |
||||
|
- API endpoint `Github\Api\Repo::replaceTopics()` |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Fixed bug in `PathPrepend` plugin where "api/vX" could be duplicated. |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- Improved documentation and doc blocks |
||||
|
|
||||
|
### Removed |
||||
|
|
||||
|
- Dropped support for php 5.5 |
||||
|
|
||||
|
### Deprecated |
||||
|
|
||||
|
The following endpoints were deprecated by Github and are also deprecated in the client: |
||||
|
|
||||
|
- `Github\Api\Repo::find()` |
||||
|
- `Github\Api\User::find()` |
||||
|
- `Github\Api\Issue::find()` |
||||
|
|
||||
|
## 2.6.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Support for graphql api [variables](https://developer.github.com/v4/guides/forming-calls/#working-with-variables) (#612) |
||||
|
- Added missing branch protection methods (#616) |
||||
|
- Helper function `fromFile ` to get GraphQL queries from a file (#628) |
||||
|
- Extra parameter `params` to collaborators api calls (#623) |
||||
|
- Documentation for GitData API (#613) |
||||
|
|
||||
|
### Fixed |
||||
|
- Remove `body` as a required parameter when creating an issue (#624) |
||||
|
- Minor fixes in example code (#617) |
||||
|
|
||||
|
## 2.5.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Stable support for graphql api (V4) (#593) |
||||
|
- Stable support for apps (previously integrations) (#592) |
||||
|
- `Repo::events()` |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Incorrect link in repository search docs (#594) |
||||
|
- Added the required parameter `$message` on `Review::dismiss`. |
||||
|
|
||||
|
## 2.4.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- `Integrations::configure` to allow accessing early access program endpoints. |
||||
|
- Add support for pagination and parameters in the pull request comments |
||||
|
- Add the ability to fetch user installations (`CurrentUser::installations`) |
||||
|
- Allow getting repo info by id (`Repo::showById`) |
||||
|
- Allow fetching repositories for a specific installation and user (`CurrentUser::repositoriesByInstallation`) |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- `PullRequest\Review` and `PullRequest\ReviewRequest` is now part of the official API. No need to call `configure`. |
||||
|
|
||||
|
## 2.3.0 |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Issue where we serve the wrong cached response. We vary on authorization header now. |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- `PullRequest::status` |
||||
|
- Throw InvalidArgumentException on `PullRequest::merge` when wrong merge method is used. |
||||
|
- Added `Protection::configure` |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- First argument to `Integrations::listRepositories()` is now optional. |
||||
|
- Moved tests from "functional" to "integration" |
||||
|
|
||||
|
## 2.2.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- API support for Pull Request Review Requests. |
||||
|
- API support for Traffic. |
||||
|
- API support for issue Assignees. |
||||
|
- API support for Miscellaneous Gitignore and Emojis. |
||||
|
- Added endpoints for issue lock, unlock and issue label show. |
||||
|
- Added more parameters to `User::starred`. |
||||
|
- Fluid interface by allowing `configure()` to return `$this`. |
||||
|
- `configure()` support for issues API. |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Cache issue where some requests are not cached |
||||
|
- Issue with `User::all()` creates a query with double question marks. |
||||
|
|
||||
|
## 2.1.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Add support for retrieving a single notification info using his ID |
||||
|
- Add a function to get user organizations |
||||
|
- Added GraphQL support |
||||
|
- Add page variable to organization repo list (Organization::repositories()) |
||||
|
- Add support for pull request review. |
||||
|
- Add support for adding branch protection. |
||||
|
|
||||
|
### Fixed |
||||
|
|
||||
|
- Bug with double slashes when using enterprise URL. |
||||
|
- Bug when headers not being passed to request (#529) |
||||
|
|
||||
|
## 2.0.0 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- Support for JWT authentication |
||||
|
- API for Organization\Members |
||||
|
- API for Integrations |
||||
|
- API for Repo\Cards |
||||
|
- API for Repo\Columns |
||||
|
- API for Repo\Projects |
||||
|
- API for User\MyRepositories |
||||
|
- Methods in Repo API for frequency and participation |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- `ApiLimitExceedException::__construct` has a new second parameter for the remaining API calls. |
||||
|
- First parameter of `Github\Client` has changed type from `\Http\Client\HttpClient` to |
||||
|
`Github\HttpClient\Builder`. A factory class was also added. To upgrade you need to change: |
||||
|
|
||||
|
```php |
||||
|
// Old way does not work: |
||||
|
$github = new Github\Client($httpClient); |
||||
|
|
||||
|
// New way will work: |
||||
|
$github = new Github\Client(new Github\HttpClient\Builder($httpClient)); |
||||
|
$github = Github\Client::createWithHttpClient($httpClient); |
||||
|
``` |
||||
|
- Renamed the currentuser `DeployKeys` api class to `PublicKeys` to reflect to github api name. |
||||
|
|
||||
|
## 2.0.0-rc4 |
||||
|
|
||||
|
### Added |
||||
|
|
||||
|
- HTTPlug to decouple from Guzzle |
||||
|
- `Github\Client::getLastResponse` was added |
||||
|
- Support for PSR-6 cache |
||||
|
- `Github\Client::addPlugin` and `Github\Client::removePlugin` |
||||
|
- `Github\Client::getApiVersion` |
||||
|
- `Github\Client::removeCache` |
||||
|
|
||||
|
### Changed |
||||
|
|
||||
|
- Uses of `Github\HttpClient\HttpClientInterface` is replaced by `Http\Client\HttpClient` ie the constructor of `Github\Client`. |
||||
|
- We use PSR-7's representation of HTTP message instead of `Guzzle\Http\Message\Response` and `Guzzle\Http\Message\Request`. |
||||
|
- `Github\Client::addHeaders` was added instead of `Github\Client::setHeaders` |
||||
|
- Signature of `Github\Client::useCache` has changed. First argument must be a `CacheItemPoolInterface` |
||||
|
- We use PSR-4 instead of PSR-0 |
||||
|
|
||||
|
### Removed |
||||
|
|
||||
|
- Support for PHP 5.3 and 5.4 |
||||
|
- `Github/HttpClient/HttpClientInterface` was removed |
||||
|
- `Github/HttpClient/HttpClient` was removed |
||||
|
- All classes in `Github/HttpClient/HttpClient/Listener/*` were removed |
||||
|
- `Github/HttpClient/CachedHttpClient` was removed |
||||
|
- All classes in `Github/HttpClient/Cache/*` were removed |
||||
|
|
||||
|
## 1.7.1 |
||||
|
|
||||
|
No change log before this version |
@ -0,0 +1,22 @@ |
|||||
|
The MIT License |
||||
|
|
||||
|
Copyright (c) 2012 KnpLabs |
||||
|
Copyright (c) 2010 Thibault Duplessis |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
@ -0,0 +1,111 @@ |
|||||
|
# PHP GitHub API |
||||
|
|
||||
|
[![Build Status](https://travis-ci.org/KnpLabs/php-github-api.svg?branch=master)](https://travis-ci.org/KnpLabs/php-github-api) |
||||
|
[![StyleCI](https://styleci.io/repos/3948501/shield?style=flat)](https://styleci.io/repos/3948501) |
||||
|
[![Latest Stable Version](https://poser.pugx.org/knplabs/github-api/v/stable)](https://packagist.org/packages/knplabs/github-api) |
||||
|
[![Total Downloads](https://poser.pugx.org/knplabs/github-api/downloads)](https://packagist.org/packages/knplabs/github-api) |
||||
|
[![Latest Unstable Version](https://poser.pugx.org/knplabs/github-api/v/unstable)](https://packagist.org/packages/knplabs/github-api) |
||||
|
[![Monthly Downloads](https://poser.pugx.org/knplabs/github-api/d/monthly)](https://packagist.org/packages/knplabs/github-api) |
||||
|
[![Daily Downloads](https://poser.pugx.org/knplabs/github-api/d/daily)](https://packagist.org/packages/knplabs/github-api) |
||||
|
|
||||
|
A simple Object Oriented wrapper for GitHub API, written with PHP5. |
||||
|
|
||||
|
Uses [GitHub API v3](http://developer.github.com/v3/) & supports [GitHub API v4](http://developer.github.com/v4). The object API (v3) is very similar to the RESTful API. |
||||
|
|
||||
|
## Features |
||||
|
|
||||
|
* Light and fast thanks to lazy loading of API classes |
||||
|
* Extensively tested and documented |
||||
|
|
||||
|
## Requirements |
||||
|
|
||||
|
* PHP >= 5.6 |
||||
|
* A [HTTP client](https://packagist.org/providers/php-http/client-implementation) |
||||
|
* A [PSR-7 implementation](https://packagist.org/providers/psr/http-message-implementation) |
||||
|
* (optional) PHPUnit to run tests. |
||||
|
|
||||
|
## Install |
||||
|
|
||||
|
Via Composer: |
||||
|
|
||||
|
```bash |
||||
|
$ composer require knplabs/github-api php-http/guzzle6-adapter |
||||
|
``` |
||||
|
|
||||
|
Why `php-http/guzzle6-adapter`? We are decoupled from any HTTP messaging client with help by [HTTPlug](http://httplug.io/). Read about clients in our [docs](doc/customize.md). |
||||
|
|
||||
|
|
||||
|
## Using Laravel? |
||||
|
|
||||
|
[Laravel GitHub](https://github.com/GrahamCampbell/Laravel-GitHub) by [Graham Campbell](https://github.com/GrahamCampbell) might interest you. |
||||
|
|
||||
|
## Basic usage of `php-github-api` client |
||||
|
|
||||
|
```php |
||||
|
<?php |
||||
|
|
||||
|
// This file is generated by Composer |
||||
|
require_once __DIR__ . '/vendor/autoload.php'; |
||||
|
|
||||
|
$client = new \Github\Client(); |
||||
|
$repositories = $client->api('user')->repositories('ornicar'); |
||||
|
``` |
||||
|
|
||||
|
From `$client` object, you can access to all GitHub. |
||||
|
|
||||
|
## Cache usage |
||||
|
|
||||
|
This example uses the PSR6 cache pool [redis-adapter](https://github.com/php-cache/redis-adapter). See http://www.php-cache.com/ for alternatives. |
||||
|
|
||||
|
```php |
||||
|
<?php |
||||
|
|
||||
|
// This file is generated by Composer |
||||
|
require_once __DIR__ . '/vendor/autoload.php'; |
||||
|
|
||||
|
use Cache\Adapter\Redis\RedisCachePool; |
||||
|
|
||||
|
$client = new \Redis(); |
||||
|
$client->connect('127.0.0.1', 6379); |
||||
|
// Create a PSR6 cache pool |
||||
|
$pool = new RedisCachePool($client); |
||||
|
|
||||
|
$client = new \Github\Client(); |
||||
|
$client->addCache($pool); |
||||
|
|
||||
|
// Do some request |
||||
|
|
||||
|
// Stop using cache |
||||
|
$client->removeCache(); |
||||
|
``` |
||||
|
|
||||
|
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). |
||||
|
|
||||
|
|
||||
|
## Documentation |
||||
|
|
||||
|
See the [`doc` directory](doc/) for more detailed documentation. |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
`php-github-api` is licensed under the MIT License - see the LICENSE file for details |
||||
|
|
||||
|
## Credits |
||||
|
|
||||
|
### Sponsored by |
||||
|
|
||||
|
[![KnpLabs Team](http://knplabs.com/front/images/knp-labs-logo.png)](http://knplabs.com) |
||||
|
|
||||
|
### Contributors |
||||
|
|
||||
|
- Thanks to [Thibault Duplessis aka. ornicar](http://github.com/ornicar) for his first version of this library. |
||||
|
- Thanks to [Joseph Bielawski aka. stloyd](http://github.com/stloyd) for his contributions and support. |
||||
|
- Thanks to [noloh](http://github.com/noloh) for his contribution on the Object API. |
||||
|
- Thanks to [bshaffer](http://github.com/bshaffer) for his contribution on the Repo API. |
||||
|
- Thanks to [Rolf van de Krol](http://github.com/rolfvandekrol) for his countless contributions. |
||||
|
- Thanks to [Nicolas Pastorino](http://github.com/jeanvoye) for his contribution on the Pull Request API. |
||||
|
- Thanks to [Edoardo Rivello](http://github.com/erivello) for his contribution on the Gists API. |
||||
|
- Thanks to [Miguel Piedrafita](https://github.com/m1guelpf) for his contribution to the v4 & Apps API. |
||||
|
|
||||
|
Thanks to GitHub for the high quality API and documentation. |
@ -0,0 +1,49 @@ |
|||||
|
{ |
||||
|
"name": "knplabs/github-api", |
||||
|
"type": "library", |
||||
|
"description": "GitHub API v3 client", |
||||
|
"homepage": "https://github.com/KnpLabs/php-github-api", |
||||
|
"keywords": ["github", "gh", "api", "gist"], |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "KnpLabs Team", |
||||
|
"homepage": "http://knplabs.com" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "Thibault Duplessis", |
||||
|
"email": "thibault.duplessis@gmail.com", |
||||
|
"homepage": "http://ornicar.github.com" |
||||
|
} |
||||
|
], |
||||
|
"require": { |
||||
|
"php": "^5.6 || ^7.0", |
||||
|
"psr/http-message": "^1.0", |
||||
|
"psr/cache": "^1.0", |
||||
|
"php-http/httplug": "^1.1", |
||||
|
"php-http/discovery": "^1.0", |
||||
|
"php-http/client-implementation": "^1.0", |
||||
|
"php-http/client-common": "^1.6", |
||||
|
"php-http/cache-plugin": "^1.4" |
||||
|
}, |
||||
|
"require-dev": { |
||||
|
"phpunit/phpunit": "^5.5 || ^6.0", |
||||
|
"php-http/guzzle6-adapter": "^1.0", |
||||
|
"php-http/mock-client": "^1.0", |
||||
|
"guzzlehttp/psr7": "^1.2", |
||||
|
"cache/array-adapter": "^0.4" |
||||
|
}, |
||||
|
"autoload": { |
||||
|
"psr-4": { "Github\\": "lib/Github/" } |
||||
|
}, |
||||
|
"autoload-dev": { |
||||
|
"psr-4": { "Github\\Tests\\": "test/Github/Tests/"} |
||||
|
}, |
||||
|
"minimum-stability": "dev", |
||||
|
"prefer-stable": true, |
||||
|
"extra": { |
||||
|
"branch-alias": { |
||||
|
"dev-master": "2.10.x-dev" |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,243 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Client; |
||||
|
use Github\HttpClient\Message\ResponseMediator; |
||||
|
|
||||
|
/** |
||||
|
* Abstract class for Api classes. |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
abstract class AbstractApi implements ApiInterface |
||||
|
{ |
||||
|
/** |
||||
|
* The client. |
||||
|
* |
||||
|
* @var Client |
||||
|
*/ |
||||
|
protected $client; |
||||
|
|
||||
|
/** |
||||
|
* The requested page (GitHub pagination). |
||||
|
* |
||||
|
* @var null|int |
||||
|
*/ |
||||
|
private $page; |
||||
|
|
||||
|
/** |
||||
|
* Number of items per page (GitHub pagination). |
||||
|
* |
||||
|
* @var null|int |
||||
|
*/ |
||||
|
protected $perPage; |
||||
|
|
||||
|
/** |
||||
|
* @param Client $client |
||||
|
*/ |
||||
|
public function __construct(Client $client) |
||||
|
{ |
||||
|
$this->client = $client; |
||||
|
} |
||||
|
|
||||
|
public function configure() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return null|int |
||||
|
*/ |
||||
|
public function getPage() |
||||
|
{ |
||||
|
return $this->page; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param null|int $page |
||||
|
*/ |
||||
|
public function setPage($page) |
||||
|
{ |
||||
|
$this->page = (null === $page ? $page : (int) $page); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return null|int |
||||
|
*/ |
||||
|
public function getPerPage() |
||||
|
{ |
||||
|
return $this->perPage; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param null|int $perPage |
||||
|
*/ |
||||
|
public function setPerPage($perPage) |
||||
|
{ |
||||
|
$this->perPage = (null === $perPage ? $perPage : (int) $perPage); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a GET request with query parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters GET parameters. |
||||
|
* @param array $requestHeaders Request Headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function get($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
if (null !== $this->page && !isset($parameters['page'])) { |
||||
|
$parameters['page'] = $this->page; |
||||
|
} |
||||
|
if (null !== $this->perPage && !isset($parameters['per_page'])) { |
||||
|
$parameters['per_page'] = $this->perPage; |
||||
|
} |
||||
|
if (array_key_exists('ref', $parameters) && is_null($parameters['ref'])) { |
||||
|
unset($parameters['ref']); |
||||
|
} |
||||
|
|
||||
|
if (count($parameters) > 0) { |
||||
|
$path .= '?'.http_build_query($parameters); |
||||
|
} |
||||
|
|
||||
|
$response = $this->client->getHttpClient()->get($path, $requestHeaders); |
||||
|
|
||||
|
return ResponseMediator::getContent($response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a HEAD request with query parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters HEAD parameters. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return \Psr\Http\Message\ResponseInterface |
||||
|
*/ |
||||
|
protected function head($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
if (array_key_exists('ref', $parameters) && is_null($parameters['ref'])) { |
||||
|
unset($parameters['ref']); |
||||
|
} |
||||
|
|
||||
|
$response = $this->client->getHttpClient()->head($path.'?'.http_build_query($parameters), $requestHeaders); |
||||
|
|
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a POST request with JSON-encoded parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters POST parameters to be JSON encoded. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function post($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return $this->postRaw( |
||||
|
$path, |
||||
|
$this->createJsonBody($parameters), |
||||
|
$requestHeaders |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a POST request with raw data. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param string $body Request body. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function postRaw($path, $body, array $requestHeaders = []) |
||||
|
{ |
||||
|
$response = $this->client->getHttpClient()->post( |
||||
|
$path, |
||||
|
$requestHeaders, |
||||
|
$body |
||||
|
); |
||||
|
|
||||
|
return ResponseMediator::getContent($response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a PATCH request with JSON-encoded parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters POST parameters to be JSON encoded. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function patch($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
$response = $this->client->getHttpClient()->patch( |
||||
|
$path, |
||||
|
$requestHeaders, |
||||
|
$this->createJsonBody($parameters) |
||||
|
); |
||||
|
|
||||
|
return ResponseMediator::getContent($response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a PUT request with JSON-encoded parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters POST parameters to be JSON encoded. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function put($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
$response = $this->client->getHttpClient()->put( |
||||
|
$path, |
||||
|
$requestHeaders, |
||||
|
$this->createJsonBody($parameters) |
||||
|
); |
||||
|
|
||||
|
return ResponseMediator::getContent($response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Send a DELETE request with JSON-encoded parameters. |
||||
|
* |
||||
|
* @param string $path Request path. |
||||
|
* @param array $parameters POST parameters to be JSON encoded. |
||||
|
* @param array $requestHeaders Request headers. |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function delete($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
$response = $this->client->getHttpClient()->delete( |
||||
|
$path, |
||||
|
$requestHeaders, |
||||
|
$this->createJsonBody($parameters) |
||||
|
); |
||||
|
|
||||
|
return ResponseMediator::getContent($response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a JSON encoded version of an array of parameters. |
||||
|
* |
||||
|
* @param array $parameters Request parameters |
||||
|
* |
||||
|
* @return null|string |
||||
|
*/ |
||||
|
protected function createJsonBody(array $parameters) |
||||
|
{ |
||||
|
return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0); |
||||
|
} |
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
<?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 = []) |
||||
|
{ |
||||
|
return parent::get($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function head($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::head($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function post($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::post($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function postRaw($path, $body, array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::postRaw($path, $body, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function patch($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::patch($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function put($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::put($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
protected function delete($path, array $parameters = [], array $requestHeaders = []) |
||||
|
{ |
||||
|
return parent::delete($path, $parameters, $this->mergeHeaders($requestHeaders)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Append a new accept header on all requests. |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
private function mergeHeaders(array $headers = []) |
||||
|
{ |
||||
|
$default = []; |
||||
|
if ($this->acceptHeaderValue) { |
||||
|
$default = ['Accept' => $this->acceptHeaderValue]; |
||||
|
} |
||||
|
|
||||
|
return array_merge($default, $headers); |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* Api interface. |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
interface ApiInterface |
||||
|
{ |
||||
|
public function getPerPage(); |
||||
|
|
||||
|
public function setPerPage($perPage); |
||||
|
} |
@ -0,0 +1,93 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/apps/ |
||||
|
* |
||||
|
* @author Nils Adermann <naderman@naderman.de> |
||||
|
*/ |
||||
|
class Apps extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Create an access token for an installation. |
||||
|
* |
||||
|
* @param int $installationId An integration installation id |
||||
|
* @param int $userId An optional user id on behalf of whom the |
||||
|
* token will be requested |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/apps/#create-a-new-installation-token |
||||
|
* |
||||
|
* @return array token and token metadata |
||||
|
*/ |
||||
|
public function createInstallationToken($installationId, $userId = null) |
||||
|
{ |
||||
|
$parameters = []; |
||||
|
if ($userId) { |
||||
|
$parameters['user_id'] = $userId; |
||||
|
} |
||||
|
|
||||
|
return $this->post('/app/installations/'.rawurlencode($installationId).'/access_tokens', $parameters); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Find all installations for the authenticated application. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/apps/#find-installations |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function findInstallations() |
||||
|
{ |
||||
|
return $this->get('/app/installations'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List repositories that are accessible to the authenticated installation. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/apps/installations/#list-repositories |
||||
|
* |
||||
|
* @param int $userId |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function listRepositories($userId = null) |
||||
|
{ |
||||
|
$parameters = []; |
||||
|
if ($userId) { |
||||
|
$parameters['user_id'] = $userId; |
||||
|
} |
||||
|
|
||||
|
return $this->get('/installation/repositories', $parameters); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Add a single repository to an installation. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/apps/installations/#add-repository-to-installation |
||||
|
* |
||||
|
* @param int $installationId |
||||
|
* @param int $repositoryId |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function addRepository($installationId, $repositoryId) |
||||
|
{ |
||||
|
return $this->put('/installations/'.rawurlencode($installationId).'/repositories/'.rawurlencode($repositoryId)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove a single repository from an installation. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/apps/installations/#remove-repository-from-installation |
||||
|
* |
||||
|
* @param int $installationId |
||||
|
* @param int $repositoryId |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function removeRepository($installationId, $repositoryId) |
||||
|
{ |
||||
|
return $this->delete('/installations/'.rawurlencode($installationId).'/repositories/'.rawurlencode($repositoryId)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,122 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* Creating, deleting and listing authorizations. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/oauth_authorizations/ |
||||
|
* |
||||
|
* @author Evgeniy Guseletov <d46k16@gmail.com> |
||||
|
*/ |
||||
|
class Authorizations extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List all authorizations. |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/authorizations'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Show a single authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($clientId) |
||||
|
{ |
||||
|
return $this->get('/authorizations/'.rawurlencode($clientId)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create an authorization. |
||||
|
* |
||||
|
* @param array $params |
||||
|
* @param null $OTPCode |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create(array $params, $OTPCode = null) |
||||
|
{ |
||||
|
$headers = null === $OTPCode ? [] : ['X-GitHub-OTP' => $OTPCode]; |
||||
|
|
||||
|
return $this->post('/authorizations', $params, $headers); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update an authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($clientId, array $params) |
||||
|
{ |
||||
|
return $this->patch('/authorizations/'.rawurlencode($clientId), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove an authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($clientId) |
||||
|
{ |
||||
|
return $this->delete('/authorizations/'.rawurlencode($clientId)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check an authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* @param $token |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function check($clientId, $token) |
||||
|
{ |
||||
|
return $this->get('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reset an authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* @param $token |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function reset($clientId, $token) |
||||
|
{ |
||||
|
return $this->post('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove an authorization. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
* @param $token |
||||
|
*/ |
||||
|
public function revoke($clientId, $token) |
||||
|
{ |
||||
|
$this->delete('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Revoke all authorizations. |
||||
|
* |
||||
|
* @param $clientId |
||||
|
*/ |
||||
|
public function revokeAll($clientId) |
||||
|
{ |
||||
|
$this->delete('/applications/'.rawurlencode($clientId).'/tokens'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,207 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Api\CurrentUser\Emails; |
||||
|
use Github\Api\CurrentUser\Followers; |
||||
|
use Github\Api\CurrentUser\Memberships; |
||||
|
use Github\Api\CurrentUser\Notifications; |
||||
|
use Github\Api\CurrentUser\PublicKeys; |
||||
|
use Github\Api\CurrentUser\Starring; |
||||
|
use Github\Api\CurrentUser\Watchers; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/users/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
* @author Felipe Valtl de Mello <eu@felipe.im> |
||||
|
*/ |
||||
|
class CurrentUser extends AbstractApi |
||||
|
{ |
||||
|
public function show() |
||||
|
{ |
||||
|
return $this->get('/user'); |
||||
|
} |
||||
|
|
||||
|
public function update(array $params) |
||||
|
{ |
||||
|
return $this->patch('/user', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Emails |
||||
|
*/ |
||||
|
public function emails() |
||||
|
{ |
||||
|
return new Emails($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Followers |
||||
|
*/ |
||||
|
public function follow() |
||||
|
{ |
||||
|
return new Followers($this->client); |
||||
|
} |
||||
|
|
||||
|
public function followers($page = 1) |
||||
|
{ |
||||
|
return $this->get('/user/followers', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/issues/#list-issues |
||||
|
* |
||||
|
* @param array $params |
||||
|
* @param bool $includeOrgIssues |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function issues(array $params = [], $includeOrgIssues = true) |
||||
|
{ |
||||
|
return $this->get($includeOrgIssues ? '/issues' : '/user/issues', array_merge(['page' => 1], $params)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return PublicKeys |
||||
|
*/ |
||||
|
public function keys() |
||||
|
{ |
||||
|
return new PublicKeys($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Notifications |
||||
|
*/ |
||||
|
public function notifications() |
||||
|
{ |
||||
|
return new Notifications($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Memberships |
||||
|
*/ |
||||
|
public function memberships() |
||||
|
{ |
||||
|
return new Memberships($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/orgs/#list-user-organizations |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function organizations() |
||||
|
{ |
||||
|
return $this->get('/user/orgs'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/orgs/teams/#list-user-teams |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function teams() |
||||
|
{ |
||||
|
return $this->get('/user/teams'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/repos/#list-your-repositories |
||||
|
* |
||||
|
* @param string $type role in the repository |
||||
|
* @param string $sort sort by |
||||
|
* @param string $direction direction of sort, asc or desc |
||||
|
* @param string $visibility visibility of repository |
||||
|
* @param string $affiliation relationship to repository |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function repositories($type = 'owner', $sort = 'full_name', $direction = 'asc', $visibility = null, $affiliation = null) |
||||
|
{ |
||||
|
$params = [ |
||||
|
'type' => $type, |
||||
|
'sort' => $sort, |
||||
|
'direction' => $direction, |
||||
|
]; |
||||
|
|
||||
|
if (null !== $visibility) { |
||||
|
unset($params['type']); |
||||
|
$params['visibility'] = $visibility; |
||||
|
} |
||||
|
|
||||
|
if (null !== $affiliation) { |
||||
|
unset($params['type']); |
||||
|
$params['affiliation'] = $affiliation; |
||||
|
} |
||||
|
|
||||
|
return $this->get('/user/repos', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Watchers |
||||
|
*/ |
||||
|
public function watchers() |
||||
|
{ |
||||
|
return new Watchers($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @deprecated Use watchers() instead |
||||
|
*/ |
||||
|
public function watched($page = 1) |
||||
|
{ |
||||
|
return $this->get('/user/watched', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Starring |
||||
|
*/ |
||||
|
public function starring() |
||||
|
{ |
||||
|
return new Starring($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @deprecated Use starring() instead |
||||
|
*/ |
||||
|
public function starred($page = 1) |
||||
|
{ |
||||
|
return $this->get('/user/starred', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/activity/watching/#list-repositories-being-watched |
||||
|
*/ |
||||
|
public function subscriptions() |
||||
|
{ |
||||
|
return $this->get('/user/subscriptions'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/integrations/#list-installations-for-user |
||||
|
* |
||||
|
* @param array $params |
||||
|
*/ |
||||
|
public function installations(array $params = []) |
||||
|
{ |
||||
|
return $this->get('/user/installations', array_merge(['page' => 1], $params)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/integrations/installations/#list-repositories-accessible-to-the-user-for-an-installation |
||||
|
* |
||||
|
* @param string $installationId the ID of the Installation |
||||
|
* @param array $params |
||||
|
*/ |
||||
|
public function repositoriesByInstallation($installationId, array $params = []) |
||||
|
{ |
||||
|
return $this->get(sprintf('/user/installations/%s/repositories', $installationId), array_merge(['page' => 1], $params)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,94 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\InvalidArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/users/emails/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Emails extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List emails for the authenticated user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/users/emails/ |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/user/emails'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List public email addresses for a user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/emails/#list-public-email-addresses-for-a-user |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function allPublic() |
||||
|
{ |
||||
|
return $this->get('/user/public_emails'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds one or more email for the authenticated user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/users/emails/ |
||||
|
* |
||||
|
* @param string|array $emails |
||||
|
* |
||||
|
* @throws \Github\Exception\InvalidArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function add($emails) |
||||
|
{ |
||||
|
if (is_string($emails)) { |
||||
|
$emails = [$emails]; |
||||
|
} elseif (0 === count($emails)) { |
||||
|
throw new InvalidArgumentException(); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/user/emails', $emails); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Removes one or more email for the authenticated user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/users/emails/ |
||||
|
* |
||||
|
* @param string|array $emails |
||||
|
* |
||||
|
* @throws \Github\Exception\InvalidArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($emails) |
||||
|
{ |
||||
|
if (is_string($emails)) { |
||||
|
$emails = [$emails]; |
||||
|
} elseif (0 === count($emails)) { |
||||
|
throw new InvalidArgumentException(); |
||||
|
} |
||||
|
|
||||
|
return $this->delete('/user/emails', $emails); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Toggle primary email visibility. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/emails/#toggle-primary-email-visibility |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function toggleVisibility() |
||||
|
{ |
||||
|
return $this->patch('/user/email/visibility'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/users/followers/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Followers extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List followed users by the authenticated user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/repos/followers/ |
||||
|
* |
||||
|
* @param int $page |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($page = 1) |
||||
|
{ |
||||
|
return $this->get('/user/following', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check that the authenticated user follows a user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/repos/followers/ |
||||
|
* |
||||
|
* @param string $username the username to follow |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function check($username) |
||||
|
{ |
||||
|
return $this->get('/user/following/'.rawurlencode($username)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user follow a user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/repos/followers/ |
||||
|
* |
||||
|
* @param string $username the username to follow |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function follow($username) |
||||
|
{ |
||||
|
return $this->put('/user/following/'.rawurlencode($username)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user un-follow a user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/repos/followers/ |
||||
|
* |
||||
|
* @param string $username the username to un-follow |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function unfollow($username) |
||||
|
{ |
||||
|
return $this->delete('/user/following/'.rawurlencode($username)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class Memberships extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List your organization memberships. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/orgs/members/#get-your-organization-membership |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/user/memberships/orgs'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get your organization membership. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/orgs/members/#get-your-organization-membership |
||||
|
* |
||||
|
* @param string $organization |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function organization($organization) |
||||
|
{ |
||||
|
return $this->get('/user/memberships/orgs/'.rawurlencode($organization)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Edit your organization membership. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/orgs/members/#edit-your-organization-membership |
||||
|
* |
||||
|
* @param string $organization |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function edit($organization) |
||||
|
{ |
||||
|
return $this->patch('/user/memberships/orgs/'.rawurlencode($organization), ['state' => 'active']); |
||||
|
} |
||||
|
} |
@ -0,0 +1,145 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/activity/notifications/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Notifications extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List all notifications for the authenticated user. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#list-your-notifications |
||||
|
* |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all(array $params = []) |
||||
|
{ |
||||
|
return $this->get('/notifications', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all notifications for the authenticated user in selected repository. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function allInRepository($username, $repository, array $params = []) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/notifications', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Mark all notifications as read. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#mark-as-read |
||||
|
* |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function markAsReadAll(array $params = []) |
||||
|
{ |
||||
|
return $this->put('/notifications', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Mark all notifications for a repository as read. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function markAsReadInRepository($username, $repository, array $params = []) |
||||
|
{ |
||||
|
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/notifications', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Mark a notification as read. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read |
||||
|
* |
||||
|
* @param int $id the notification number |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function markAsRead($id, array $params) |
||||
|
{ |
||||
|
return $this->patch('/notifications/threads/'.rawurlencode($id), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Show a notification. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#view-a-single-thread |
||||
|
* |
||||
|
* @param int $id the notification number |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($id) |
||||
|
{ |
||||
|
return $this->get('/notifications/threads/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Show a subscription. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#get-a-thread-subscription |
||||
|
* |
||||
|
* @param int $id the notification number |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function showSubscription($id) |
||||
|
{ |
||||
|
return $this->get('/notifications/threads/'.rawurlencode($id).'/subscription'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a subscription. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#set-a-thread-subscription |
||||
|
* |
||||
|
* @param int $id the notification number |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function createSubscription($id, array $params) |
||||
|
{ |
||||
|
return $this->put('/notifications/threads/'.rawurlencode($id).'/subscription', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a subscription. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription |
||||
|
* |
||||
|
* @param int $id the notification number |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function removeSubscription($id) |
||||
|
{ |
||||
|
return $this->delete('/notifications/threads/'.rawurlencode($id).'/subscription'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,74 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/users/keys/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class PublicKeys extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List deploy keys for the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/keys/ |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/user/keys'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Shows deploy key for the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/keys/ |
||||
|
* |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($id) |
||||
|
{ |
||||
|
return $this->get('/user/keys/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Adds deploy key for the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/keys/ |
||||
|
* |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create(array $params) |
||||
|
{ |
||||
|
if (!isset($params['title'], $params['key'])) { |
||||
|
throw new MissingArgumentException(['title', 'key']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/user/keys', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Removes deploy key for the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/keys/ |
||||
|
* |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($id) |
||||
|
{ |
||||
|
return $this->delete('/user/keys/'.rawurlencode($id)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/activity/starring/ |
||||
|
* |
||||
|
* @author Felipe Valtl de Mello <eu@felipe.im> |
||||
|
*/ |
||||
|
class Starring extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List repositories starred by the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/starring/ |
||||
|
* |
||||
|
* @param int $page |
||||
|
* @param int $perPage |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($page = 1, $perPage = 30) |
||||
|
{ |
||||
|
return $this->get('/user/starred', [ |
||||
|
'page' => $page, |
||||
|
'per_page' => $perPage, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check that the authenticated user starres a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/starring/ |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function check($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/user/starred/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user star a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/starring/ |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function star($username, $repository) |
||||
|
{ |
||||
|
return $this->put('/user/starred/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user unstar a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/starring |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function unstar($username, $repository) |
||||
|
{ |
||||
|
return $this->delete('/user/starred/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,75 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\CurrentUser; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/activity/watching/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
* @revised Felipe Valtl de Mello <eu@felipe.im> |
||||
|
*/ |
||||
|
class Watchers extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List repositories watched by the authenticated user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/watching/ |
||||
|
* |
||||
|
* @param int $page |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($page = 1) |
||||
|
{ |
||||
|
return $this->get('/user/subscriptions', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check that the authenticated user watches a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/watching/ |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function check($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/user/subscriptions/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user watch a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/watching/ |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function watch($username, $repository) |
||||
|
{ |
||||
|
return $this->put('/user/subscriptions/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Make the authenticated user unwatch a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/activity/watching/ |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function unwatch($username, $repository) |
||||
|
{ |
||||
|
return $this->delete('/user/subscriptions/'.rawurlencode($username).'/'.rawurlencode($repository)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,107 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* Listing, creating and updating deployments. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/repos/deployments/ |
||||
|
*/ |
||||
|
class Deployment extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List deployments for a particular repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/repos/deployments/#list-deployments |
||||
|
* |
||||
|
* @param string $username the username of the user who owns the repository |
||||
|
* @param string $repository the name of the repository |
||||
|
* @param array $params query parameters to filter deployments by (see link) |
||||
|
* |
||||
|
* @return array the deployments requested |
||||
|
*/ |
||||
|
public function all($username, $repository, array $params = []) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a deployment in selected repository. |
||||
|
* |
||||
|
* @param string $username the user who owns the repo |
||||
|
* @param string $repository the name of the repo |
||||
|
* @param int $id the id of the deployment |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a new deployment for the given username and repo. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/repos/deployments/#create-a-deployment |
||||
|
* |
||||
|
* Important: Once a deployment is created, it cannot be updated. Changes are indicated by creating new statuses. |
||||
|
* @see updateStatus |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param array $params the new deployment data |
||||
|
* |
||||
|
* @throws MissingArgumentException |
||||
|
* |
||||
|
* @return array information about the deployment |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['ref'])) { |
||||
|
throw new MissingArgumentException(['ref']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Updates a deployment by creating a new status update. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/repos/deployments/#create-a-deployment-status |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param int $id the deployment number |
||||
|
* @param array $params The information about the deployment update. |
||||
|
* Must include a "state" field of pending, success, error, or failure. |
||||
|
* May also be given a target_url and description, ßee link for more details. |
||||
|
* |
||||
|
* @throws MissingArgumentException |
||||
|
* |
||||
|
* @return array information about the deployment |
||||
|
*/ |
||||
|
public function updateStatus($username, $repository, $id, array $params) |
||||
|
{ |
||||
|
if (!isset($params['state'])) { |
||||
|
throw new MissingArgumentException(['state']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id).'/statuses', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Gets all of the status updates tied to a given deployment. |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param int $id the deployment identifier |
||||
|
* |
||||
|
* @return array the deployment statuses |
||||
|
*/ |
||||
|
public function getStatuses($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id).'/statuses'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Api\Enterprise\License; |
||||
|
use Github\Api\Enterprise\ManagementConsole; |
||||
|
use Github\Api\Enterprise\Stats; |
||||
|
use Github\Api\Enterprise\UserAdmin; |
||||
|
|
||||
|
/** |
||||
|
* Getting information about a GitHub Enterprise instance. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
* @author Guillermo A. Fisher <guillermoandraefisher@gmail.com> |
||||
|
*/ |
||||
|
class Enterprise extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* @return Stats |
||||
|
*/ |
||||
|
public function stats() |
||||
|
{ |
||||
|
return new Stats($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return License |
||||
|
*/ |
||||
|
public function license() |
||||
|
{ |
||||
|
return new License($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return ManagementConsole |
||||
|
*/ |
||||
|
public function console() |
||||
|
{ |
||||
|
return new ManagementConsole($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return UserAdmin |
||||
|
*/ |
||||
|
public function userAdmin() |
||||
|
{ |
||||
|
return new UserAdmin($this->client); |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Enterprise; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class License extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Provides information about your Enterprise license (only available to site admins). |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/license/ |
||||
|
* |
||||
|
* @return array array of license information |
||||
|
*/ |
||||
|
public function show() |
||||
|
{ |
||||
|
return $this->get('/enterprise/settings/license'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Enterprise; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class ManagementConsole extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Checks the status of your installation’s most recent configuration process. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/management_console/#check-configuration-status |
||||
|
* |
||||
|
* @param string $hash md5 hash of your license |
||||
|
* |
||||
|
* @return array array of configuration status information |
||||
|
*/ |
||||
|
public function configcheck($hash) |
||||
|
{ |
||||
|
return $this->getWithLicenseHash('/setup/api/configcheck', $hash); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Retrieves your installation’s settings. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/management_console/#retrieve-settings |
||||
|
* |
||||
|
* @param string $hash md5 hash of your license |
||||
|
* |
||||
|
* @return array array of settings |
||||
|
*/ |
||||
|
public function settings($hash) |
||||
|
{ |
||||
|
return $this->getWithLicenseHash('/setup/api/settings', $hash); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks your installation’s maintenance status. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status |
||||
|
* |
||||
|
* @param string $hash md5 hash of your license |
||||
|
* |
||||
|
* @return array array of maintenance status information |
||||
|
*/ |
||||
|
public function maintenance($hash) |
||||
|
{ |
||||
|
return $this->getWithLicenseHash('/setup/api/maintenance', $hash); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Retrieves your installation’s authorized SSH keys. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/enterprise/management_console/#retrieve-authorized-ssh-keys |
||||
|
* |
||||
|
* @param string $hash md5 hash of your license |
||||
|
* |
||||
|
* @return array array of authorized keys |
||||
|
*/ |
||||
|
public function keys($hash) |
||||
|
{ |
||||
|
return $this->getWithLicenseHash('/setup/api/settings/authorized-keys', $hash); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Sends an authenticated GET request. |
||||
|
* |
||||
|
* @param string $uri the request URI |
||||
|
* @param string $hash md5 hash of your license |
||||
|
* |
||||
|
* @return array|string |
||||
|
*/ |
||||
|
protected function getWithLicenseHash($uri, $hash) |
||||
|
{ |
||||
|
return $this->get($uri, ['license_md5' => rawurlencode($hash)]); |
||||
|
} |
||||
|
} |
@ -0,0 +1,128 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Enterprise; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class Stats extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Returns the number of open and closed issues. |
||||
|
* |
||||
|
* @return array array with totals of open and closed issues |
||||
|
*/ |
||||
|
public function issues() |
||||
|
{ |
||||
|
return $this->show('issues'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of active and inactive hooks. |
||||
|
* |
||||
|
* @return array array with totals of active and inactive hooks |
||||
|
*/ |
||||
|
public function hooks() |
||||
|
{ |
||||
|
return $this->show('hooks'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of open and closed milestones. |
||||
|
* |
||||
|
* @return array array with totals of open and closed milestones |
||||
|
*/ |
||||
|
public function milestones() |
||||
|
{ |
||||
|
return $this->show('milestones'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of organizations, teams, team members, and disabled organizations. |
||||
|
* |
||||
|
* @return array array with totals of organizations, teams, team members, and disabled organizations |
||||
|
*/ |
||||
|
public function orgs() |
||||
|
{ |
||||
|
return $this->show('orgs'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of comments on issues, pull requests, commits, and gists. |
||||
|
* |
||||
|
* @return array array with totals of comments on issues, pull requests, commits, and gists |
||||
|
*/ |
||||
|
public function comments() |
||||
|
{ |
||||
|
return $this->show('comments'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of GitHub Pages sites. |
||||
|
* |
||||
|
* @return array array with totals of GitHub Pages sites |
||||
|
*/ |
||||
|
public function pages() |
||||
|
{ |
||||
|
return $this->show('pages'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of suspended and admin users. |
||||
|
* |
||||
|
* @return array array with totals of suspended and admin users |
||||
|
*/ |
||||
|
public function users() |
||||
|
{ |
||||
|
return $this->show('users'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of private and public gists. |
||||
|
* |
||||
|
* @return array array with totals of private and public gists |
||||
|
*/ |
||||
|
public function gists() |
||||
|
{ |
||||
|
return $this->show('gists'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of merged, mergeable, and unmergeable pull requests. |
||||
|
* |
||||
|
* @return array array with totals of merged, mergeable, and unmergeable pull requests |
||||
|
*/ |
||||
|
public function pulls() |
||||
|
{ |
||||
|
return $this->show('pulls'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of organization-owned repositories, root repositories, forks, pushed commits, and wikis. |
||||
|
* |
||||
|
* @return array array with totals of organization-owned repositories, root repositories, forks, pushed commits, and wikis |
||||
|
*/ |
||||
|
public function repos() |
||||
|
{ |
||||
|
return $this->show('repos'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns all of the statistics. |
||||
|
* |
||||
|
* @return array array with all of the statistics |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->show('all'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $type The type of statistics to show |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($type) |
||||
|
{ |
||||
|
return $this->get('/enterprise/stats/'.rawurlencode($type)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Enterprise; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class UserAdmin extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Suspend a user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/administration/#suspend-a-user |
||||
|
* |
||||
|
* @param string $username |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function suspend($username) |
||||
|
{ |
||||
|
return $this->put('/users/'.rawurldecode($username).'/suspended', ['Content-Length' => 0]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Unsuspend a user. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/users/administration/#unsuspend-a-user |
||||
|
* |
||||
|
* @param string $username |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function unsuspend($username) |
||||
|
{ |
||||
|
return $this->delete('/users/'.rawurldecode($username).'/suspended'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,101 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Gist; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Api\AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* @link https://developer.github.com/v3/gists/comments/ |
||||
|
* |
||||
|
* @author Kayla Daniels <kayladnls@gmail.com> |
||||
|
*/ |
||||
|
class Comments extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* Configure the body type. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/gists/comments/#custom-media-types |
||||
|
* |
||||
|
* @param string|null $bodyType |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure($bodyType = null) |
||||
|
{ |
||||
|
if (!in_array($bodyType, ['text', 'html', 'full'])) { |
||||
|
$bodyType = 'raw'; |
||||
|
} |
||||
|
|
||||
|
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all comments for a gist. |
||||
|
* |
||||
|
* @param string $gist |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($gist) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($gist).'/comments'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a comment of a gist. |
||||
|
* |
||||
|
* @param string $gist |
||||
|
* @param int $comment |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($gist, $comment) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a comment for gist. |
||||
|
* |
||||
|
* @param string $gist |
||||
|
* @param string $body |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($gist, $body) |
||||
|
{ |
||||
|
return $this->post('/gists/'.rawurlencode($gist).'/comments', ['body' => $body]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a comment for a gist. |
||||
|
* |
||||
|
* @param string $gist |
||||
|
* @param int $comment_id |
||||
|
* @param string $body |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($gist, $comment_id, $body) |
||||
|
{ |
||||
|
return $this->patch('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment_id), ['body' => $body]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a comment for a gist. |
||||
|
* |
||||
|
* @param string $gist |
||||
|
* @param int $comment |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($gist, $comment) |
||||
|
{ |
||||
|
return $this->delete('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,116 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Api\Gist\Comments; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* Creating, editing, deleting and listing gists. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/gists/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
* @author Edoardo Rivello <edoardo.rivello at gmail dot com> |
||||
|
*/ |
||||
|
class Gists extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* Configure the body type. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/gists/#custom-media-types |
||||
|
* |
||||
|
* @param string|null $bodyType |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure($bodyType = null) |
||||
|
{ |
||||
|
if (!in_array($bodyType, ['base64'])) { |
||||
|
$bodyType = 'raw'; |
||||
|
} |
||||
|
|
||||
|
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s', $this->client->getApiVersion(), $bodyType); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
public function all($type = null) |
||||
|
{ |
||||
|
if (!in_array($type, ['public', 'starred'])) { |
||||
|
return $this->get('/gists'); |
||||
|
} |
||||
|
|
||||
|
return $this->get('/gists/'.rawurlencode($type)); |
||||
|
} |
||||
|
|
||||
|
public function show($number) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($number)); |
||||
|
} |
||||
|
|
||||
|
public function create(array $params) |
||||
|
{ |
||||
|
if (!isset($params['files']) || (!is_array($params['files']) || 0 === count($params['files']))) { |
||||
|
throw new MissingArgumentException('files'); |
||||
|
} |
||||
|
|
||||
|
$params['public'] = (bool) $params['public']; |
||||
|
|
||||
|
return $this->post('/gists', $params); |
||||
|
} |
||||
|
|
||||
|
public function update($id, array $params) |
||||
|
{ |
||||
|
return $this->patch('/gists/'.rawurlencode($id), $params); |
||||
|
} |
||||
|
|
||||
|
public function commits($id) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($id).'/commits'); |
||||
|
} |
||||
|
|
||||
|
public function fork($id) |
||||
|
{ |
||||
|
return $this->post('/gists/'.rawurlencode($id).'/fork'); |
||||
|
} |
||||
|
|
||||
|
public function forks($id) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($id).'/forks'); |
||||
|
} |
||||
|
|
||||
|
public function remove($id) |
||||
|
{ |
||||
|
return $this->delete('/gists/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
public function check($id) |
||||
|
{ |
||||
|
return $this->get('/gists/'.rawurlencode($id).'/star'); |
||||
|
} |
||||
|
|
||||
|
public function star($id) |
||||
|
{ |
||||
|
return $this->put('/gists/'.rawurlencode($id).'/star'); |
||||
|
} |
||||
|
|
||||
|
public function unstar($id) |
||||
|
{ |
||||
|
return $this->delete('/gists/'.rawurlencode($id).'/star'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a gist's comments. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/gists/comments/ |
||||
|
* |
||||
|
* @return Comments |
||||
|
*/ |
||||
|
public function comments() |
||||
|
{ |
||||
|
return new Comments($this->client); |
||||
|
} |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Api\GitData\Blobs; |
||||
|
use Github\Api\GitData\Commits; |
||||
|
use Github\Api\GitData\References; |
||||
|
use Github\Api\GitData\Tags; |
||||
|
use Github\Api\GitData\Trees; |
||||
|
|
||||
|
/** |
||||
|
* Getting full versions of specific files and trees in your Git repositories. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/git/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class GitData extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* @return Blobs |
||||
|
*/ |
||||
|
public function blobs() |
||||
|
{ |
||||
|
return new Blobs($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Commits |
||||
|
*/ |
||||
|
public function commits() |
||||
|
{ |
||||
|
return new Commits($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return References |
||||
|
*/ |
||||
|
public function references() |
||||
|
{ |
||||
|
return new References($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Tags |
||||
|
*/ |
||||
|
public function tags() |
||||
|
{ |
||||
|
return new Tags($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Trees |
||||
|
*/ |
||||
|
public function trees() |
||||
|
{ |
||||
|
return new Trees($this->client); |
||||
|
} |
||||
|
} |
@ -0,0 +1,70 @@ |
|||||
|
<?php |
||||
|
|
||||
|
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 Accept header depending on the blob type. |
||||
|
* |
||||
|
* @param string|null $bodyType |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure($bodyType = null) |
||||
|
{ |
||||
|
if ('raw' === $bodyType) { |
||||
|
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.raw', $this->client->getApiVersion()); |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Show a blob of a sha for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $sha |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $sha) |
||||
|
{ |
||||
|
$response = $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/blobs/'.rawurlencode($sha)); |
||||
|
|
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a blob of a sha for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['content'], $params['encoding'])) { |
||||
|
throw new MissingArgumentException(['content', 'encoding']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/blobs', $params); |
||||
|
} |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\GitData; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/git/commits/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Commits extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Show a commit for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $sha |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $sha) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/commits/'.rawurlencode($sha)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a commit for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['message'], $params['tree'], $params['parents'])) { |
||||
|
throw new MissingArgumentException(['message', 'tree', 'parents']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/commits', $params); |
||||
|
} |
||||
|
} |
@ -0,0 +1,140 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\GitData; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/git/references/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class References extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get all references of a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all branches of a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function branches($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/heads'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all tags of a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function tags($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/tags'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Show the reference of a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $reference |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $reference) |
||||
|
{ |
||||
|
$reference = $this->encodeReference($reference); |
||||
|
|
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/'.$reference); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a reference for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['ref'], $params['sha'])) { |
||||
|
throw new MissingArgumentException(['ref', 'sha']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update a reference for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $reference |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($username, $repository, $reference, array $params) |
||||
|
{ |
||||
|
if (!isset($params['sha'])) { |
||||
|
throw new MissingArgumentException('sha'); |
||||
|
} |
||||
|
|
||||
|
$reference = $this->encodeReference($reference); |
||||
|
|
||||
|
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/'.$reference, $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a reference of a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $reference |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($username, $repository, $reference) |
||||
|
{ |
||||
|
$reference = $this->encodeReference($reference); |
||||
|
|
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/'.$reference); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Encode the raw reference. |
||||
|
* |
||||
|
* @param string $rawReference |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
private function encodeReference($rawReference) |
||||
|
{ |
||||
|
return implode('/', array_map('rawurlencode', explode('/', $rawReference))); |
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\GitData; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/git/tags/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Tags extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get all tags for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs/tags'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a tag for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $sha |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $sha) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/tags/'.rawurlencode($sha)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a tag for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['tag'], $params['message'], $params['object'], $params['type'])) { |
||||
|
throw new MissingArgumentException(['tag', 'message', 'object', 'type']); |
||||
|
} |
||||
|
|
||||
|
if (!isset($params['tagger'])) { |
||||
|
throw new MissingArgumentException('tagger'); |
||||
|
} |
||||
|
|
||||
|
if (!isset($params['tagger']['name'], $params['tagger']['email'], $params['tagger']['date'])) { |
||||
|
throw new MissingArgumentException(['tagger.name', 'tagger.email', 'tagger.date']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/tags', $params); |
||||
|
} |
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\GitData; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/git/trees/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Trees extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get the tree for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $sha |
||||
|
* @param bool $recursive |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $sha, $recursive = false) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/trees/'.rawurlencode($sha), $recursive ? ['recursive' => 1] : []); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create tree for a repository. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['tree']) || !is_array($params['tree'])) { |
||||
|
throw new MissingArgumentException('tree'); |
||||
|
} |
||||
|
|
||||
|
if (!isset($params['tree'][0])) { |
||||
|
$params['tree'] = [$params['tree']]; |
||||
|
} |
||||
|
|
||||
|
foreach ($params['tree'] as $key => $tree) { |
||||
|
if (!isset($tree['path'], $tree['mode'], $tree['type'])) { |
||||
|
throw new MissingArgumentException(["tree.$key.path", "tree.$key.mode", "tree.$key.type"]); |
||||
|
} |
||||
|
|
||||
|
// If `sha` is not set, `content` is required |
||||
|
if (!isset($tree['sha']) && !isset($tree['content'])) { |
||||
|
throw new MissingArgumentException("tree.$key.content"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/trees', $params); |
||||
|
} |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* GraphQL API. |
||||
|
* |
||||
|
* Part of the Github v4 API |
||||
|
* |
||||
|
* @link https://developer.github.com/v4/ |
||||
|
* |
||||
|
* @author Miguel Piedrafita <soy@miguelpiedrafita.com> |
||||
|
*/ |
||||
|
class GraphQL extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* @param string $query |
||||
|
* @param array $variables |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function execute($query, array $variables = []) |
||||
|
{ |
||||
|
$this->acceptHeaderValue = 'application/vnd.github.v4+json'; |
||||
|
$params = [ |
||||
|
'query' => $query, |
||||
|
]; |
||||
|
if (!empty($variables)) { |
||||
|
$params['variables'] = json_encode($variables); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/graphql', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $file |
||||
|
* @param array $variables |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function fromFile($file, array $variables = []) |
||||
|
{ |
||||
|
return $this->execute(file_get_contents($file), $variables); |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
@trigger_error('The '.__NAMESPACE__.'\Integrations class is deprecated. Use the '.__NAMESPACE__.'\Apps class instead.', E_USER_DEPRECATED); |
||||
|
|
||||
|
/** |
||||
|
* @deprecated Use the Apps class |
||||
|
* @link https://developer.github.com/v3/apps/ |
||||
|
* |
||||
|
* @author Nils Adermann <naderman@naderman.de> |
||||
|
*/ |
||||
|
class Integrations extends Apps |
||||
|
{ |
||||
|
/** |
||||
|
* @deprecated |
||||
|
* Configure the accept header for Early Access to the integrations api (DEPRECATED) |
||||
|
* @see https://developer.github.com/v3/apps/ |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure() |
||||
|
{ |
||||
|
return $this; |
||||
|
} |
||||
|
} |
@ -0,0 +1,263 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
use Github\Api\Issue\Assignees; |
||||
|
use Github\Api\Issue\Comments; |
||||
|
use Github\Api\Issue\Events; |
||||
|
use Github\Api\Issue\Labels; |
||||
|
use Github\Api\Issue\Milestones; |
||||
|
use Github\Api\Issue\Timeline; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* Listing issues, searching, editing and closing your projects issues. |
||||
|
* |
||||
|
* @link http://develop.github.com/p/issues.html |
||||
|
* |
||||
|
* @author Thibault Duplessis <thibault.duplessis at gmail dot com> |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Issue extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* Configure the body type. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/#custom-media-types |
||||
|
* |
||||
|
* @param string|null $bodyType |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure($bodyType = null) |
||||
|
{ |
||||
|
if (!in_array($bodyType, ['text', 'html', 'full'])) { |
||||
|
$bodyType = 'raw'; |
||||
|
} |
||||
|
|
||||
|
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List issues by username, repo and state. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/ |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param array $params the additional parameters like milestone, assignees, labels, sort, direction |
||||
|
* |
||||
|
* @return array list of issues found |
||||
|
*/ |
||||
|
public function all($username, $repository, array $params = []) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues', array_merge(['page' => 1], $params)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Search issues by username, repo, state and keyword. |
||||
|
* |
||||
|
* @deprecated This method is deprecated use the Search api instead. See https://developer.github.com/v3/search/legacy/#legacy-search-api-is-deprecated |
||||
|
* @link http://developer.github.com/v3/search/#search-issues |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param string $state the issue state, can be open or closed |
||||
|
* @param string $keyword the keyword to filter issues by |
||||
|
* |
||||
|
* @return array list of issues found |
||||
|
*/ |
||||
|
public function find($username, $repository, $state, $keyword) |
||||
|
{ |
||||
|
if (!in_array($state, ['open', 'closed'])) { |
||||
|
$state = 'open'; |
||||
|
} |
||||
|
|
||||
|
return $this->get('/legacy/issues/search/'.rawurlencode($username).'/'.rawurlencode($repository).'/'.rawurlencode($state).'/'.rawurlencode($keyword)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List issues by organization. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/ |
||||
|
* |
||||
|
* @param string $organization the organization |
||||
|
* @param string $state the issue state, can be open or closed |
||||
|
* @param array $params the additional parameters like milestone, assignees, labels, sort, direction |
||||
|
* |
||||
|
* @return array list of issues found |
||||
|
*/ |
||||
|
public function org($organization, $state, array $params = []) |
||||
|
{ |
||||
|
if (!in_array($state, ['open', 'closed'])) { |
||||
|
$state = 'open'; |
||||
|
} |
||||
|
|
||||
|
return $this->get('/orgs/'.rawurlencode($organization).'/issues', array_merge(['page' => 1, 'state' => $state], $params)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get extended information about an issue by its username, repo and number. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/ |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param int $id the issue number |
||||
|
* |
||||
|
* @return array information about the issue |
||||
|
*/ |
||||
|
public function show($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a new issue for the given username and repo. |
||||
|
* The issue is assigned to the authenticated user. Requires authentication. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/ |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param array $params the new issue data |
||||
|
* |
||||
|
* @throws MissingArgumentException |
||||
|
* |
||||
|
* @return array information about the issue |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['title'])) { |
||||
|
throw new MissingArgumentException(['title']); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update issue information's by username, repo and issue number. Requires authentication. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/ |
||||
|
* |
||||
|
* @param string $username the username |
||||
|
* @param string $repository the repository |
||||
|
* @param int $id the issue number |
||||
|
* @param array $params key=>value user attributes to update. |
||||
|
* key can be title or body |
||||
|
* |
||||
|
* @return array information about the issue |
||||
|
*/ |
||||
|
public function update($username, $repository, $id, array $params) |
||||
|
{ |
||||
|
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Lock an issue. Users with push access can lock an issue's conversation. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/#lock-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function lock($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id).'/lock'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Unlock an issue. Users with push access can unlock an issue's conversation. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/#lock-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function unlock($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id).'/lock'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List an issue comments. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/comments/ |
||||
|
* |
||||
|
* @return Comments |
||||
|
*/ |
||||
|
public function comments() |
||||
|
{ |
||||
|
return new Comments($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all project events. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/events/ |
||||
|
* |
||||
|
* @return Events |
||||
|
*/ |
||||
|
public function events() |
||||
|
{ |
||||
|
return new Events($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all project labels. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/labels/ |
||||
|
* |
||||
|
* @return Labels |
||||
|
*/ |
||||
|
public function labels() |
||||
|
{ |
||||
|
return new Labels($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all project milestones. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/issues/milestones/ |
||||
|
* |
||||
|
* @return Milestones |
||||
|
*/ |
||||
|
public function milestones() |
||||
|
{ |
||||
|
return new Milestones($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all assignees. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/assignees/ |
||||
|
* |
||||
|
* @return Assignees |
||||
|
*/ |
||||
|
public function assignees() |
||||
|
{ |
||||
|
return new Assignees($this->client); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all events. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/timeline/ |
||||
|
* |
||||
|
* @return Timeline |
||||
|
*/ |
||||
|
public function timeline() |
||||
|
{ |
||||
|
return new Timeline($this->client); |
||||
|
} |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
class Assignees extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* List all the available assignees to which issues may be assigned. |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $parameters |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function listAvailable($username, $repository, array $parameters = []) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/assignees', $parameters); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check to see if a particular user is an assignee for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/assignees/#check-assignee |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $assignee |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function check($username, $repository, $assignee) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/assignees/'.rawurlencode($assignee)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Add assignees to an Issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $issue |
||||
|
* @param array $parameters |
||||
|
* |
||||
|
* @throws MissingArgumentException |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function add($username, $repository, $issue, array $parameters) |
||||
|
{ |
||||
|
if (!isset($parameters['assignees'])) { |
||||
|
throw new MissingArgumentException('assignees'); |
||||
|
} |
||||
|
|
||||
|
if (!is_array($parameters['assignees'])) { |
||||
|
@trigger_error(sprintf('Passing the "assignees" parameter as a string in "%s" is deprecated and will throw an exception in php-github-api version 3.0. Pass an array of strings instead', __METHOD__), E_USER_DEPRECATED); |
||||
|
|
||||
|
$parameters['assignees'] = [$parameters['assignees']]; |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/assignees', $parameters); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove assignees from an Issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $issue |
||||
|
* @param array $parameters |
||||
|
* |
||||
|
* @throws MissingArgumentException |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function remove($username, $repository, $issue, array $parameters) |
||||
|
{ |
||||
|
if (!isset($parameters['assignees'])) { |
||||
|
throw new MissingArgumentException('assignees'); |
||||
|
} |
||||
|
|
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/assignees', $parameters); |
||||
|
} |
||||
|
} |
@ -0,0 +1,135 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Api\AcceptHeaderTrait; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/issues/comments/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
* @author Tobias Nyholm <tobias.nyholm@gmail.com> |
||||
|
*/ |
||||
|
class Comments extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
/** |
||||
|
* Configure the body type. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#custom-media-types |
||||
|
* |
||||
|
* @param string|null $bodyType |
||||
|
* |
||||
|
* @return self |
||||
|
*/ |
||||
|
public function configure($bodyType = null) |
||||
|
{ |
||||
|
if (!in_array($bodyType, ['raw', 'text', 'html'])) { |
||||
|
$bodyType = 'full'; |
||||
|
} |
||||
|
|
||||
|
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all comments for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $issue |
||||
|
* @param int $page |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository, $issue, $page = 1) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/comments', [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a comment for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#get-a-single-comment |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $comment |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $comment) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a comment for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#create-a-comment |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $issue |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, $issue, array $params) |
||||
|
{ |
||||
|
if (!isset($params['body'])) { |
||||
|
throw new MissingArgumentException('body'); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/comments', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update a comment for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#edit-a-comment |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $comment |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($username, $repository, $comment, array $params) |
||||
|
{ |
||||
|
if (!isset($params['body'])) { |
||||
|
throw new MissingArgumentException('body'); |
||||
|
} |
||||
|
|
||||
|
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a comment for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/comments/#delete-a-comment |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $comment |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function remove($username, $repository, $comment) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/issues/events/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Events extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get all events for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/events/#list-events-for-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int|null $issue |
||||
|
* @param int $page |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository, $issue = null, $page = 1) |
||||
|
{ |
||||
|
if (null !== $issue) { |
||||
|
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/events'; |
||||
|
} else { |
||||
|
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/events'; |
||||
|
} |
||||
|
|
||||
|
return $this->get($path, [ |
||||
|
'page' => $page, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Display an event for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/events/#get-a-single-event |
||||
|
* |
||||
|
* @param $username |
||||
|
* @param $repository |
||||
|
* @param $event |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $event) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/events/'.rawurlencode($event)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,192 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\InvalidArgumentException; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/issues/labels/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Labels extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get all labels for a repository or the labels for a specific issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int|null $issue |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository, $issue = null) |
||||
|
{ |
||||
|
if ($issue === null) { |
||||
|
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels'; |
||||
|
} else { |
||||
|
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels'; |
||||
|
} |
||||
|
|
||||
|
return $this->get($path); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a single label. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#get-a-single-label |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $label |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $label) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels/'.rawurlencode($label)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a label for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#create-a-label |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['name'])) { |
||||
|
throw new MissingArgumentException('name'); |
||||
|
} |
||||
|
if (!isset($params['color'])) { |
||||
|
$params['color'] = 'FFFFFF'; |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a label for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $label |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function deleteLabel($username, $repository, $label) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels/'.rawurlencode($label)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Edit a label for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#update-a-label |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $label |
||||
|
* @param string $newName |
||||
|
* @param string $color |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($username, $repository, $label, $newName, $color) |
||||
|
{ |
||||
|
$params = [ |
||||
|
'name' => $newName, |
||||
|
'color' => $color, |
||||
|
]; |
||||
|
|
||||
|
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels/'.rawurlencode($label), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Add a label to an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $issue |
||||
|
* @param string $labels |
||||
|
* |
||||
|
* @return array |
||||
|
* |
||||
|
* @thorws \Github\Exception\InvalidArgumentException |
||||
|
*/ |
||||
|
public function add($username, $repository, $issue, $labels) |
||||
|
{ |
||||
|
if (is_string($labels)) { |
||||
|
$labels = [$labels]; |
||||
|
} elseif (0 === count($labels)) { |
||||
|
throw new InvalidArgumentException(); |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels', $labels); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Replace labels for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $issue |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function replace($username, $repository, $issue, array $params) |
||||
|
{ |
||||
|
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove a label for an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $issue |
||||
|
* @param string $label |
||||
|
* |
||||
|
* @return null |
||||
|
*/ |
||||
|
public function remove($username, $repository, $issue, $label) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels/'.rawurlencode($label)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Remove all labels from an issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param string $issue |
||||
|
* |
||||
|
* @return null |
||||
|
*/ |
||||
|
public function clear($username, $repository, $issue) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,139 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Exception\MissingArgumentException; |
||||
|
|
||||
|
/** |
||||
|
* @link http://developer.github.com/v3/issues/milestones/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Milestones extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get all milestones for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository, array $params = []) |
||||
|
{ |
||||
|
if (isset($params['state']) && !in_array($params['state'], ['open', 'closed', 'all'])) { |
||||
|
$params['state'] = 'open'; |
||||
|
} |
||||
|
if (isset($params['sort']) && !in_array($params['sort'], ['due_date', 'completeness'])) { |
||||
|
$params['sort'] = 'due_date'; |
||||
|
} |
||||
|
if (isset($params['direction']) && !in_array($params['direction'], ['asc', 'desc'])) { |
||||
|
$params['direction'] = 'asc'; |
||||
|
} |
||||
|
|
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones', array_merge([ |
||||
|
'page' => 1, |
||||
|
'state' => 'open', |
||||
|
'sort' => 'due_date', |
||||
|
'direction' => 'asc', |
||||
|
], $params)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a milestone for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/milestones/#get-a-single-milestone |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create a milestone for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/milestones/#create-a-milestone |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @throws \Github\Exception\MissingArgumentException |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function create($username, $repository, array $params) |
||||
|
{ |
||||
|
if (!isset($params['title'])) { |
||||
|
throw new MissingArgumentException('title'); |
||||
|
} |
||||
|
if (isset($params['state']) && !in_array($params['state'], ['open', 'closed'])) { |
||||
|
$params['state'] = 'open'; |
||||
|
} |
||||
|
|
||||
|
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Update a milestone for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/milestones/#update-a-milestone |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* @param array $params |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function update($username, $repository, $id, array $params) |
||||
|
{ |
||||
|
if (isset($params['state']) && !in_array($params['state'], ['open', 'closed'])) { |
||||
|
$params['state'] = 'open'; |
||||
|
} |
||||
|
|
||||
|
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id), $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Delete a milestone for a repository. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/milestones/#delete-a-milestone |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return null |
||||
|
*/ |
||||
|
public function remove($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the labels of a milestone. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function labels($username, $repository, $id) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id).'/labels'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Issue; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Api\AcceptHeaderTrait; |
||||
|
|
||||
|
class Timeline extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
public function configure() |
||||
|
{ |
||||
|
$this->acceptHeaderValue = 'application/vnd.github.mockingbird-preview'; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all events for a specific issue. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue |
||||
|
* |
||||
|
* @param string $username |
||||
|
* @param string $repository |
||||
|
* @param int $issue |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all($username, $repository, $issue) |
||||
|
{ |
||||
|
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/timeline'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* Markdown Rendering API. |
||||
|
* |
||||
|
* @link http://developer.github.com/v3/markdown/ |
||||
|
* |
||||
|
* @author Joseph Bielawski <stloyd@gmail.com> |
||||
|
*/ |
||||
|
class Markdown extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* @param string $text |
||||
|
* @param string $mode |
||||
|
* @param string $context |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function render($text, $mode = 'markdown', $context = null) |
||||
|
{ |
||||
|
if (!in_array($mode, ['gfm', 'markdown'])) { |
||||
|
$mode = 'markdown'; |
||||
|
} |
||||
|
|
||||
|
$params = [ |
||||
|
'text' => $text, |
||||
|
'mode' => $mode, |
||||
|
]; |
||||
|
if (null !== $context && 'gfm' === $mode) { |
||||
|
$params['context'] = $context; |
||||
|
} |
||||
|
|
||||
|
return $this->post('/markdown', $params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $file |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function renderRaw($file) |
||||
|
{ |
||||
|
return $this->post('/markdown/raw', [ |
||||
|
'file' => $file, |
||||
|
]); |
||||
|
} |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api; |
||||
|
|
||||
|
/** |
||||
|
* Getting GitHub service information. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/meta/ |
||||
|
* |
||||
|
* @author Claude Dioudonnat <claude.dioudonnat@gmail.com> |
||||
|
*/ |
||||
|
class Meta extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Get the ip address of the hook and git servers for the GitHub.com service. |
||||
|
* |
||||
|
* @return array Information about the service of GitHub.com |
||||
|
*/ |
||||
|
public function service() |
||||
|
{ |
||||
|
return $this->get('/meta'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Miscellaneous; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
use Github\Api\AcceptHeaderTrait; |
||||
|
|
||||
|
class CodeOfConduct extends AbstractApi |
||||
|
{ |
||||
|
use AcceptHeaderTrait; |
||||
|
|
||||
|
public function configure() |
||||
|
{ |
||||
|
$this->acceptHeaderValue = 'application/vnd.github.scarlet-witch-preview+json'; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* List all codes of conduct. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/codes_of_conduct/#list-all-codes-of-conduct |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/codes_of_conduct'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get an individual code of conduct. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/codes_of_conduct/#get-an-individual-code-of-conduct |
||||
|
* |
||||
|
* @param string $key |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function show($key) |
||||
|
{ |
||||
|
return $this->get('/codes_of_conduct/'.rawurlencode($key)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace Github\Api\Miscellaneous; |
||||
|
|
||||
|
use Github\Api\AbstractApi; |
||||
|
|
||||
|
class Emojis extends AbstractApi |
||||
|
{ |
||||
|
/** |
||||
|
* Lists all the emojis available to use on GitHub. |
||||
|
* |
||||
|
* @link https://developer.github.com/v3/emojis/ |
||||
|
* |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function all() |
||||
|
{ |
||||
|
return $this->get('/emojis'); |
||||
|
} |
||||
|
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue