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 |
|||
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: |
|||
Files: src/Composer/Util/TlsHelper.php |
|||
Copyright: 2016, Nils Adermann <naderman@naderman.de> |
|||
2016, Jordi Boggiano <j.boggiano@seld.be> |
|||
2013, Evan Coury <me@evancoury.com> |
|||
License: Expat and BSD-2-Clause |
|||
|
|||
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. |
|||
License: BSD-2-Clause |
|||
Redistribution and use in source and binary forms, with or without modification, |
|||
are permitted provided that the following conditions are met: |
|||
. |
|||
* Redistributions of source code must retain the above copyright notice, |
|||
this list of conditions and the following disclaimer. |
|||
. |
|||
* Redistributions in binary form must reproduce the above copyright notice, |
|||
this list of conditions and the following disclaimer in the documentation |
|||
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