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 [](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 | |||
| 
 | |||
| [](https://travis-ci.org/KnpLabs/php-github-api) | |||
| [](https://styleci.io/repos/3948501) | |||
| [](https://packagist.org/packages/knplabs/github-api) | |||
| [](https://packagist.org/packages/knplabs/github-api) | |||
| [](https://packagist.org/packages/knplabs/github-api) | |||
| [](https://packagist.org/packages/knplabs/github-api) | |||
| [](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 | |||
| 
 | |||
| [](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