Update to laravel 7

This commit is contained in:
KodeStar
2022-03-10 11:54:29 +00:00
parent 61a5a1a8b0
commit f9a19fce91
7170 changed files with 274189 additions and 283773 deletions

View File

@@ -1,13 +0,0 @@
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

View File

@@ -1,14 +0,0 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__);
$config = PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
])
->setFinder($finder)
;
return $config;

View File

@@ -1,5 +0,0 @@
preset: recommended
disabled:
- align_double_arrow
- no_multiline_whitespace_before_semicolons

View File

@@ -0,0 +1,114 @@
# Changelog
## 3.5.1
### Fixed
- Boolean private needed to create private repo! ([mruell](https://github.com/mruell)) [#1051](https://github.com/KnpLabs/php-github-api/issues/1051)
## 3.5.0
### Added
- added support for psr\cache 3.0 ([rconfig](https://github.com/rconfig)) [#1046](https://github.com/KnpLabs/php-github-api/issues/1046)
- Symfony: allow deprecation-contracts version 3 ([glaubinix](https://github.com/glaubinix)) [#1049](https://github.com/KnpLabs/php-github-api/issues/1049)
### Changed
- Fix internal doc link ([staudenmeir](https://github.com/staudenmeir)) [#1044](https://github.com/KnpLabs/php-github-api/issues/1044)
### Fixed
- Fix Client URL Prepending For GraphQL Endpoint on Enterprise ([asher-goldberg](https://github.com/asher-goldberg), [acrobat](https://github.com/acrobat)) [#1048](https://github.com/KnpLabs/php-github-api/issues/1048)
## 3.4.0
### Added
- Add create a repository using a template endpoint ([martinbean](https://github.com/martinbean)) [#994](https://github.com/KnpLabs/php-github-api/issues/994)
- Allow fetching repo readme for a specific ref ([bery](https://github.com/bery)) [#1019](https://github.com/KnpLabs/php-github-api/issues/1019)
- allow assigning role to organisation members ([luceos](https://github.com/luceos)) [#1018](https://github.com/KnpLabs/php-github-api/issues/1018)
- Branch lists . ( ? query per_page) ([pitonic](https://github.com/pitonic)) [#1020](https://github.com/KnpLabs/php-github-api/issues/1020)
- Php8.1 support ([acrobat](https://github.com/acrobat)) [#1025](https://github.com/KnpLabs/php-github-api/issues/1025)
- Allow psr/cache 2.0 as well as 1.0 ([johnnoel](https://github.com/johnnoel)) [#1029](https://github.com/KnpLabs/php-github-api/issues/1029)
- adding code_with_match (#1024) ([QuentinRa](https://github.com/QuentinRa)) [#1031](https://github.com/KnpLabs/php-github-api/issues/1031)
- Added dir parameter for Repo readme ([AlexandrePavy](https://github.com/AlexandrePavy)) [#1032](https://github.com/KnpLabs/php-github-api/issues/1032)
- refs #955: deprecate Client::AUTH_* constants and replace them with AuthMethod::AUTH_* const ([ipalo](https://github.com/ipalo)) [#1036](https://github.com/KnpLabs/php-github-api/issues/1036)
- feat: Add `visibility` option to repo create ([gerdemann](https://github.com/gerdemann)) [#1038](https://github.com/KnpLabs/php-github-api/issues/1038)
- Feature get authenticated app ([kdaniel95](https://github.com/kdaniel95)) [#1041](https://github.com/KnpLabs/php-github-api/issues/1041)
### Changed
- Fix up typos ([dereuromark](https://github.com/dereuromark)) [#1011](https://github.com/KnpLabs/php-github-api/issues/1011)
- Update integration authentication documentation for usage with lcobucci/jwt ^4 ([glaubinix](https://github.com/glaubinix)) [#1017](https://github.com/KnpLabs/php-github-api/issues/1017)
- Update result_pager.md ([tomsowerby](https://github.com/tomsowerby)) [#1023](https://github.com/KnpLabs/php-github-api/issues/1023)
- fix(doc): links to doc in CurrentUser class ([Nek-](https://github.com/Nek-)) [#1026](https://github.com/KnpLabs/php-github-api/issues/1026)
- Fix incorrect phpdoc ([gemal](https://github.com/gemal)) [#1034](https://github.com/KnpLabs/php-github-api/issues/1034)
### Fixed
- Add accept header for creating repo from template ([davidpeach](https://github.com/davidpeach)) [#1030](https://github.com/KnpLabs/php-github-api/issues/1030)
## 3.3.0
### Added
- Allow costume accept headers for GraphQL Endpoint. ([Necmttn](https://github.com/Necmttn)) [#1001](https://github.com/KnpLabs/php-github-api/issues/1001)
- Add endpoint for approve workflow run ([Nyholm](https://github.com/Nyholm)) [#1006](https://github.com/KnpLabs/php-github-api/issues/1006)
### Changed
- Update readme and add example for different http client usage ([acrobat](https://github.com/acrobat)) [#1002](https://github.com/KnpLabs/php-github-api/issues/1002)
- Bumped branch alias after new feature merged ([GrahamCampbell](https://github.com/GrahamCampbell)) [#1004](https://github.com/KnpLabs/php-github-api/issues/1004)
- Add comment on AbstractApi::$perPage() ([Nyholm](https://github.com/Nyholm)) [#1007](https://github.com/KnpLabs/php-github-api/issues/1007)
### Fixed
- Fix publicKey ([Yurunsoft](https://github.com/Yurunsoft)) [#1005](https://github.com/KnpLabs/php-github-api/issues/1005)
## 3.2.0
### Added
- Deprecate ResultPager::postFetch method ([acrobat](https://github.com/acrobat)) [#986](https://github.com/KnpLabs/php-github-api/issues/986)
- Add deprecations to the PR review methods to allow cleanup ([acrobat](https://github.com/acrobat)) [#984](https://github.com/KnpLabs/php-github-api/issues/984)
- Allow binary content downloads of assets ([acrobat](https://github.com/acrobat)) [#990](https://github.com/KnpLabs/php-github-api/issues/990)
- Deployments: added missing 'delete deployment' endpoint ([clxmstaab](https://github.com/clxmstaab)) [#991](https://github.com/KnpLabs/php-github-api/issues/991)
- Events list per authenticated user for all repos ([richard015ar](https://github.com/richard015ar)) [#1000](https://github.com/KnpLabs/php-github-api/issues/1000)
### Changed
- Fixed branch alias ([GrahamCampbell](https://github.com/GrahamCampbell)) [#975](https://github.com/KnpLabs/php-github-api/issues/975)
- fix typo ([staabm](https://github.com/staabm)) [#977](https://github.com/KnpLabs/php-github-api/issues/977)
- Improved bc check ([acrobat](https://github.com/acrobat)) [#982](https://github.com/KnpLabs/php-github-api/issues/982)
- Correctly link to github actions docs and fix backlinks ([acrobat](https://github.com/acrobat)) [#983](https://github.com/KnpLabs/php-github-api/issues/983)
- Add missing repo hooks documentation ([acrobat](https://github.com/acrobat)) [#987](https://github.com/KnpLabs/php-github-api/issues/987)
- Fix incorrect public key documentation ([acrobat](https://github.com/acrobat)) [#988](https://github.com/KnpLabs/php-github-api/issues/988)
- Fixed incorrect parameters in apps docs ([acrobat](https://github.com/acrobat)) [#989](https://github.com/KnpLabs/php-github-api/issues/989)
- phpdoc: fix typo ([clxmstaab](https://github.com/clxmstaab)) [#993](https://github.com/KnpLabs/php-github-api/issues/993)
- Fix upmerged usage of deprecated phpunit assert ([acrobat](https://github.com/acrobat)) [#995](https://github.com/KnpLabs/php-github-api/issues/995)
- Fix typo ([romainneutron](https://github.com/romainneutron)) [#997](https://github.com/KnpLabs/php-github-api/issues/997)
### Fixed
- Deployments: use proper media-type for in_progress/queued, inactive state ([staabm](https://github.com/staabm)) [#979](https://github.com/KnpLabs/php-github-api/issues/979)
- [952] doc - Specify lcobucci/jwt version, fix deprecation ([amacrobert-meq](https://github.com/amacrobert-meq), [acrobat](https://github.com/acrobat)) [#953](https://github.com/KnpLabs/php-github-api/issues/953)
- Replace deprecated organization team repository add/remove urls ([acrobat](https://github.com/acrobat)) [#985](https://github.com/KnpLabs/php-github-api/issues/985)
- fixed php warning in GithubExceptionThrower ([clxmstaab](https://github.com/clxmstaab), [acrobat](https://github.com/acrobat)) [#992](https://github.com/KnpLabs/php-github-api/issues/992)
## 3.1.0
### Added
- Add workflow dispatch and allow workflow names. ([fodinabor](https://github.com/fodinabor)) [#969](https://github.com/KnpLabs/php-github-api/issues/969)
### Changed
- Re-enable roave bc check for 3.x ([acrobat](https://github.com/acrobat)) [#958](https://github.com/KnpLabs/php-github-api/issues/958)
- Cleanup 3.0.0 changelog ([acrobat](https://github.com/acrobat)) [#957](https://github.com/KnpLabs/php-github-api/issues/957)
- Update new GitHub doc links in repo. ([fodinabor](https://github.com/fodinabor)) [#974](https://github.com/KnpLabs/php-github-api/issues/974)
### Fixed
- Add accept header for the checks API ([Agares](https://github.com/Agares)) [#968](https://github.com/KnpLabs/php-github-api/issues/968)
- ExceptionThrower: adjust rate limit detection ([glaubinix](https://github.com/glaubinix)) [#959](https://github.com/KnpLabs/php-github-api/issues/959)
## 3.0.0
### Added
- Switch to PSR18 client implementation and bump httplug minimum version to ^2.0 ([GrahamCampbell](https://github.com/GrahamCampbell)) [#885](https://github.com/KnpLabs/php-github-api/issues/885)
- Switch to PSR-17 and remove deprecated code ([GrahamCampbell](https://github.com/GrahamCampbell)) [#888](https://github.com/KnpLabs/php-github-api/issues/888)
- Allow PHP8 ([acrobat](https://github.com/acrobat)) [#934](https://github.com/KnpLabs/php-github-api/issues/934)
- [3.x] Make PHP 7.2.5 the minimum version ([GrahamCampbell](https://github.com/GrahamCampbell)) [#942](https://github.com/KnpLabs/php-github-api/issues/942)
- [3.x] Re-worked pagination to not mutate the api classes ([GrahamCampbell](https://github.com/GrahamCampbell)) [#907](https://github.com/KnpLabs/php-github-api/issues/907) & ([acrobat](https://github.com/acrobat)) [#956](https://github.com/KnpLabs/php-github-api/issues/956)
- Prepare 3.0 release and remove remaining deprecated code ([acrobat](https://github.com/acrobat)) [#948](https://github.com/KnpLabs/php-github-api/issues/948)
### Changed
- Remove BC check on 3.x ([GrahamCampbell](https://github.com/GrahamCampbell)) [#900](https://github.com/KnpLabs/php-github-api/issues/900)
- [3.x] Fix the HTTP methods client ([GrahamCampbell](https://github.com/GrahamCampbell)) [#910](https://github.com/KnpLabs/php-github-api/issues/910)
- fix typo ([michielkempen](https://github.com/michielkempen)) [#920](https://github.com/KnpLabs/php-github-api/issues/920)
- [3.x] Added some additional scalar types and return types ([GrahamCampbell](https://github.com/GrahamCampbell)) [#949](https://github.com/KnpLabs/php-github-api/issues/949)

View File

@@ -1,6 +1,173 @@
# Change Log
# Changelog
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
## 2.20.0
### Added
- Deployments: added missing 'delete deployment' endpoint ([clxmstaab](https://github.com/clxmstaab)) [#991](https://github.com/KnpLabs/php-github-api/issues/991)
### Changed
- phpdoc: fix typo ([clxmstaab](https://github.com/clxmstaab)) [#993](https://github.com/KnpLabs/php-github-api/issues/993)
### Fixed
- fixed php warning in GithubExceptionThrower ([clxmstaab](https://github.com/clxmstaab), [acrobat](https://github.com/acrobat)) [#992](https://github.com/KnpLabs/php-github-api/issues/992)
## 2.19.2
### Changed
- Improved bc check ([acrobat](https://github.com/acrobat)) [#982](https://github.com/KnpLabs/php-github-api/issues/982)
- Correctly link to github actions docs and fix backlinks ([acrobat](https://github.com/acrobat)) [#983](https://github.com/KnpLabs/php-github-api/issues/983)
- Add missing repo hooks documentation ([acrobat](https://github.com/acrobat)) [#987](https://github.com/KnpLabs/php-github-api/issues/987)
- Fix incorrect public key documentation ([acrobat](https://github.com/acrobat)) [#988](https://github.com/KnpLabs/php-github-api/issues/988)
- Fixed incorrect parameters in apps docs ([acrobat](https://github.com/acrobat)) [#989](https://github.com/KnpLabs/php-github-api/issues/989)
### Fixed
- Deployments: use proper media-type for in_progress/queued, inactive state ([staabm](https://github.com/staabm)) [#979](https://github.com/KnpLabs/php-github-api/issues/979)
- backported #979 into 2.x ([staabm](https://github.com/staabm)) [#981](https://github.com/KnpLabs/php-github-api/issues/981)
- [952] doc - Specify lcobucci/jwt version, fix deprecation ([amacrobert-meq](https://github.com/amacrobert-meq), [acrobat](https://github.com/acrobat)) [#953](https://github.com/KnpLabs/php-github-api/issues/953)
- Replace deprecated organization team repository add/remove urls ([acrobat](https://github.com/acrobat)) [#985](https://github.com/KnpLabs/php-github-api/issues/985)
## 2.19.1
### Fixed
- ExceptionThrower: adjust rate limit detection ([glaubinix](https://github.com/glaubinix)) [#959](https://github.com/KnpLabs/php-github-api/issues/959)
## 2.19.0
### Added
- Mark some classes as final ([acrobat](https://github.com/acrobat)) [#954](https://github.com/KnpLabs/php-github-api/issues/954)
## 2.18.0
### Added
- Add parameters to PullRequest commits method ([seanmtaylor](https://github.com/seanmtaylor)) [#938](https://github.com/KnpLabs/php-github-api/issues/938)
- Actions (#872) ([lexor](https://github.com/lexor)) [#939](https://github.com/KnpLabs/php-github-api/issues/939)
- automated security endpoints (#868) ([lexor](https://github.com/lexor)) [#944](https://github.com/KnpLabs/php-github-api/issues/944)
### Changed
- Update apps.md ([clarkeash](https://github.com/clarkeash)) [#936](https://github.com/KnpLabs/php-github-api/issues/936)
### Fixed
- Throw exception for graphql errors ([acrobat](https://github.com/acrobat)) [#941](https://github.com/KnpLabs/php-github-api/issues/941)
## 2.17.0
### Added
- Improve checks api implementation ([acrobat](https://github.com/acrobat)) [#932](https://github.com/KnpLabs/php-github-api/issues/932)
### Changed
- Missing auth method in list of omitted passwords. ([tobyS](https://github.com/tobyS)) [#933](https://github.com/KnpLabs/php-github-api/issues/933)
- Improve github actions setup ([acrobat](https://github.com/acrobat)) [#935](https://github.com/KnpLabs/php-github-api/issues/935)
## 2.16.0
### Added
- Add support for SSO errors coming from the API ([eiriksm](https://github.com/eiriksm)) [#913](https://github.com/KnpLabs/php-github-api/issues/913)
- Add OutsideCollaborators api ([Matth--](https://github.com/Matth--)) [#925](https://github.com/KnpLabs/php-github-api/issues/925)
- Add support for creating a repo dispatch event ([Nyholm](https://github.com/Nyholm)) [#931](https://github.com/KnpLabs/php-github-api/issues/931)
### Changed
- Fix: Wrong PHPDoc description ([OskarStark](https://github.com/OskarStark)) [#922](https://github.com/KnpLabs/php-github-api/issues/922)
- Adding GitHub authentication to GraphQL documentation ([legionth](https://github.com/legionth)) [#927](https://github.com/KnpLabs/php-github-api/issues/927)
### Fixed
- Use RFC3986 for building URI query strings ([GrahamCampbell](https://github.com/GrahamCampbell)) [#908](https://github.com/KnpLabs/php-github-api/issues/908)
- Fix call to test a webhook method ([morrislaptop](https://github.com/morrislaptop)) [#915](https://github.com/KnpLabs/php-github-api/issues/915)
## 2.15.0
### Added
- Prepare deprecation of authentication methods ([acrobat](https://github.com/acrobat)) [#870](https://github.com/KnpLabs/php-github-api/issues/870)
- Add Support For GitData Reference Matching Methods ([nickpoulos](https://github.com/nickpoulos)) [#875](https://github.com/KnpLabs/php-github-api/issues/875)
- Make invalid request error more clear ([acrobat](https://github.com/acrobat)) [#880](https://github.com/KnpLabs/php-github-api/issues/880)
- Show user by ID ([genintho](https://github.com/genintho)) [#894](https://github.com/KnpLabs/php-github-api/issues/894)
- add additional check run methods ([bobeagan](https://github.com/bobeagan), [acrobat](https://github.com/acrobat)) [#865](https://github.com/KnpLabs/php-github-api/issues/865)
### Changed
- Added phpstan ([clxkoders](https://github.com/clxkoders)) [#871](https://github.com/KnpLabs/php-github-api/issues/871)
- Increase phpstan to level 4 ([acrobat](https://github.com/acrobat)) [#874](https://github.com/KnpLabs/php-github-api/issues/874)
- [Documentation] Add Missing Children to Pull Request Index ([jimlind](https://github.com/jimlind)) [#877](https://github.com/KnpLabs/php-github-api/issues/877)
- [Documentation] Include links to Pull Request Children on Pull Request Doc. ([jimlind](https://github.com/jimlind)) [#878](https://github.com/KnpLabs/php-github-api/issues/878)
- Fix typo in /lib/Github/Api/RateLimit.php ([yoonper](https://github.com/yoonper)) [#886](https://github.com/KnpLabs/php-github-api/issues/886)
- Don't use deprecated auth in examples ([GrahamCampbell](https://github.com/GrahamCampbell)) [#892](https://github.com/KnpLabs/php-github-api/issues/892)
- Removed shadow-cat ([GrahamCampbell](https://github.com/GrahamCampbell)) [#893](https://github.com/KnpLabs/php-github-api/issues/893)
- Don't urlencode integer values ([acrobat](https://github.com/acrobat)) [#895](https://github.com/KnpLabs/php-github-api/issues/895)
- phpstan level 6 fixes ([acrobat](https://github.com/acrobat), [GrahamCampbell](https://github.com/GrahamCampbell)) [#897](https://github.com/KnpLabs/php-github-api/issues/897)
### Fixed
- fix: use new media type for branch protections ([iBotPeaches](https://github.com/iBotPeaches)) [#881](https://github.com/KnpLabs/php-github-api/issues/881)
- Added missing 'machine-man-preview' accept headers ([vovayatsyuk](https://github.com/vovayatsyuk)) [#883](https://github.com/KnpLabs/php-github-api/issues/883)
- Fix broken roave/bc-check test ([acrobat](https://github.com/acrobat)) [#890](https://github.com/KnpLabs/php-github-api/issues/890)
- Fixed incorrect MissingArgumentException parent constructor values ([acrobat](https://github.com/acrobat)) [#896](https://github.com/KnpLabs/php-github-api/issues/896)
- Added AUTH_ACCESS_TOKEN to allowed methods ([GrahamCampbell](https://github.com/GrahamCampbell)) [#899](https://github.com/KnpLabs/php-github-api/issues/899)
## 2.14.0
### Added
- Replace deprecated Organization\Teams api calls ([lolos](https://github.com/lolos)) [#860](https://github.com/KnpLabs/php-github-api/issues/860)
- Add sort and direction for fetching organizations repos ([pgrimaud](https://github.com/pgrimaud)) [#863](https://github.com/KnpLabs/php-github-api/issues/863)
- Added parameters to Repo/milestones() method ([dereuromark](https://github.com/dereuromark)) [#856](https://github.com/KnpLabs/php-github-api/issues/856)
### Fixed
- Remove incorrect MissingArgumentException in Labels api ([bobeagan](https://github.com/bobeagan)) [#861](https://github.com/KnpLabs/php-github-api/issues/861)
### Changed
- Fix typos in test/Github/Tests/Api/RepoTest.php ([pgrimaud](https://github.com/pgrimaud)) [#862](https://github.com/KnpLabs/php-github-api/issues/862)
- further detail on ResultPager parameters ([sepiariver](https://github.com/sepiariver)) [#843](https://github.com/KnpLabs/php-github-api/issues/843)
- fix phpdoc in labels api ([staabm](https://github.com/staabm)) [#854](https://github.com/KnpLabs/php-github-api/issues/854)
- fix api link in Issue\Labels::add() phpdoc ([staabm](https://github.com/staabm)) [#853](https://github.com/KnpLabs/php-github-api/issues/853)
## 2.13.0
### Added
- Support the new authorizations API
- Repo community profile API endpoint
- Support for draft PRs
- Missing Apps endpoints
- Test against php 7.4
### Changed
- Allow create & remove to set and remove requests for teams
## 2.12.1
### Fixed
- Fixed bug in handling of validation errors
- Updated docs to not use deprected string parameter in issue assignee call
## 2.12.0
### Added
- Support for HTTPlug 2.0 and PSR-18
- Add support for GitHub Checks
- Add support for GitHub Pages
- Add support to update a Pull Request Review
- Add support to get specific revision of a gist
- Added a 4th argument `$parameters` to `PullRequest::files()`
- Added `Accept` headers to Github Apps
### Removed
- Active support for HHVM
- Support for PHP <7.1
### Changed
- Allow tags to be created without the `Tagger` object
- When updating DeployKeys we will first remove existing then add a new DeployKey
### Fixed
- In `Trees` we should check if `array_key_exists('sha', $tree)` instead of `isset` to avoid issues with `null`. (#822)
### Deprecated
- Passing an integer (`$page`) as 4th arugment in `Comments::all()` is deprecated. It should be an array.
## 2.11.0

View File

@@ -1,10 +1,9 @@
# PHP GitHub API
[![Build Status](https://travis-ci.org/KnpLabs/php-github-api.svg?branch=master)](https://travis-ci.org/KnpLabs/php-github-api)
![Build Status](https://github.com/KnpLabs/php-github-api/actions/workflows/ci.yml/badge.svg)
[![StyleCI](https://styleci.io/repos/3948501/shield?style=flat)](https://styleci.io/repos/3948501)
[![Latest Stable Version](https://poser.pugx.org/knplabs/github-api/v/stable)](https://packagist.org/packages/knplabs/github-api)
[![Total Downloads](https://poser.pugx.org/knplabs/github-api/downloads)](https://packagist.org/packages/knplabs/github-api)
[![Latest Unstable Version](https://poser.pugx.org/knplabs/github-api/v/unstable)](https://packagist.org/packages/knplabs/github-api)
[![Monthly Downloads](https://poser.pugx.org/knplabs/github-api/d/monthly)](https://packagist.org/packages/knplabs/github-api)
[![Daily Downloads](https://poser.pugx.org/knplabs/github-api/d/daily)](https://packagist.org/packages/knplabs/github-api)
@@ -19,25 +18,46 @@ Uses [GitHub API v3](http://developer.github.com/v3/) & supports [GitHub API v4]
## 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.
* PHP >= 7.2
* A [PSR-17 implementation](https://packagist.org/providers/psr/http-factory-implementation)
* A [PSR-18 implementation](https://packagist.org/providers/psr/http-client-implementation)
## Install
## Quick install
Via Composer:
Via [Composer](https://getcomposer.org).
This command will get you up and running quickly with a Guzzle HTTP client.
```bash
$ composer require knplabs/github-api php-http/guzzle6-adapter "^1.1"
composer require knplabs/github-api:^3.0 guzzlehttp/guzzle:^7.0.1 http-interop/http-factory-guzzle:^1.0
```
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).
## Advanced install
We are decoupled from any HTTP messaging client with help by [HTTPlug](https://httplug.io).
## Using Laravel?
### Using a different http client
[Laravel GitHub](https://github.com/GrahamCampbell/Laravel-GitHub) by [Graham Campbell](https://github.com/GrahamCampbell) might interest you.
```bash
composer require knplabs/github-api:^3.0 symfony/http-client nyholm/psr7
```
To set up the Github client with this HTTP client
```php
use Github\Client;
use Symfony\Component\HttpClient\HttplugClient;
$client = Client::createWithHttpClient(new HttplugClient());
```
Read more about [using different clients in our docs](doc/customize.md).
## Framework integrations
### Laravel
To integrate this library in laravel [Graham Campbell](https://github.com/GrahamCampbell) created [graham-campbell/github](https://github.com/GrahamCampbell/Laravel-GitHub). See the [installation instructions](https://github.com/GrahamCampbell/Laravel-GitHub#installation) to get started in laravel.
## Basic usage of `php-github-api` client
@@ -51,7 +71,7 @@ $client = new \Github\Client();
$repositories = $client->api('user')->repositories('ornicar');
```
From `$client` object, you can access to all GitHub.
From `$client` object, you have access to all available GitHub api endpoints.
## Cache usage
@@ -91,21 +111,24 @@ See the [`doc` directory](doc/) for more detailed documentation.
`php-github-api` is licensed under the MIT License - see the LICENSE file for details
## Credits
## Maintainers
### Sponsored by
Please read [this post](https://knplabs.com/en/blog/news-for-our-foss-projects-maintenance) first.
[![KnpLabs Team](http://knplabs.com/front/images/knp-labs-logo.png)](http://knplabs.com)
This library is maintained by the following people (alphabetically sorted) :
- [@acrobat](https://github.com/acrobat)
- [@Nyholm](https://github.com/Nyholm)
### Contributors
## 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 [Thibault Duplessis aka. ornicar](https://github.com/ornicar) for his first version of this library.
- Thanks to [Joseph Bielawski aka. stloyd](https://github.com/stloyd) for his contributions and support.
- Thanks to [noloh](https://github.com/noloh) for his contribution on the Object API.
- Thanks to [bshaffer](https://github.com/bshaffer) for his contribution on the Repo API.
- Thanks to [Rolf van de Krol](https://github.com/rolfvandekrol) for his countless contributions.
- Thanks to [Nicolas Pastorino](https://github.com/jeanvoye) for his contribution on the Pull Request API.
- Thanks to [Edoardo Rivello](https://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 [Emre DEGER](https://github.com/lexor) for his contribution to the Actions API.
Thanks to GitHub for the high quality API and documentation.

View File

@@ -0,0 +1,21 @@
## UPGRADE from 2.x to 3.0
### General
* The `php-http/httplug` dependency requires is bumped to minimum ^2.1.
* A client implementing `psr/http-client-implementation` is required.
To upgrade your application (default install) switch from guzzle 6 to guzzle 7 (or replace `php-http/guzzle6-adapter` with any `psr/http-client-implementation`), see the install instructions in the [README file](README.md)
* All previous deprecated code in version 2 is removed.
* The following classes are now final
* `Github\HttpClient\Message\ResponseMediator`
* `Github\HttpClient\Plugin\Authentication`
* `Github\HttpClient\Plugin\GithubExceptionThrower`
* `Github\HttpClient\Plugin\History`
* `Github\HttpClient\Plugin\PathPrepend`
### Authentication methods
* `Github\Client::AUTH_URL_TOKEN` use `Github\Client::AUTH_ACCESS_TOKEN` instead.
* `Github\Client::AUTH_URL_CLIENT_ID` use `Github\Client::AUTH_CLIENT_ID` instead.
* `Github\Client::AUTH_HTTP_TOKEN` use `Github\Client::AUTH_ACCESS_TOKEN` instead.
* `Github\Client::AUTH_HTTP_PASSWORD` use `Github\Client::AUTH_ACCESS_TOKEN` instead.

View File

@@ -0,0 +1,11 @@
## UPGRADE from 3.x to 4.0
### ResultPager
* `\Github\ResultPagerInterface::postFetch` is deprecated, and the method will be removed from the ResultPager interface/class.
### Authentication methods
* `Github\Client::AUTH_CLIENT_ID` is deprecated, use `Github\AuthMethod::CLIENT_ID` instead.
* `Github\Client::AUTH_ACCESS_TOKEN` is deprecated, use `Github\AuthMethod::ACCESS_TOKEN` instead.
* `Github\Client::AUTH_JWT` is deprecated, use `Github\AuthMethod::JWT` instead.

View File

@@ -17,21 +17,31 @@
}
],
"require": {
"php": "^5.6 || ^7.0",
"php": "^7.2.5 || ^8.0",
"ext-json": "*",
"php-http/cache-plugin": "^1.7.1",
"php-http/client-common": "^2.3",
"php-http/discovery": "^1.12",
"php-http/httplug": "^2.2",
"php-http/multipart-stream-builder": "^1.1.2",
"psr/cache": "^1.0|^2.0|^3.0",
"psr/http-client-implementation": "^1.0",
"psr/http-factory-implementation": "^1.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"
"symfony/polyfill-php80": "^1.17",
"symfony/deprecation-contracts": "^2.2|^3.0"
},
"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"
"symfony/cache": "^5.1.8",
"guzzlehttp/psr7": "^1.7",
"http-interop/http-factory-guzzle": "^1.0",
"guzzlehttp/guzzle": "^7.2",
"php-http/mock-client": "^1.4.1",
"phpstan/phpstan": "^0.12.57",
"phpstan/extension-installer": "^1.0.5",
"phpstan/phpstan-deprecation-rules": "^0.12.5",
"phpunit/phpunit": "^8.5 || ^9.4",
"symfony/phpunit-bridge": "^5.2"
},
"autoload": {
"psr-4": { "Github\\": "lib/Github/" }
@@ -39,11 +49,15 @@
"autoload-dev": {
"psr-4": { "Github\\Tests\\": "test/Github/Tests/"}
},
"minimum-stability": "dev",
"prefer-stable": true,
"extra": {
"branch-alias": {
"dev-master": "2.11.x-dev"
"dev-2.x": "2.20.x-dev",
"dev-master": "3.4.x-dev"
}
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
}
}
}

View File

@@ -4,80 +4,65 @@ namespace Github\Api;
use Github\Client;
use Github\HttpClient\Message\ResponseMediator;
use Psr\Http\Message\ResponseInterface;
/**
* Abstract class for Api classes.
*
* @author Joseph Bielawski <stloyd@gmail.com>
* @author Graham Campbell <graham@alt-three.com>
*/
abstract class AbstractApi implements ApiInterface
abstract class AbstractApi
{
/**
* The client.
* The client instance.
*
* @var Client
*/
protected $client;
private $client;
/**
* The requested page (GitHub pagination).
* The per page parameter. It is used by the ResultPager.
*
* @var null|int
* @var int|null
*/
private $page;
private $perPage;
/**
* Number of items per page (GitHub pagination).
* Create a new API instance.
*
* @var null|int
*/
protected $perPage;
/**
* @param Client $client
*
* @return void
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* Get the client instance.
*
* @return Client
*/
protected function getClient(): Client
{
return $this->client;
}
/**
* Get the API version.
*
* @return string
*/
protected function getApiVersion(): string
{
return $this->client->getApiVersion();
}
/**
* @return $this
*/
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;
}
@@ -90,20 +75,18 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function get($path, array $parameters = [], array $requestHeaders = [])
protected function get(string $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) && null === $parameters['ref']) {
unset($parameters['ref']);
}
if (count($parameters) > 0) {
$path .= '?'.http_build_query($parameters);
$path .= '?'.http_build_query($parameters, '', '&', PHP_QUERY_RFC3986);
}
$response = $this->client->getHttpClient()->get($path, $requestHeaders);
@@ -118,17 +101,15 @@ abstract class AbstractApi implements ApiInterface
* @param array $parameters HEAD parameters.
* @param array $requestHeaders Request headers.
*
* @return \Psr\Http\Message\ResponseInterface
* @return ResponseInterface
*/
protected function head($path, array $parameters = [], array $requestHeaders = [])
protected function head(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
if (array_key_exists('ref', $parameters) && null === $parameters['ref']) {
unset($parameters['ref']);
}
$response = $this->client->getHttpClient()->head($path.'?'.http_build_query($parameters), $requestHeaders);
return $response;
return $this->client->getHttpClient()->head($path.'?'.http_build_query($parameters, '', '&', PHP_QUERY_RFC3986), $requestHeaders);
}
/**
@@ -140,7 +121,7 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function post($path, array $parameters = [], array $requestHeaders = [])
protected function post(string $path, array $parameters = [], array $requestHeaders = [])
{
return $this->postRaw(
$path,
@@ -158,7 +139,7 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function postRaw($path, $body, array $requestHeaders = [])
protected function postRaw(string $path, $body, array $requestHeaders = [])
{
$response = $this->client->getHttpClient()->post(
$path,
@@ -178,7 +159,7 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function patch($path, array $parameters = [], array $requestHeaders = [])
protected function patch(string $path, array $parameters = [], array $requestHeaders = [])
{
$response = $this->client->getHttpClient()->patch(
$path,
@@ -198,7 +179,7 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function put($path, array $parameters = [], array $requestHeaders = [])
protected function put(string $path, array $parameters = [], array $requestHeaders = [])
{
$response = $this->client->getHttpClient()->put(
$path,
@@ -218,7 +199,7 @@ abstract class AbstractApi implements ApiInterface
*
* @return array|string
*/
protected function delete($path, array $parameters = [], array $requestHeaders = [])
protected function delete(string $path, array $parameters = [], array $requestHeaders = [])
{
$response = $this->client->getHttpClient()->delete(
$path,
@@ -234,9 +215,9 @@ abstract class AbstractApi implements ApiInterface
*
* @param array $parameters Request parameters
*
* @return null|string
* @return string|null
*/
protected function createJsonBody(array $parameters)
protected function createJsonBody(array $parameters): ?string
{
return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0);
}

View File

@@ -2,6 +2,8 @@
namespace Github\Api;
use Psr\Http\Message\ResponseInterface;
/**
* A trait to make sure we add accept headers on all requests.
*
@@ -9,39 +11,40 @@ namespace Github\Api;
*/
trait AcceptHeaderTrait
{
/** @var string */
protected $acceptHeaderValue;
protected function get($path, array $parameters = [], array $requestHeaders = [])
protected function get(string $path, array $parameters = [], array $requestHeaders = [])
{
return parent::get($path, $parameters, $this->mergeHeaders($requestHeaders));
}
protected function head($path, array $parameters = [], array $requestHeaders = [])
protected function head(string $path, array $parameters = [], array $requestHeaders = []): ResponseInterface
{
return parent::head($path, $parameters, $this->mergeHeaders($requestHeaders));
}
protected function post($path, array $parameters = [], array $requestHeaders = [])
protected function post(string $path, array $parameters = [], array $requestHeaders = [])
{
return parent::post($path, $parameters, $this->mergeHeaders($requestHeaders));
}
protected function postRaw($path, $body, array $requestHeaders = [])
protected function postRaw(string $path, $body, array $requestHeaders = [])
{
return parent::postRaw($path, $body, $this->mergeHeaders($requestHeaders));
}
protected function patch($path, array $parameters = [], array $requestHeaders = [])
protected function patch(string $path, array $parameters = [], array $requestHeaders = [])
{
return parent::patch($path, $parameters, $this->mergeHeaders($requestHeaders));
}
protected function put($path, array $parameters = [], array $requestHeaders = [])
protected function put(string $path, array $parameters = [], array $requestHeaders = [])
{
return parent::put($path, $parameters, $this->mergeHeaders($requestHeaders));
}
protected function delete($path, array $parameters = [], array $requestHeaders = [])
protected function delete(string $path, array $parameters = [], array $requestHeaders = [])
{
return parent::delete($path, $parameters, $this->mergeHeaders($requestHeaders));
}
@@ -51,7 +54,7 @@ trait AcceptHeaderTrait
*
* @return array
*/
private function mergeHeaders(array $headers = [])
private function mergeHeaders(array $headers = []): array
{
$default = [];
if ($this->acceptHeaderValue) {

View File

@@ -1,15 +0,0 @@
<?php
namespace Github\Api;
/**
* Api interface.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
interface ApiInterface
{
public function getPerPage();
public function setPerPage($perPage);
}

View File

@@ -9,6 +9,13 @@ namespace Github\Api;
*/
class Apps extends AbstractApi
{
use AcceptHeaderTrait;
private function configurePreviewHeader()
{
$this->acceptHeaderValue = 'application/vnd.github.machine-man-preview+json';
}
/**
* Create an access token for an installation.
*
@@ -27,7 +34,9 @@ class Apps extends AbstractApi
$parameters['user_id'] = $userId;
}
return $this->post('/app/installations/'.rawurlencode($installationId).'/access_tokens', $parameters);
$this->configurePreviewHeader();
return $this->post('/app/installations/'.$installationId.'/access_tokens', $parameters);
}
/**
@@ -39,9 +48,90 @@ class Apps extends AbstractApi
*/
public function findInstallations()
{
$this->configurePreviewHeader();
return $this->get('/app/installations');
}
/**
* Get an installation of the application.
*
* @link https://developer.github.com/v3/apps/#get-an-installation
*
* @param int $installationId An integration installation id
*
* @return array
*/
public function getInstallation($installationId)
{
$this->configurePreviewHeader();
return $this->get('/app/installations/'.$installationId);
}
/**
* Get an installation of the application for an organization.
*
* @link https://developer.github.com/v3/apps/#get-an-organization-installation
*
* @param string $org An organization
*
* @return array
*/
public function getInstallationForOrganization($org)
{
$this->configurePreviewHeader();
return $this->get('/org/'.rawurldecode($org).'/installation');
}
/**
* Get an installation of the application for a repository.
*
* @link https://developer.github.com/v3/apps/#get-a-repository-installation
*
* @param string $owner the owner of a repository
* @param string $repo the name of the repository
*
* @return array
*/
public function getInstallationForRepo($owner, $repo)
{
$this->configurePreviewHeader();
return $this->get('/repos/'.rawurldecode($owner).'/'.rawurldecode($repo).'/installation');
}
/**
* Get an installation of the application for a user.
*
* @link https://developer.github.com/v3/apps/#get-a-user-installation
*
* @param string $username
*
* @return array
*/
public function getInstallationForUser($username)
{
$this->configurePreviewHeader();
return $this->get('/users/'.rawurldecode($username).'/installation');
}
/**
* Delete an installation of the application.
*
* @link https://developer.github.com/v3/apps/#delete-an-installation
*
* @param int $installationId An integration installation id
*/
public function removeInstallation($installationId)
{
$this->configurePreviewHeader();
$this->delete('/app/installations/'.$installationId);
}
/**
* List repositories that are accessible to the authenticated installation.
*
@@ -58,6 +148,8 @@ class Apps extends AbstractApi
$parameters['user_id'] = $userId;
}
$this->configurePreviewHeader();
return $this->get('/installation/repositories', $parameters);
}
@@ -73,7 +165,9 @@ class Apps extends AbstractApi
*/
public function addRepository($installationId, $repositoryId)
{
return $this->put('/installations/'.rawurlencode($installationId).'/repositories/'.rawurlencode($repositoryId));
$this->configurePreviewHeader();
return $this->put('/installations/'.$installationId.'/repositories/'.$repositoryId);
}
/**
@@ -88,6 +182,20 @@ class Apps extends AbstractApi
*/
public function removeRepository($installationId, $repositoryId)
{
return $this->delete('/installations/'.rawurlencode($installationId).'/repositories/'.rawurlencode($repositoryId));
$this->configurePreviewHeader();
return $this->delete('/installations/'.$installationId.'/repositories/'.$repositoryId);
}
/**
* Get the currently authenticated app.
*
* @link https://docs.github.com/en/rest/reference/apps#get-the-authenticated-app
*
* @return array
*/
public function getAuthenticatedApp()
{
return $this->get('/app');
}
}

View File

@@ -12,111 +12,54 @@ namespace Github\Api;
class Authorizations extends AbstractApi
{
/**
* List all authorizations.
* Check an application token.
*
* @param string $clientId
* @param string|null $token
*
* @return array
*/
public function all()
public function checkToken($clientId, $token = null)
{
return $this->get('/authorizations');
return $this->post('/applications/'.rawurlencode($clientId).'/token', $token ? ['access_token' => $token] : []);
}
/**
* Show a single authorization.
* Reset an application token.
*
* @param string $clientId
* @param string $clientId
* @param string|null $token
*
* @return array
*/
public function show($clientId)
public function resetToken($clientId, $token = null)
{
return $this->get('/authorizations/'.rawurlencode($clientId));
return $this->patch('/applications/'.rawurlencode($clientId).'/token', $token ? ['access_token' => $token] : []);
}
/**
* Create an authorization.
* Revoke an application token.
*
* @param array $params
* @param null $OTPCode
* @param string $clientId
* @param string|null $token
*
* @return array
* @return void
*/
public function create(array $params, $OTPCode = null)
public function deleteToken($clientId, $token = null)
{
$headers = null === $OTPCode ? [] : ['X-GitHub-OTP' => $OTPCode];
return $this->post('/authorizations', $params, $headers);
$this->delete('/applications/'.rawurlencode($clientId).'/token', $token ? ['access_token' => $token] : []);
}
/**
* Update an authorization.
* Revoke an application authorization.
*
* @param string $clientId
* @param array $params
* @param string $clientId
* @param string|null $token
*
* @return array
* @return void
*/
public function update($clientId, array $params)
public function deleteGrant($clientId, $token = null)
{
return $this->patch('/authorizations/'.rawurlencode($clientId), $params);
}
/**
* Remove an authorization.
*
* @param string $clientId
*
* @return array
*/
public function remove($clientId)
{
return $this->delete('/authorizations/'.rawurlencode($clientId));
}
/**
* Check an authorization.
*
* @param string $clientId
* @param string $token
*
* @return array
*/
public function check($clientId, $token)
{
return $this->get('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token));
}
/**
* Reset an authorization.
*
* @param string $clientId
* @param string $token
*
* @return array
*/
public function reset($clientId, $token)
{
return $this->post('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token));
}
/**
* Remove an authorization.
*
* @param string $clientId
* @param string $token
*/
public function revoke($clientId, $token)
{
$this->delete('/applications/'.rawurlencode($clientId).'/tokens/'.rawurlencode($token));
}
/**
* Revoke all authorizations.
*
* @param string $clientId
*/
public function revokeAll($clientId)
{
$this->delete('/applications/'.rawurlencode($clientId).'/tokens');
$this->delete('/applications/'.rawurlencode($clientId).'/grant', $token ? ['access_token' => $token] : []);
}
}

View File

@@ -18,6 +18,8 @@ use Github\Api\CurrentUser\Watchers;
*/
class CurrentUser extends AbstractApi
{
use AcceptHeaderTrait;
public function show()
{
return $this->get('/user');
@@ -33,7 +35,7 @@ class CurrentUser extends AbstractApi
*/
public function emails()
{
return new Emails($this->client);
return new Emails($this->getClient());
}
/**
@@ -41,7 +43,7 @@ class CurrentUser extends AbstractApi
*/
public function follow()
{
return new Followers($this->client);
return new Followers($this->getClient());
}
public function followers($page = 1)
@@ -52,7 +54,7 @@ class CurrentUser extends AbstractApi
}
/**
* @link http://developer.github.com/v3/issues/#list-issues
* @link https://docs.github.com/en/rest/reference/issues#list-user-account-issues-assigned-to-the-authenticated-user
*
* @param array $params
* @param bool $includeOrgIssues
@@ -69,7 +71,7 @@ class CurrentUser extends AbstractApi
*/
public function keys()
{
return new PublicKeys($this->client);
return new PublicKeys($this->getClient());
}
/**
@@ -77,7 +79,7 @@ class CurrentUser extends AbstractApi
*/
public function notifications()
{
return new Notifications($this->client);
return new Notifications($this->getClient());
}
/**
@@ -85,11 +87,11 @@ class CurrentUser extends AbstractApi
*/
public function memberships()
{
return new Memberships($this->client);
return new Memberships($this->getClient());
}
/**
* @link http://developer.github.com/v3/orgs/#list-user-organizations
* @link https://docs.github.com/en/rest/reference/orgs#list-organizations-for-the-authenticated-user
*
* @return array
*/
@@ -109,7 +111,7 @@ class CurrentUser extends AbstractApi
}
/**
* @link http://developer.github.com/v3/repos/#list-your-repositories
* @link https://docs.github.com/en/rest/reference/repos#list-repositories-for-the-authenticated-user
*
* @param string $type role in the repository
* @param string $sort sort by
@@ -145,17 +147,7 @@ class CurrentUser extends AbstractApi
*/
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 new Watchers($this->getClient());
}
/**
@@ -163,21 +155,11 @@ class CurrentUser extends AbstractApi
*/
public function starring()
{
return new Starring($this->client);
return new Starring($this->getClient());
}
/**
* @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
* @link https://docs.github.com/en/rest/reference/activity#list-repositories-watched-by-the-authenticated-user
*/
public function subscriptions()
{
@@ -185,23 +167,27 @@ class CurrentUser extends AbstractApi
}
/**
* @link https://developer.github.com/v3/integrations/#list-installations-for-user
* @link https://docs.github.com/en/rest/reference/apps#list-app-installations-accessible-to-the-user-access-token
*
* @param array $params
*/
public function installations(array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.machine-man-preview+json';
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
* @link https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-access-token
*
* @param string $installationId the ID of the Installation
* @param array $params
*/
public function repositoriesByInstallation($installationId, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.machine-man-preview+json';
return $this->get(sprintf('/user/installations/%s/repositories', $installationId), array_merge(['page' => 1], $params));
}
}

View File

@@ -83,7 +83,7 @@ class Notifications extends AbstractApi
*/
public function markAsRead($id, array $params)
{
return $this->patch('/notifications/threads/'.rawurlencode($id), $params);
return $this->patch('/notifications/threads/'.$id, $params);
}
/**
@@ -97,7 +97,7 @@ class Notifications extends AbstractApi
*/
public function show($id)
{
return $this->get('/notifications/threads/'.rawurlencode($id));
return $this->get('/notifications/threads/'.$id);
}
/**
@@ -111,7 +111,7 @@ class Notifications extends AbstractApi
*/
public function showSubscription($id)
{
return $this->get('/notifications/threads/'.rawurlencode($id).'/subscription');
return $this->get('/notifications/threads/'.$id.'/subscription');
}
/**
@@ -126,7 +126,7 @@ class Notifications extends AbstractApi
*/
public function createSubscription($id, array $params)
{
return $this->put('/notifications/threads/'.rawurlencode($id).'/subscription', $params);
return $this->put('/notifications/threads/'.$id.'/subscription', $params);
}
/**
@@ -140,6 +140,6 @@ class Notifications extends AbstractApi
*/
public function removeSubscription($id)
{
return $this->delete('/notifications/threads/'.rawurlencode($id).'/subscription');
return $this->delete('/notifications/threads/'.$id.'/subscription');
}
}

View File

@@ -35,7 +35,7 @@ class PublicKeys extends AbstractApi
*/
public function show($id)
{
return $this->get('/user/keys/'.rawurlencode($id));
return $this->get('/user/keys/'.$id);
}
/**
@@ -69,6 +69,6 @@ class PublicKeys extends AbstractApi
*/
public function remove($id)
{
return $this->delete('/user/keys/'.rawurlencode($id));
return $this->delete('/user/keys/'.$id);
}
}

View File

@@ -21,12 +21,12 @@ class Starring extends AbstractApi
*
* @param string $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
if ('star' === $bodyType) {
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.star+json', $this->client->getApiVersion());
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.star+json', $this->getApiVersion());
}
return $this;

View File

@@ -11,6 +11,8 @@ use Github\Exception\MissingArgumentException;
*/
class Deployment extends AbstractApi
{
use AcceptHeaderTrait;
/**
* List deployments for a particular repository.
*
@@ -38,7 +40,7 @@ class Deployment extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.$id);
}
/**
@@ -66,6 +68,21 @@ class Deployment extends AbstractApi
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments', $params);
}
/**
* Delete a deployment for the given username and repo.
*
* @link https://docs.github.com/en/rest/reference/repos#delete-a-deployment
*
* Important: Deployments can only be deleted when in inactive state
* @see updateStatus
*
* @return mixed null on success, array on error with 'message'
*/
public function remove(string $username, string $repository, int $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.$id);
}
/**
* Updates a deployment by creating a new status update.
*
@@ -76,7 +93,7 @@ class Deployment extends AbstractApi
* @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.
* May also be given a target_url and description, see link for more details.
*
* @throws MissingArgumentException
*
@@ -88,7 +105,16 @@ class Deployment extends AbstractApi
throw new MissingArgumentException(['state']);
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id).'/statuses', $params);
// adjust media-type per github docs
// https://docs.github.com/en/rest/reference/repos#create-a-deployment-status
if ($params['state'] === 'inactive') {
$this->acceptHeaderValue = 'application/vnd.github.ant-man-preview+json';
}
if ($params['state'] === 'in_progress' || $params['state'] === 'queued') {
$this->acceptHeaderValue = 'application/vnd.github.flash-preview+json';
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.$id.'/statuses', $params);
}
/**
@@ -102,6 +128,6 @@ class Deployment extends AbstractApi
*/
public function getStatuses($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.rawurlencode($id).'/statuses');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/deployments/'.$id.'/statuses');
}
}

View File

@@ -22,7 +22,7 @@ class Enterprise extends AbstractApi
*/
public function stats()
{
return new Stats($this->client);
return new Stats($this->getClient());
}
/**
@@ -30,7 +30,7 @@ class Enterprise extends AbstractApi
*/
public function license()
{
return new License($this->client);
return new License($this->getClient());
}
/**
@@ -38,7 +38,7 @@ class Enterprise extends AbstractApi
*/
public function console()
{
return new ManagementConsole($this->client);
return new ManagementConsole($this->getClient());
}
/**
@@ -46,6 +46,6 @@ class Enterprise extends AbstractApi
*/
public function userAdmin()
{
return new UserAdmin($this->client);
return new UserAdmin($this->getClient());
}
}

View File

@@ -21,7 +21,7 @@ class Comments extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -29,7 +29,7 @@ class Comments extends AbstractApi
$bodyType = 'raw';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->getApiVersion(), $bodyType);
return $this;
}
@@ -56,7 +56,7 @@ class Comments extends AbstractApi
*/
public function show($gist, $comment)
{
return $this->get('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment));
return $this->get('/gists/'.rawurlencode($gist).'/comments/'.$comment);
}
/**
@@ -83,7 +83,7 @@ class Comments extends AbstractApi
*/
public function update($gist, $comment_id, $body)
{
return $this->patch('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment_id), ['body' => $body]);
return $this->patch('/gists/'.rawurlencode($gist).'/comments/'.$comment_id, ['body' => $body]);
}
/**
@@ -96,6 +96,6 @@ class Comments extends AbstractApi
*/
public function remove($gist, $comment)
{
return $this->delete('/gists/'.rawurlencode($gist).'/comments/'.rawurlencode($comment));
return $this->delete('/gists/'.rawurlencode($gist).'/comments/'.$comment);
}
}

View File

@@ -24,7 +24,7 @@ class Gists extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -32,11 +32,16 @@ class Gists extends AbstractApi
$bodyType = 'raw';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s', $this->getApiVersion(), $bodyType);
return $this;
}
/**
* @param string|null $type
*
* @return array|string
*/
public function all($type = null)
{
if (!in_array($type, ['public', 'starred'])) {
@@ -46,11 +51,31 @@ class Gists extends AbstractApi
return $this->get('/gists/'.rawurlencode($type));
}
/**
* @param string $number
*
* @return array
*/
public function show($number)
{
return $this->get('/gists/'.rawurlencode($number));
}
/**
* Get a specific revision of a gist.
*
* @param string $number
* @param string $sha
*
* @link https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
*
* @return array
*/
public function revision($number, $sha)
{
return $this->get('/gists/'.rawurlencode($number).'/'.rawurlencode($sha));
}
public function create(array $params)
{
if (!isset($params['files']) || (!is_array($params['files']) || 0 === count($params['files']))) {
@@ -62,41 +87,82 @@ class Gists extends AbstractApi
return $this->post('/gists', $params);
}
/**
* @param string $id
* @param array $params
*
* @return array
*/
public function update($id, array $params)
{
return $this->patch('/gists/'.rawurlencode($id), $params);
}
/**
* @param string $id
*
* @return array
*/
public function commits($id)
{
return $this->get('/gists/'.rawurlencode($id).'/commits');
}
/**
* @param string $id
*
* @return array
*/
public function fork($id)
{
return $this->post('/gists/'.rawurlencode($id).'/fork');
}
/**
* @param string $id
*
* @return array
*/
public function forks($id)
{
return $this->get('/gists/'.rawurlencode($id).'/forks');
}
/**
* @param string $id
*
* @return array
*/
public function remove($id)
{
return $this->delete('/gists/'.rawurlencode($id));
}
/**
* @param string $id
*
* @return array
*/
public function check($id)
{
return $this->get('/gists/'.rawurlencode($id).'/star');
}
/**
* @param string $id
*
* @return array
*/
public function star($id)
{
return $this->put('/gists/'.rawurlencode($id).'/star');
}
/**
* @param string $id
*
* @return array
*/
public function unstar($id)
{
return $this->delete('/gists/'.rawurlencode($id).'/star');
@@ -111,6 +177,6 @@ class Gists extends AbstractApi
*/
public function comments()
{
return new Comments($this->client);
return new Comments($this->getClient());
}
}

View File

@@ -22,7 +22,7 @@ class GitData extends AbstractApi
*/
public function blobs()
{
return new Blobs($this->client);
return new Blobs($this->getClient());
}
/**
@@ -30,7 +30,7 @@ class GitData extends AbstractApi
*/
public function commits()
{
return new Commits($this->client);
return new Commits($this->getClient());
}
/**
@@ -38,7 +38,7 @@ class GitData extends AbstractApi
*/
public function references()
{
return new References($this->client);
return new References($this->getClient());
}
/**
@@ -46,7 +46,7 @@ class GitData extends AbstractApi
*/
public function tags()
{
return new Tags($this->client);
return new Tags($this->getClient());
}
/**
@@ -54,6 +54,6 @@ class GitData extends AbstractApi
*/
public function trees()
{
return new Trees($this->client);
return new Trees($this->getClient());
}
}

View File

@@ -21,12 +21,12 @@ class Blobs extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
if ('raw' === $bodyType) {
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.raw', $this->client->getApiVersion());
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.raw', $this->getApiVersion());
}
return $this;
@@ -43,9 +43,7 @@ class Blobs extends AbstractApi
*/
public function show($username, $repository, $sha)
{
$response = $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/blobs/'.rawurlencode($sha));
return $response;
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/blobs/'.rawurlencode($sha));
}
/**

View File

@@ -25,6 +25,22 @@ class References extends AbstractApi
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/refs');
}
/**
* Get all matching references for the supplied reference name.
*
* @param string $username
* @param string $repository
* @param string $reference
*
* @return array
*/
public function matching(string $username, string $repository, string $reference): array
{
$reference = $this->encodeReference($reference);
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/git/matching-refs/'.$reference);
}
/**
* Get all branches of a repository.
*

View File

@@ -56,11 +56,7 @@ class Tags extends AbstractApi
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'])) {
if (isset($params['tagger']) && !isset($params['tagger']['name'], $params['tagger']['email'], $params['tagger']['date'])) {
throw new MissingArgumentException(['tagger.name', 'tagger.email', 'tagger.date']);
}

View File

@@ -54,7 +54,7 @@ class Trees extends AbstractApi
}
// If `sha` is not set, `content` is required
if (!isset($tree['sha']) && !isset($tree['content'])) {
if (!array_key_exists('sha', $tree) && !isset($tree['content'])) {
throw new MissingArgumentException("tree.$key.content");
}
}

View File

@@ -18,12 +18,13 @@ class GraphQL extends AbstractApi
/**
* @param string $query
* @param array $variables
* @param string $acceptHeaderValue
*
* @return array
*/
public function execute($query, array $variables = [])
public function execute($query, array $variables = [], string $acceptHeaderValue = 'application/vnd.github.v4+json')
{
$this->acceptHeaderValue = 'application/vnd.github.v4+json';
$this->acceptHeaderValue = $acceptHeaderValue;
$params = [
'query' => $query,
];

View File

@@ -1,26 +0,0 @@
<?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;
}
}

View File

@@ -29,7 +29,7 @@ class Issue extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -37,7 +37,7 @@ class Issue extends AbstractApi
$bodyType = 'raw';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->getApiVersion(), $bodyType);
return $this;
}
@@ -58,28 +58,6 @@ class Issue extends AbstractApi
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.
*
@@ -113,7 +91,7 @@ class Issue extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$id);
}
/**
@@ -154,7 +132,7 @@ class Issue extends AbstractApi
*/
public function update($username, $repository, $id, array $params)
{
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$id, $params);
}
/**
@@ -170,7 +148,7 @@ class Issue extends AbstractApi
*/
public function lock($username, $repository, $id)
{
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id).'/lock');
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$id.'/lock');
}
/**
@@ -186,7 +164,7 @@ class Issue extends AbstractApi
*/
public function unlock($username, $repository, $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($id).'/lock');
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$id.'/lock');
}
/**
@@ -198,7 +176,7 @@ class Issue extends AbstractApi
*/
public function comments()
{
return new Comments($this->client);
return new Comments($this->getClient());
}
/**
@@ -210,7 +188,7 @@ class Issue extends AbstractApi
*/
public function events()
{
return new Events($this->client);
return new Events($this->getClient());
}
/**
@@ -222,7 +200,7 @@ class Issue extends AbstractApi
*/
public function labels()
{
return new Labels($this->client);
return new Labels($this->getClient());
}
/**
@@ -234,7 +212,7 @@ class Issue extends AbstractApi
*/
public function milestones()
{
return new Milestones($this->client);
return new Milestones($this->getClient());
}
/**
@@ -246,7 +224,7 @@ class Issue extends AbstractApi
*/
public function assignees()
{
return new Assignees($this->client);
return new Assignees($this->getClient());
}
/**
@@ -258,6 +236,6 @@ class Issue extends AbstractApi
*/
public function timeline()
{
return new Timeline($this->client);
return new Timeline($this->getClient());
}
}

View File

@@ -3,6 +3,7 @@
namespace Github\Api\Issue;
use Github\Api\AbstractApi;
use Github\Exception\InvalidArgumentException;
use Github\Exception\MissingArgumentException;
class Assignees extends AbstractApi
@@ -47,6 +48,7 @@ class Assignees extends AbstractApi
* @param string $issue
* @param array $parameters
*
* @throws InvalidArgumentException
* @throws MissingArgumentException
*
* @return string
@@ -58,9 +60,7 @@ class Assignees extends AbstractApi
}
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']];
throw new InvalidArgumentException('The assignees parameter should be an array of assignees');
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/assignees', $parameters);

View File

@@ -23,7 +23,7 @@ class Comments extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -31,7 +31,7 @@ class Comments extends AbstractApi
$bodyType = 'full';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->getApiVersion(), $bodyType);
return $this;
}
@@ -44,15 +44,13 @@ class Comments extends AbstractApi
* @param string $username
* @param string $repository
* @param int $issue
* @param int $page
* @param array $params
*
* @return array
*/
public function all($username, $repository, $issue, $page = 1)
public function all($username, $repository, $issue, array $params = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/comments', [
'page' => $page,
]);
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/comments', $params);
}
/**
@@ -68,7 +66,7 @@ class Comments extends AbstractApi
*/
public function show($username, $repository, $comment)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.$comment);
}
/**
@@ -91,7 +89,7 @@ class Comments extends AbstractApi
throw new MissingArgumentException('body');
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/comments', $params);
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/comments', $params);
}
/**
@@ -114,7 +112,7 @@ class Comments extends AbstractApi
throw new MissingArgumentException('body');
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.$comment, $params);
}
/**
@@ -130,6 +128,6 @@ class Comments extends AbstractApi
*/
public function remove($username, $repository, $comment)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.rawurlencode($comment));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/comments/'.$comment);
}
}

View File

@@ -26,7 +26,7 @@ class Events extends AbstractApi
public function all($username, $repository, $issue = null, $page = 1)
{
if (null !== $issue) {
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/events';
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/events';
} else {
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/events';
}

View File

@@ -29,7 +29,7 @@ class Labels extends AbstractApi
if ($issue === null) {
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels';
} else {
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels';
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/labels';
}
return $this->get($path);
@@ -118,7 +118,7 @@ class Labels extends AbstractApi
/**
* Add a label to an issue.
*
* @link https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
* @link https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue
*
* @param string $username
* @param string $repository
@@ -137,7 +137,7 @@ class Labels extends AbstractApi
throw new InvalidArgumentException('The labels parameter should be a single label or an array of labels');
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels', $labels);
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/labels', $labels);
}
/**
@@ -154,7 +154,7 @@ class Labels extends AbstractApi
*/
public function replace($username, $repository, $issue, array $params)
{
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels', $params);
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/labels', $params);
}
/**
@@ -164,14 +164,14 @@ class Labels extends AbstractApi
*
* @param string $username
* @param string $repository
* @param string $issue
* @param int $issue
* @param string $label
*
* @return array|string
*/
public function remove($username, $repository, $issue, $label)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels/'.rawurlencode($label));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/labels/'.rawurlencode($label));
}
/**
@@ -181,12 +181,12 @@ class Labels extends AbstractApi
*
* @param string $username
* @param string $repository
* @param string $issue
* @param int $issue
*
* @return array|string
*/
public function clear($username, $repository, $issue)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/labels');
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/labels');
}
}

View File

@@ -56,7 +56,7 @@ class Milestones extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.$id);
}
/**
@@ -102,7 +102,7 @@ class Milestones extends AbstractApi
$params['state'] = 'open';
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.$id, $params);
}
/**
@@ -118,7 +118,7 @@ class Milestones extends AbstractApi
*/
public function remove($username, $repository, $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.$id);
}
/**
@@ -134,6 +134,6 @@ class Milestones extends AbstractApi
*/
public function labels($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.rawurlencode($id).'/labels');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/milestones/'.$id.'/labels');
}
}

View File

@@ -29,6 +29,6 @@ class Timeline extends AbstractApi
*/
public function all($username, $repository, $issue)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.rawurlencode($issue).'/timeline');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/issues/'.$issue.'/timeline');
}
}

View File

@@ -23,6 +23,7 @@ class Notification extends AbstractApi
* @param bool $includingRead
* @param bool $participating
* @param DateTime|null $since
* @param DateTime|null $before
*
* @return array array of notifications
*/

View File

@@ -2,8 +2,10 @@
namespace Github\Api;
use Github\Api\Organization\Actions\Secrets;
use Github\Api\Organization\Hooks;
use Github\Api\Organization\Members;
use Github\Api\Organization\OutsideCollaborators;
use Github\Api\Organization\Teams;
/**
@@ -53,15 +55,27 @@ class Organization extends AbstractApi
* @param string $organization the user name
* @param string $type the type of repositories
* @param int $page the page
* @param string $sort sort by
* @param string $direction direction of sort, asc or desc
*
* @return array the repositories
*/
public function repositories($organization, $type = 'all', $page = 1)
public function repositories($organization, $type = 'all', $page = 1, $sort = null, $direction = null)
{
return $this->get('/orgs/'.rawurlencode($organization).'/repos', [
$parameters = [
'type' => $type,
'page' => $page,
]);
];
if ($sort !== null) {
$parameters['sort'] = $sort;
}
if ($direction !== null) {
$parameters['direction'] = $direction;
}
return $this->get('/orgs/'.rawurlencode($organization).'/repos', $parameters);
}
/**
@@ -69,7 +83,7 @@ class Organization extends AbstractApi
*/
public function members()
{
return new Members($this->client);
return new Members($this->getClient());
}
/**
@@ -77,7 +91,7 @@ class Organization extends AbstractApi
*/
public function hooks()
{
return new Hooks($this->client);
return new Hooks($this->getClient());
}
/**
@@ -85,7 +99,23 @@ class Organization extends AbstractApi
*/
public function teams()
{
return new Teams($this->client);
return new Teams($this->getClient());
}
/**
* @return Secrets
*/
public function secrets(): Secrets
{
return new Secrets($this->getClient());
}
/**
* @return OutsideCollaborators
*/
public function outsideCollaborators()
{
return new OutsideCollaborators($this->getClient());
}
/**

View File

@@ -0,0 +1,144 @@
<?php
namespace Github\Api\Organization\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#secrets
*/
class Secrets extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-organization-secrets
*
* @param string $organization
*
* @return array|string
*/
public function all(string $organization)
{
return $this->get('/orgs/'.rawurlencode($organization).'/actions/secrets');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-an-organization-secret
*
* @param string $organization
* @param string $secretName
*
* @return array|string
*/
public function show(string $organization, string $secretName)
{
return $this->get('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName));
}
/**
* @link https://docs.github.com/en/rest/reference/actions#create-or-update-an-organization-secret
*
* @param string $organization
* @param string $secretName
* @param array $parameters
*
* @return array|string
*/
public function create(string $organization, string $secretName, array $parameters = [])
{
return $this->put('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName), $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#create-or-update-an-organization-secret
*
* @param string $organization
* @param string $secretName
* @param array $parameters
*
* @return array|string
*/
public function update(string $organization, string $secretName, array $parameters = [])
{
return $this->put('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName), $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-an-organization-secret
*
* @param string $organization
* @param string $secretName
*
* @return array|string
*/
public function remove(string $organization, string $secretName)
{
return $this->delete('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName));
}
/**
* @link https://docs.github.com/en/rest/reference/actions#list-selected-repositories-for-an-organization-secret
*
* @param string $organization
* @param string $secretName
*
* @return array|string
*/
public function selectedRepositories(string $organization, string $secretName)
{
return $this->get('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName).'/repositories');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#set-selected-repositories-for-an-organization-secret
*
* @param string $organization
* @param string $secretName
* @param array $parameters
*
* @return array|string
*/
public function setSelectedRepositories(string $organization, string $secretName, array $parameters = [])
{
return $this->put('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName).'/repositories', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#add-selected-repository-to-an-organization-secret
*
* @param string $organization
* @param string $repositoryId
* @param string $secretName
*
* @return array|string
*/
public function addSecret(string $organization, string $repositoryId, string $secretName)
{
return $this->put('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName).'/repositories/'.$repositoryId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#remove-selected-repository-from-an-organization-secret
*
* @param string $organization
* @param string $repositoryId
* @param string $secretName
*
* @return array|string
*/
public function removeSecret(string $organization, string $repositoryId, string $secretName)
{
return $this->delete('/orgs/'.rawurlencode($organization).'/actions/secrets/'.rawurlencode($secretName).'/repositories/'.$repositoryId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-an-organization-public-key
*
* @param string $organization
*
* @return array|string
*/
public function publicKey(string $organization)
{
return $this->get('/orgs/'.rawurlencode($organization).'/actions/secrets/public-key');
}
}

View File

@@ -33,7 +33,7 @@ class Hooks extends AbstractApi
*/
public function show($organization, $id)
{
return $this->get('/orgs/'.rawurlencode($organization).'/hooks/'.rawurlencode($id));
return $this->get('/orgs/'.rawurlencode($organization).'/hooks/'.$id);
}
/**
@@ -76,7 +76,7 @@ class Hooks extends AbstractApi
throw new MissingArgumentException(['config']);
}
return $this->patch('/orgs/'.rawurlencode($organization).'/hooks/'.rawurlencode($id), $params);
return $this->patch('/orgs/'.rawurlencode($organization).'/hooks/'.$id, $params);
}
/**
@@ -91,7 +91,7 @@ class Hooks extends AbstractApi
*/
public function ping($organization, $id)
{
return $this->post('/orgs/'.rawurlencode($organization).'/hooks/'.rawurlencode($id).'/pings');
return $this->post('/orgs/'.rawurlencode($organization).'/hooks/'.$id.'/pings');
}
/**
@@ -106,6 +106,6 @@ class Hooks extends AbstractApi
*/
public function remove($organization, $id)
{
return $this->delete('/orgs/'.rawurlencode($organization).'/hooks/'.rawurlencode($id));
return $this->delete('/orgs/'.rawurlencode($organization).'/hooks/'.$id);
}
}

View File

@@ -58,9 +58,9 @@ class Members extends AbstractApi
/*
* Add user to organization
*/
public function add($organization, $username)
public function add($organization, $username, array $params = [])
{
return $this->put('/orgs/'.rawurlencode($organization).'/memberships/'.rawurlencode($username));
return $this->put('/orgs/'.rawurlencode($organization).'/memberships/'.rawurlencode($username), $params);
}
public function addMember($organization, $username)

View File

@@ -0,0 +1,52 @@
<?php
namespace Github\Api\Organization;
use Github\Api\AbstractApi;
/**
* @link https://developer.github.com/v3/orgs/outside_collaborators/
*
* @author Matthieu Calie <matthieu@calie.be>
*/
class OutsideCollaborators extends AbstractApi
{
/**
* @link https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators-for-an-organization
*
* @param string $organization the organization
* @param array $params
*
* @return array the organizations
*/
public function all($organization, array $params = [])
{
return $this->get('/orgs/'.rawurlencode($organization).'/outside_collaborators', $params);
}
/**
* @link https://developer.github.com/v3/orgs/outside_collaborators/#convert-an-organization-member-to-outside-collaborator
*
* @param string $organization the organization
* @param string $username the github username
*
* @return array
*/
public function convert($organization, $username)
{
return $this->put('/orgs/'.rawurlencode($organization).'/outside_collaborators/'.rawurldecode($username));
}
/**
* @link https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator-from-an-organization
*
* @param string $organization the organization
* @param string $username the username
*
* @return array
*/
public function remove($organization, $username)
{
return $this->delete('/orgs/'.rawurlencode($organization).'/outside_collaborators/'.rawurldecode($username));
}
}

View File

@@ -32,12 +32,18 @@ class Teams extends AbstractApi
return $this->post('/orgs/'.rawurlencode($organization).'/teams', $params);
}
public function show($team)
/**
* @link https://developer.github.com/v3/teams/#list-teams
*/
public function show($team, $organization)
{
return $this->get('/teams/'.rawurlencode($team));
return $this->get('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team));
}
public function update($team, array $params)
/**
* @link https://developer.github.com/v3/teams/#edit-team
*/
public function update($team, array $params, $organization)
{
if (!isset($params['name'])) {
throw new MissingArgumentException('name');
@@ -46,32 +52,47 @@ class Teams extends AbstractApi
$params['permission'] = 'pull';
}
return $this->patch('/teams/'.rawurlencode($team), $params);
return $this->patch('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team), $params);
}
public function remove($team)
/**
* @link https://developer.github.com/v3/teams/#delete-team
*/
public function remove($team, $organization)
{
return $this->delete('/teams/'.rawurlencode($team));
return $this->delete('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team));
}
public function members($team)
/**
* @link https://developer.github.com/v3/teams/members/#list-team-members
*/
public function members($team, $organization)
{
return $this->get('/teams/'.rawurlencode($team).'/members');
return $this->get('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/members');
}
public function check($team, $username)
/**
* @link https://developer.github.com/v3/teams/members/#get-team-membership
*/
public function check($team, $username, $organization)
{
return $this->get('/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
return $this->get('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
}
public function addMember($team, $username)
/**
* @link https://developer.github.com/v3/teams/members/#add-or-update-team-membership
*/
public function addMember($team, $username, $organization)
{
return $this->put('/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
return $this->put('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
}
public function removeMember($team, $username)
/**
* @link https://developer.github.com/v3/teams/members/#remove-team-membership
*/
public function removeMember($team, $username, $organization)
{
return $this->delete('/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
return $this->delete('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/memberships/'.rawurlencode($username));
}
public function repositories($team)
@@ -86,15 +107,15 @@ class Teams extends AbstractApi
public function addRepository($team, $organization, $repository, $params = [])
{
if (isset($params['permission']) && !in_array($params['permission'], ['pull', 'push', 'admin'])) {
if (isset($params['permission']) && !in_array($params['permission'], ['pull', 'push', 'admin', 'maintain', 'triage'])) {
$params['permission'] = 'pull';
}
return $this->put('/teams/'.rawurlencode($team).'/repos/'.rawurlencode($organization).'/'.rawurlencode($repository), $params);
return $this->put('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/repos/'.rawurlencode($organization).'/'.rawurlencode($repository), $params);
}
public function removeRepository($team, $organization, $repository)
{
return $this->delete('/teams/'.rawurlencode($team).'/repos/'.rawurlencode($organization).'/'.rawurlencode($repository));
return $this->delete('/orgs/'.rawurlencode($organization).'/teams/'.rawurlencode($team).'/repos/'.rawurlencode($organization).'/'.rawurlencode($repository));
}
}

View File

@@ -14,7 +14,7 @@ abstract class AbstractProjectApi extends AbstractApi
*
* @see https://developer.github.com/v3/repos/projects/#projects
*
* @return self
* @return $this
*/
public function configure()
{
@@ -40,6 +40,6 @@ abstract class AbstractProjectApi extends AbstractApi
public function columns()
{
return new Columns($this->client);
return new Columns($this->getClient());
}
}

View File

@@ -15,7 +15,7 @@ class Cards extends AbstractApi
*
* @see https://developer.github.com/v3/repos/projects/#projects
*
* @return self
* @return $this
*/
public function configure()
{

View File

@@ -68,6 +68,6 @@ class Columns extends AbstractApi
public function cards()
{
return new Cards($this->client);
return new Cards($this->getClient());
}
}

View File

@@ -27,12 +27,12 @@ class PullRequest extends AbstractApi
* @param string|null $bodyType
* @param string|null $apiVersion
*
* @return self
* @return $this
*/
public function configure($bodyType = null, $apiVersion = null)
{
if (null === $apiVersion) {
$apiVersion = $this->client->getApiVersion();
$apiVersion = $this->getApiVersion();
}
if (!in_array($bodyType, ['text', 'html', 'full', 'diff', 'patch'])) {
@@ -55,17 +55,12 @@ class PullRequest extends AbstractApi
*
* @param string $username the username
* @param string $repository the repository
* @param array $params a list of extra parameters.
* @param array $parameters a list of extra parameters.
*
* @return array array of pull requests for the project
*/
public function all($username, $repository, array $params = [])
public function all($username, $repository, array $parameters = [])
{
$parameters = array_merge([
'page' => 1,
'per_page' => 30,
], $params);
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls', $parameters);
}
@@ -82,17 +77,17 @@ class PullRequest extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$id);
}
public function commits($username, $repository, $id)
public function commits($username, $repository, $id, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($id).'/commits');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($id).'/commits', $parameters);
}
public function files($username, $repository, $id)
public function files($username, $repository, $id, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($id).'/files');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($id).'/files', $parameters);
}
/**
@@ -115,17 +110,17 @@ class PullRequest extends AbstractApi
public function comments()
{
return new Comments($this->client);
return new Comments($this->getClient());
}
public function reviews()
{
return new Review($this->client);
return new Review($this->getClient());
}
public function reviewRequests()
{
return new ReviewRequest($this->client);
return new ReviewRequest($this->getClient());
}
/**

View File

@@ -23,12 +23,12 @@ class Comments extends AbstractApi
* @param string|null $bodyType
* @param string|null $apiVersion
*
* @return self
* @return $this
*/
public function configure($bodyType = null, $apiVersion = null)
{
if ($apiVersion !== 'squirrel-girl-preview') {
$apiVersion = $this->client->getApiVersion();
$apiVersion = $this->getApiVersion();
}
if (!in_array($bodyType, ['text', 'html', 'full'])) {
@@ -57,7 +57,7 @@ class Comments extends AbstractApi
public function all($username, $repository, $pullRequest = null, array $params = [])
{
if (null !== $pullRequest) {
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/comments');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/comments');
}
$parameters = array_merge([
@@ -81,7 +81,7 @@ class Comments extends AbstractApi
*/
public function show($username, $repository, $comment)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.rawurlencode($comment));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.$comment);
}
/**
@@ -109,7 +109,7 @@ class Comments extends AbstractApi
throw new MissingArgumentException(['commit_id', 'path', 'position']);
}
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/comments', $params);
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/comments', $params);
}
/**
@@ -132,7 +132,7 @@ class Comments extends AbstractApi
throw new MissingArgumentException('body');
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.rawurlencode($comment), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.$comment, $params);
}
/**
@@ -148,6 +148,6 @@ class Comments extends AbstractApi
*/
public function remove($username, $repository, $comment)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.rawurlencode($comment));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/comments/'.$comment);
}
}

View File

@@ -20,6 +20,8 @@ class Review extends AbstractApi
public function configure()
{
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "%s" is deprecated and will be removed.', __METHOD__);
return $this;
}
@@ -37,6 +39,10 @@ class Review extends AbstractApi
*/
public function all($username, $repository, $pullRequest, array $params = [])
{
if (!empty($params)) {
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "$params" parameter is deprecated, to paginate the results use the "ResultPager" instead.');
}
$parameters = array_merge([
'page' => 1,
'per_page' => 30,
@@ -93,7 +99,7 @@ class Review extends AbstractApi
*/
public function comments($username, $repository, $pullRequest, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.rawurlencode($pullRequest).'/reviews/'.rawurlencode($id).'/comments');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id.'/comments');
}
/**
@@ -171,7 +177,35 @@ class Review extends AbstractApi
}
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id.'/dismissals', [
'message' => $message,
'message' => $message,
]);
}
/**
* Update a pull request review by the username, repository, pull request number and the review id.
*
* @link https://developer.github.com/v3/pulls/reviews/#update-a-pull-request-review
*
* @param string $username the username
* @param string $repository the repository
* @param int $pullRequest the pull request number
* @param int $id the review id
* @param string $body a mandatory dismissal message
*
* @return array|string
*/
public function update($username, $repository, $pullRequest, $id, $body)
{
if (!is_string($body)) {
throw new InvalidArgumentException(sprintf('"body" must be a valid string ("%s" given).', gettype($body)));
}
if (empty($body)) {
throw new InvalidArgumentException('"body" is mandatory and cannot be empty');
}
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/reviews/'.$id, [
'body' => $body,
]);
}
}

View File

@@ -14,6 +14,8 @@ class ReviewRequest extends AbstractApi
public function configure()
{
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "%s" is deprecated and will be removed.', __METHOD__);
return $this;
}
@@ -29,6 +31,10 @@ class ReviewRequest extends AbstractApi
*/
public function all($username, $repository, $pullRequest, array $params = [])
{
if (!empty($params)) {
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "$params" parameter is deprecated, to paginate the results use the "ResultPager" instead.');
}
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/requested_reviewers', $params);
}
@@ -39,12 +45,13 @@ class ReviewRequest extends AbstractApi
* @param string $repository
* @param int $pullRequest
* @param array $reviewers
* @param array $teamReviewers
*
* @return string
*/
public function create($username, $repository, $pullRequest, array $reviewers)
public function create($username, $repository, $pullRequest, array $reviewers = [], array $teamReviewers = [])
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/requested_reviewers', ['reviewers' => $reviewers]);
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/requested_reviewers', ['reviewers' => $reviewers, 'team_reviewers' => $teamReviewers]);
}
/**
@@ -54,11 +61,12 @@ class ReviewRequest extends AbstractApi
* @param string $repository
* @param int $pullRequest
* @param array $reviewers
* @param array $teamReviewers
*
* @return string
*/
public function remove($username, $repository, $pullRequest, array $reviewers)
public function remove($username, $repository, $pullRequest, array $reviewers = [], array $teamReviewers = [])
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/requested_reviewers', ['reviewers' => $reviewers]);
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pulls/'.$pullRequest.'/requested_reviewers', ['reviewers' => $reviewers, 'team_reviewers' => $teamReviewers]);
}
}

View File

@@ -18,18 +18,6 @@ class RateLimit extends AbstractApi
*/
protected $resources = [];
/**
* Get rate limits data in an array.
*
* @deprecated since 2.11.0 Use `->getResources()` instead
*
* @return array
*/
public function getRateLimits()
{
return $this->fetchLimits();
}
/**
* Gets the rate limit resource objects.
*
@@ -79,28 +67,4 @@ class RateLimit extends AbstractApi
return $result;
}
/**
* Get core rate limit.
*
* @deprecated since 2.11.0 Use `->getResource('core')->getLimit()` instead
*
* @return int
*/
public function getCoreLimit()
{
return $this->getResource('core')->getLimit();
}
/**
* Get search rate limit.
*
* @deprecated since 2.11.0 Use `->getResource('core')->getLimit()` instead
*
* @return int
*/
public function getSearchLimit()
{
return $this->getResource('search')->getLimit();
}
}

View File

@@ -2,6 +2,14 @@
namespace Github\Api;
use Github\Api\Repository\Actions\Artifacts;
use Github\Api\Repository\Actions\Secrets;
use Github\Api\Repository\Actions\SelfHostedRunners;
use Github\Api\Repository\Actions\WorkflowJobs;
use Github\Api\Repository\Actions\WorkflowRuns;
use Github\Api\Repository\Actions\Workflows;
use Github\Api\Repository\Checks\CheckRuns;
use Github\Api\Repository\Checks\CheckSuites;
use Github\Api\Repository\Collaborators;
use Github\Api\Repository\Comments;
use Github\Api\Repository\Commits;
@@ -11,6 +19,7 @@ use Github\Api\Repository\Downloads;
use Github\Api\Repository\Forks;
use Github\Api\Repository\Hooks;
use Github\Api\Repository\Labels;
use Github\Api\Repository\Pages;
use Github\Api\Repository\Projects;
use Github\Api\Repository\Protection;
use Github\Api\Repository\Releases;
@@ -31,22 +40,6 @@ class Repo extends AbstractApi
{
use AcceptHeaderTrait;
/**
* Search repositories by 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-repositories
*
* @param string $keyword the search query
* @param array $params
*
* @return array list of found repositories
*/
public function find($keyword, array $params = [])
{
return $this->get('/legacy/repos/search/'.rawurlencode($keyword), array_merge(['start_page' => 1], $params));
}
/**
* List all public repositories.
*
@@ -62,7 +55,7 @@ class Repo extends AbstractApi
return $this->get('/repositories');
}
return $this->get('/repositories?since='.rawurldecode($id));
return $this->get('/repositories', ['since' => $id]);
}
/**
@@ -169,7 +162,7 @@ class Repo extends AbstractApi
*/
public function showById($id)
{
return $this->get('/repositories/'.rawurlencode($id));
return $this->get('/repositories/'.$id);
}
/**
@@ -181,13 +174,14 @@ class Repo extends AbstractApi
* @param string $description repository description
* @param string $homepage homepage url
* @param bool $public `true` for public, `false` for private
* @param null|string $organization username of organization if applicable
* @param string|null $organization username of organization if applicable
* @param bool $hasIssues `true` to enable issues for this repository, `false` to disable them
* @param bool $hasWiki `true` to enable the wiki for this repository, `false` to disable it
* @param bool $hasDownloads `true` to enable downloads for this repository, `false` to disable them
* @param int $teamId The id of the team that will be granted access to this repository. This is only valid when creating a repo in an organization.
* @param bool $autoInit `true` to create an initial commit with empty README, `false` for no initial commit
* @param bool $hasProjects `true` to enable projects for this repository or false to disable them.
* @param string|null $visibility
*
* @return array returns repository data
*/
@@ -202,7 +196,8 @@ class Repo extends AbstractApi
$hasDownloads = false,
$teamId = null,
$autoInit = false,
$hasProjects = true
$hasProjects = true,
$visibility = null
) {
$path = null !== $organization ? '/orgs/'.$organization.'/repos' : '/user/repos';
@@ -210,7 +205,8 @@ class Repo extends AbstractApi
'name' => $name,
'description' => $description,
'homepage' => $homepage,
'private' => !$public,
'private' => ($visibility ?? ($public ? 'public' : 'private')) === 'private',
'visibility' => $visibility ?? ($public ? 'public' : 'private'),
'has_issues' => $hasIssues,
'has_wiki' => $hasWiki,
'has_downloads' => $hasDownloads,
@@ -264,16 +260,43 @@ class Repo extends AbstractApi
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $format one of formats: "raw", "html", or "v3+json"
* @param string $dir The alternate path to look for a README file
* @param array $params additional query params like "ref" to fetch readme for branch/tag
*
* @return string|array the readme content
*/
public function readme($username, $repository, $format = 'raw')
public function readme($username, $repository, $format = 'raw', $dir = null, $params = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme', [], [
$path = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/readme';
if (null !== $dir) {
$path .= '/'.rawurlencode($dir);
}
return $this->get($path, $params, [
'Accept' => "application/vnd.github.$format",
]);
}
/**
* Create a repository dispatch event.
*
* @link https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
*
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $eventType A custom webhook event name
*
* @return mixed null on success, array on error with 'message'
*/
public function dispatch($username, $repository, $eventType, array $clientPayload)
{
return $this->post(\sprintf('/repos/%s/%s/dispatches', rawurlencode($username), rawurlencode($repository)), [
'event_type' => $eventType,
'client_payload' => $clientPayload,
]);
}
/**
* Manage the collaborators of a repository.
*
@@ -283,7 +306,7 @@ class Repo extends AbstractApi
*/
public function collaborators()
{
return new Collaborators($this->client);
return new Collaborators($this->getClient());
}
/**
@@ -295,7 +318,7 @@ class Repo extends AbstractApi
*/
public function comments()
{
return new Comments($this->client);
return new Comments($this->getClient());
}
/**
@@ -307,7 +330,71 @@ class Repo extends AbstractApi
*/
public function commits()
{
return new Commits($this->client);
return new Commits($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/checks#check-runs
*/
public function checkRuns(): CheckRuns
{
return new CheckRuns($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/checks#check-suites
*/
public function checkSuites(): CheckSuites
{
return new CheckSuites($this->getClient());
}
/**
* @link https://developer.github.com/v3/actions/artifacts/#artifacts
*/
public function artifacts(): Artifacts
{
return new Artifacts($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/actions#workflows
*/
public function workflows(): Workflows
{
return new Workflows($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/actions#workflow-runs
*/
public function workflowRuns(): WorkflowRuns
{
return new WorkflowRuns($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/actions#workflow-jobs
*/
public function workflowJobs(): WorkflowJobs
{
return new WorkflowJobs($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/actions#self-hosted-runners
*/
public function selfHostedRunners(): SelfHostedRunners
{
return new SelfHostedRunners($this->getClient());
}
/**
* @link https://docs.github.com/en/rest/reference/actions#secrets
*/
public function secrets(): Secrets
{
return new Secrets($this->getClient());
}
/**
@@ -319,7 +406,7 @@ class Repo extends AbstractApi
*/
public function contents()
{
return new Contents($this->client);
return new Contents($this->getClient());
}
/**
@@ -331,7 +418,7 @@ class Repo extends AbstractApi
*/
public function downloads()
{
return new Downloads($this->client);
return new Downloads($this->getClient());
}
/**
@@ -343,7 +430,7 @@ class Repo extends AbstractApi
*/
public function releases()
{
return new Releases($this->client);
return new Releases($this->getClient());
}
/**
@@ -355,7 +442,7 @@ class Repo extends AbstractApi
*/
public function keys()
{
return new DeployKeys($this->client);
return new DeployKeys($this->getClient());
}
/**
@@ -367,7 +454,7 @@ class Repo extends AbstractApi
*/
public function forks()
{
return new Forks($this->client);
return new Forks($this->getClient());
}
/**
@@ -379,7 +466,7 @@ class Repo extends AbstractApi
*/
public function stargazers()
{
return new Stargazers($this->client);
return new Stargazers($this->getClient());
}
/**
@@ -391,7 +478,7 @@ class Repo extends AbstractApi
*/
public function hooks()
{
return new Hooks($this->client);
return new Hooks($this->getClient());
}
/**
@@ -403,7 +490,7 @@ class Repo extends AbstractApi
*/
public function labels()
{
return new Labels($this->client);
return new Labels($this->getClient());
}
/**
@@ -415,7 +502,7 @@ class Repo extends AbstractApi
*/
public function statuses()
{
return new Statuses($this->client);
return new Statuses($this->getClient());
}
/**
@@ -426,17 +513,18 @@ class Repo extends AbstractApi
* @param string $username the username
* @param string $repository the name of the repository
* @param string $branch the name of the branch
* @param array $parameters parameters for the query string
*
* @return array list of the repository branches
*/
public function branches($username, $repository, $branch = null)
public function branches($username, $repository, $branch = null, array $parameters = [])
{
$url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/branches';
if (null !== $branch) {
$url .= '/'.rawurlencode($branch);
}
return $this->get($url);
return $this->get($url, $parameters);
}
/**
@@ -448,7 +536,7 @@ class Repo extends AbstractApi
*/
public function protection()
{
return new Protection($this->client);
return new Protection($this->getClient());
}
/**
@@ -516,22 +604,6 @@ class Repo extends AbstractApi
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/teams');
}
/**
* @deprecated see subscribers method
*
* @param string $username
* @param string $repository
* @param int $page
*
* @return array
*/
public function watchers($username, $repository, $page = 1)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/watchers', [
'page' => $page,
]);
}
/**
* @param string $username
* @param string $repository
@@ -557,7 +629,7 @@ class Repo extends AbstractApi
* @param string $head The head to merge. This can be a branch name or a commit SHA1.
* @param string $message Commit message to use for the merge commit. If omitted, a default message will be used.
*
* @return array|null
* @return array|string
*/
public function merge($username, $repository, $base, $head, $message = null)
{
@@ -576,22 +648,58 @@ class Repo extends AbstractApi
/**
* @param string $username
* @param string $repository
* @param array $parameters
*
* @return array
*/
public function milestones($username, $repository)
public function milestones($username, $repository, array $parameters = [])
{
return $this->get('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/milestones');
return $this->get('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/milestones', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/repos#enable-automated-security-fixes
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function enableAutomatedSecurityFixes(string $username, string $repository)
{
$this->acceptHeaderValue = 'application/vnd.github.london-preview+json';
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/automated-security-fixes');
}
/**
* @link https://docs.github.com/en/rest/reference/repos#disable-automated-security-fixes
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function disableAutomatedSecurityFixes(string $username, string $repository)
{
$this->acceptHeaderValue = 'application/vnd.github.london-preview+json';
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/automated-security-fixes');
}
public function projects()
{
return new Projects($this->client);
return new Projects($this->getClient());
}
public function traffic()
{
return new Traffic($this->client);
return new Traffic($this->getClient());
}
public function pages()
{
return new Pages($this->getClient());
}
/**
@@ -608,6 +716,24 @@ class Repo extends AbstractApi
return $this->get('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/events', ['page' => $page]);
}
/**
* Get the community profile metrics for a repository.
*
* @link https://developer.github.com/v3/repos/community/#retrieve-community-profile-metrics
*
* @param string $username
* @param string $repository
*
* @return array
*/
public function communityProfile($username, $repository)
{
//This api is in preview mode, so set the correct accept-header
$this->acceptHeaderValue = 'application/vnd.github.black-panther-preview+json';
return $this->get('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/community/profile');
}
/**
* Get the contents of a repository's code of conduct.
*
@@ -677,9 +803,21 @@ class Repo extends AbstractApi
*/
public function transfer($username, $repository, $newOwner, $teamId = [])
{
//This api is in preview mode, so set the correct accept-header
$this->acceptHeaderValue = 'application/vnd.github.nightshade-preview+json';
return $this->post('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/transfer', ['new_owner' => $newOwner, 'team_id' => $teamId]);
}
/**
* Create a repository using a template.
*
* @link https://developer.github.com/v3/repos/#create-a-repository-using-a-template
*
* @return array
*/
public function createFromTemplate(string $templateOwner, string $templateRepo, array $parameters = [])
{
//This api is in preview mode, so set the correct accept-header
$this->acceptHeaderValue = 'application/vnd.github.baptiste-preview+json';
return $this->post('/repos/'.rawurldecode($templateOwner).'/'.rawurldecode($templateRepo).'/generate', $parameters);
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#artifacts
*/
class Artifacts extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-artifacts-for-a-repository
*
* @param string $username
* @param string $repository
* @param array $parameters
*
* @return array
*/
public function all(string $username, string $repository, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/artifacts', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#list-workflow-run-artifacts
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array
*/
public function runArtifacts(string $username, string $repository, int $runId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/artifacts');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-an-artifact
*
* @param string $username
* @param string $repository
* @param int $artifactId
*
* @return array
*/
public function show(string $username, string $repository, int $artifactId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/artifacts/'.$artifactId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-an-artifact
*
* @param string $username
* @param string $repository
* @param int $artifactId
*
* @return array
*/
public function remove(string $username, string $repository, int $artifactId)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/artifacts/'.$artifactId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#download-an-artifact
*
* @param string $username
* @param string $repository
* @param int $artifactId
* @param string $format
*
* @return array
*/
public function download(string $username, string $repository, int $artifactId, string $format = 'zip')
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/artifacts/'.$artifactId.'/'.$format);
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#secrets
*/
class Secrets extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-repository-secrets
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function all(string $username, string $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-repository-secret
*
* @param string $username
* @param string $repository
* @param string $secretName
*
* @return array|string
*/
public function show(string $username, string $repository, string $secretName)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets/'.rawurlencode($secretName));
}
/**
* @link https://docs.github.com/en/rest/reference/actions#create-or-update-a-repository-secret
*
* @param string $username
* @param string $repository
* @param string $secretName
* @param array $parameters
*
* @return array|string
*/
public function create(string $username, string $repository, string $secretName, array $parameters = [])
{
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets/'.rawurlencode($secretName), $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#create-or-update-a-repository-secret
*
* @param string $username
* @param string $repository
* @param string $secretName
* @param array $parameters
*
* @return array|string
*/
public function update(string $username, string $repository, string $secretName, array $parameters = [])
{
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets/'.rawurlencode($secretName), $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-a-repository-secret
*
* @param string $username
* @param string $repository
* @param string $secretName
*
* @return array|string
*/
public function remove(string $username, string $repository, string $secretName)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets/'.rawurlencode($secretName));
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-repository-public-key
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function publicKey(string $username, string $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/secrets/public-key');
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#self-hosted-runners
*/
class SelfHostedRunners extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-self-hosted-runners-for-a-repository
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function all(string $username, string $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurldecode($repository).'/actions/runners');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-self-hosted-runner-for-a-repository
*
* @param string $username
* @param string $repository
* @param int $runnerId
*
* @return array|string
*/
public function show(string $username, string $repository, int $runnerId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurldecode($repository).'/actions/runners/'.$runnerId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-a-self-hosted-runner-from-a-repository
*
* @param string $username
* @param string $repository
* @param int $runnerId
*
* @return array|string
*/
public function remove(string $username, string $repository, int $runnerId)
{
return $this->delete('/repos/'.rawurldecode($username).'/'.rawurldecode($repository).'/actions/runners/'.$runnerId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#list-runner-applications-for-a-repository
*
* @param string $username
* @param string $repository
*
* @return array|string
*/
public function applications(string $username, string $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runners/downloads');
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#workflow-jobs
*/
class WorkflowJobs extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-jobs-for-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $runId
* @param array $parameters
*
* @return array
*/
public function all(string $username, string $repository, int $runId, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/jobs', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-job-for-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $jobId
*
* @return array
*/
public function show(string $username, string $repository, int $jobId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/jobs/'.$jobId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#download-job-logs-for-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $jobId
*
* @return array
*/
public function downloadLogs(string $username, string $repository, int $jobId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/jobs/'.$jobId.'/logs');
}
}

View File

@@ -0,0 +1,155 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#workflow-runs
*/
class WorkflowRuns extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-workflow-runs-for-a-repository
*
* @param string $username
* @param string $repository
* @param array $parameters
*
* @return array
*/
public function all(string $username, string $repository, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#list-workflow-runs
*
* @param string $username
* @param string $repository
* @param string $workflow
* @param array $parameters
*
* @return array
*/
public function listRuns(string $username, string $repository, string $workflow, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/workflows/'.rawurlencode($workflow).'/runs', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $runId
* @param array $parameters
*
* @return array
*/
public function show(string $username, string $repository, int $runId, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId, $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array|string
*/
public function remove(string $username, string $repository, int $runId)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#re-run-a-workflow
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array
*/
public function rerun(string $username, string $repository, int $runId)
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/rerun');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#cancel-a-workflow-run
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array
*/
public function cancel(string $username, string $repository, int $runId)
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/cancel');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-workflow-run-usage
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array
*/
public function usage(string $username, string $repository, int $runId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/timing');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#download-workflow-run-logs
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array|string
*/
public function downloadLogs(string $username, string $repository, int $runId)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/logs');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#delete-workflow-run-logs
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array|string
*/
public function deleteLogs(string $username, string $repository, int $runId)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/logs');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#approve-a-workflow-run-for-a-fork-pull-request
*
* @param string $username
* @param string $repository
* @param int $runId
*
* @return array|string
*
* @experimental This endpoint is currently in beta.
*/
public function approve(string $username, string $repository, int $runId)
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/runs/'.$runId.'/approve');
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Github\Api\Repository\Actions;
use Github\Api\AbstractApi;
/**
* @link https://docs.github.com/en/rest/reference/actions#workflows
*/
class Workflows extends AbstractApi
{
/**
* @link https://docs.github.com/en/rest/reference/actions#list-repository-workflows
*
* @param string $username
* @param string $repository
* @param array $parameters
*
* @return array
*/
public function all(string $username, string $repository, array $parameters = [])
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/workflows', $parameters);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-a-workflow
*
* @param string $username
* @param string $repository
* @param string|int $workflow
*
* @return array
*/
public function show(string $username, string $repository, $workflow)
{
if (is_string($workflow)) {
$workflow = rawurlencode($workflow);
}
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/workflows/'.$workflow);
}
/**
* @link https://docs.github.com/en/rest/reference/actions#get-workflow-usage
*
* @param string $username
* @param string $repository
* @param string|int $workflow
*
* @return array|string
*/
public function usage(string $username, string $repository, $workflow)
{
if (is_string($workflow)) {
$workflow = rawurlencode($workflow);
}
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/workflows/'.$workflow.'/timing');
}
/**
* @link https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event
*
* @param string $username
* @param string $repository
* @param string|int $workflow
* @param string $ref
* @param array $inputs
*
* @return array|string empty
*/
public function dispatches(string $username, string $repository, $workflow, string $ref, array $inputs = null)
{
if (is_string($workflow)) {
$workflow = rawurlencode($workflow);
}
$parameters = array_filter(['ref' => $ref, 'inputs' => $inputs]);
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/actions/workflows/'.$workflow.'/dispatches', $parameters);
}
}

View File

@@ -3,6 +3,7 @@
namespace Github\Api\Repository;
use Github\Api\AbstractApi;
use Github\Api\AcceptHeaderTrait;
use Github\Exception\ErrorException;
use Github\Exception\MissingArgumentException;
@@ -13,6 +14,8 @@ use Github\Exception\MissingArgumentException;
*/
class Assets extends AbstractApi
{
use AcceptHeaderTrait;
/**
* Get all release's assets in selected repository
* GET /repos/:owner/:repo/releases/:id/assets.
@@ -25,7 +28,7 @@ class Assets extends AbstractApi
*/
public function all($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id).'/assets');
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id.'/assets');
}
/**
@@ -36,11 +39,15 @@ class Assets extends AbstractApi
* @param string $repository the name of the repo
* @param int $id the id of the asset
*
* @return array
* @return array|string
*/
public function show($username, $repository, $id)
public function show($username, $repository, $id, bool $returnBinaryContent = false)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id));
if ($returnBinaryContent) {
$this->acceptHeaderValue = 'application/octet-stream';
}
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.$id);
}
/**
@@ -67,16 +74,14 @@ class Assets extends AbstractApi
*/
public function create($username, $repository, $id, $name, $contentType, $content)
{
if (!defined('OPENSSL_TLSEXT_SERVER_NAME') || !OPENSSL_TLSEXT_SERVER_NAME) {
throw new ErrorException('Asset upload support requires Server Name Indication. This is not supported by your PHP version. See http://php.net/manual/en/openssl.constsni.php.');
if (!defined('OPENSSL_TLSEXT_SERVER_NAME') || OPENSSL_TLSEXT_SERVER_NAME == 0) {
throw new ErrorException('Asset upload support requires Server Name Indication. This is not supported by your PHP version. See https://www.php.net/manual/en/openssl.constsni.php.');
}
// Asset creation requires a separate endpoint, uploads.github.com.
// Change the base url for the HTTP client temporarily while we execute
// this request.
$response = $this->postRaw('https://uploads.github.com/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id).'/assets?name='.$name, $content, ['Content-Type' => $contentType]);
return $response;
return $this->postRaw('https://uploads.github.com/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id.'/assets?name='.$name, $content, ['Content-Type' => $contentType]);
}
/**
@@ -98,7 +103,7 @@ class Assets extends AbstractApi
throw new MissingArgumentException('name');
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.$id, $params);
}
/**
@@ -113,6 +118,6 @@ class Assets extends AbstractApi
*/
public function remove($username, $repository, $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.rawurlencode($id));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/assets/'.$id);
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Github\Api\Repository\Checks;
use Github\Api\AbstractApi;
use Github\Api\AcceptHeaderTrait;
/**
* @link https://docs.github.com/en/rest/reference/checks
*/
class CheckRuns extends AbstractApi
{
use AcceptHeaderTrait;
/**
* @link https://docs.github.com/en/rest/reference/checks#create-a-check-run
*
* @return array
*/
public function create(string $username, string $repository, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-runs', $params);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#get-a-check-run
*
* @return array
*/
public function show(string $username, string $repository, int $checkRunId)
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-runs/'.$checkRunId);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#update-a-check-run
*
* @return array
*/
public function update(string $username, string $repository, int $checkRunId, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-runs/'.$checkRunId, $params);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#list-check-run-annotations
*
* @return array
*/
public function annotations(string $username, string $repository, int $checkRunId)
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-runs/'.$checkRunId.'/annotations');
}
/**
* @link https://docs.github.com/en/rest/reference/checks#list-check-runs-in-a-check-suite
*
* @return array
*/
public function allForCheckSuite(string $username, string $repository, int $checkSuiteId, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-suites/'.$checkSuiteId.'/check-runs', $params);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#list-check-runs-for-a-git-reference
*
* @return array
*/
public function allForReference(string $username, string $repository, string $ref, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits/'.rawurlencode($ref).'/check-runs', $params);
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Github\Api\Repository\Checks;
use Github\Api\AbstractApi;
use Github\Api\AcceptHeaderTrait;
/**
* @link https://docs.github.com/en/rest/reference/checks
*/
class CheckSuites extends AbstractApi
{
use AcceptHeaderTrait;
/**
* @link https://docs.github.com/en/rest/reference/checks#create-a-check-suite
*
* @return array
*/
public function create(string $username, string $repository, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-suites', $params);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#update-repository-preferences-for-check-suites
*
* @return array
*/
public function updatePreferences(string $username, string $repository, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-suites/preferences', $params);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#get-a-check-suite
*
* @return array
*/
public function getCheckSuite(string $username, string $repository, int $checkSuiteId)
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-suites/'.$checkSuiteId);
}
/**
* @link https://docs.github.com/en/rest/reference/checks#rerequest-a-check-suite
*
* @return array
*/
public function rerequest(string $username, string $repository, int $checkSuiteId)
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/check-suites/'.$checkSuiteId.'/rerequest');
}
/**
* @link https://docs.github.com/en/rest/reference/checks#list-check-suites-for-a-git-reference
*
* @return array
*/
public function allForReference(string $username, string $repository, string $ref, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.antiope-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/commits/'.rawurlencode($ref).'/check-suites', $params);
}
}

View File

@@ -23,7 +23,7 @@ class Comments extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -31,7 +31,7 @@ class Comments extends AbstractApi
$bodyType = 'full';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s+json', $this->getApiVersion(), $bodyType);
return $this;
}

View File

@@ -25,7 +25,7 @@ class Contents extends AbstractApi
*
* @param string|null $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
@@ -33,7 +33,7 @@ class Contents extends AbstractApi
$bodyType = 'raw';
}
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s', $this->client->getApiVersion(), $bodyType);
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.%s', $this->getApiVersion(), $bodyType);
return $this;
}
@@ -45,7 +45,7 @@ class Contents extends AbstractApi
*
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param null|string $reference reference to a branch or commit
* @param string|null $reference reference to a branch or commit
*
* @return array information for README file
*/
@@ -63,8 +63,8 @@ class Contents extends AbstractApi
*
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param null|string $path path to file or directory
* @param null|string $reference reference to a branch or commit
* @param string|null $path path to file or directory
* @param string|null $reference reference to a branch or commit
*
* @return array|string information for file | information for each item in directory
*/
@@ -90,7 +90,7 @@ class Contents extends AbstractApi
* @param string $path path to file
* @param string $content contents of the new file
* @param string $message the commit message
* @param null|string $branch name of a branch
* @param string|null $branch name of a branch
* @param null|array $committer information about the committer
*
* @throws MissingArgumentException
@@ -102,8 +102,8 @@ class Contents extends AbstractApi
$url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path);
$parameters = [
'content' => base64_encode($content),
'message' => $message,
'content' => base64_encode($content),
'message' => $message,
];
if (null !== $branch) {
@@ -126,7 +126,7 @@ class Contents extends AbstractApi
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $path path of file to check
* @param null|string $reference reference to a branch or commit
* @param string|null $reference reference to a branch or commit
*
* @return bool
*/
@@ -166,7 +166,7 @@ class Contents extends AbstractApi
* @param string $content contents of the new file
* @param string $message the commit message
* @param string $sha blob SHA of the file being replaced
* @param null|string $branch name of a branch
* @param string|null $branch name of a branch
* @param null|array $committer information about the committer
*
* @throws MissingArgumentException
@@ -178,9 +178,9 @@ class Contents extends AbstractApi
$url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path);
$parameters = [
'content' => base64_encode($content),
'message' => $message,
'sha' => $sha,
'content' => base64_encode($content),
'message' => $message,
'sha' => $sha,
];
if (null !== $branch) {
@@ -207,7 +207,7 @@ class Contents extends AbstractApi
* @param string $path path to file
* @param string $message the commit message
* @param string $sha blob SHA of the file being deleted
* @param null|string $branch name of a branch
* @param string|null $branch name of a branch
* @param null|array $committer information about the committer
*
* @throws MissingArgumentException
@@ -219,8 +219,8 @@ class Contents extends AbstractApi
$url = '/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/contents/'.rawurlencode($path);
$parameters = [
'message' => $message,
'sha' => $sha,
'message' => $message,
'sha' => $sha,
];
if (null !== $branch) {
@@ -245,7 +245,7 @@ class Contents extends AbstractApi
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $format format of archive: tarball or zipball
* @param null|string $reference reference to a branch or commit
* @param string|null $reference reference to a branch or commit
*
* @return string repository archive binary data
*/
@@ -265,12 +265,12 @@ class Contents extends AbstractApi
* @param string $username the user who owns the repository
* @param string $repository the name of the repository
* @param string $path path to file
* @param null|string $reference reference to a branch or commit
* @param string|null $reference reference to a branch or commit
*
* @throws InvalidArgumentException If $path is not a file or if its encoding is different from base64
* @throws ErrorException If $path doesn't include a 'content' index
*
* @return null|string content of file, or null in case of base64_decode failure
* @return string|null content of file, or null in case of base64_decode failure
*/
public function download($username, $repository, $path, $reference = null)
{

View File

@@ -37,7 +37,9 @@ class DeployKeys extends AbstractApi
throw new MissingArgumentException(['title', 'key']);
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/keys/'.rawurlencode($id), $params);
$this->remove($username, $repository, $id);
return $this->create($username, $repository, $params);
}
public function remove($username, $repository, $id)

View File

@@ -39,7 +39,7 @@ class Downloads extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/downloads/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/downloads/'.$id);
}
/**
@@ -55,6 +55,6 @@ class Downloads extends AbstractApi
*/
public function remove($username, $repository, $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/downloads/'.rawurlencode($id));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/downloads/'.$id);
}
}

View File

@@ -47,7 +47,7 @@ class Hooks extends AbstractApi
public function test($username, $repository, $id)
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/hooks/'.rawurlencode($id).'/test');
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/hooks/'.rawurlencode($id).'/tests');
}
public function remove($username, $repository, $id)

View File

@@ -33,10 +33,6 @@ class Labels extends AbstractApi
public function update($username, $repository, $label, array $params)
{
if (!isset($params['name'], $params['color'])) {
throw new MissingArgumentException(['name', 'color']);
}
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/labels/'.rawurlencode($label), $params);
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Github\Api\Repository;
use Github\Api\AbstractApi;
use Github\Api\AcceptHeaderTrait;
/**
* @link https://developer.github.com/v3/repos/pages/
*
* @author yunwuxin <tzzhangyajun@qq.com>
*/
class Pages extends AbstractApi
{
use AcceptHeaderTrait;
public function show($username, $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages');
}
public function enable($username, $repository, array $params = [])
{
$this->acceptHeaderValue = 'application/vnd.github.switcheroo-preview+json';
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages', $params);
}
public function disable($username, $repository)
{
$this->acceptHeaderValue = 'application/vnd.github.switcheroo-preview+json';
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages');
}
public function update($username, $repository, array $params = [])
{
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages', $params);
}
public function requestBuild($username, $repository)
{
return $this->post('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages/builds');
}
public function builds($username, $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages/builds');
}
public function showLatestBuild($username, $repository)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages/builds/latest');
}
public function showBuild($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/pages/builds/'.rawurlencode($id));
}
}

View File

@@ -14,13 +14,6 @@ class Protection extends AbstractApi
{
use AcceptHeaderTrait;
public function configure()
{
$this->acceptHeaderValue = 'application/vnd.github.loki-preview+json';
return $this;
}
/**
* Retrieves configured protection for the provided branch.
*
@@ -34,6 +27,9 @@ class Protection extends AbstractApi
*/
public function show($username, $repository, $branch)
{
// Preview endpoint
$this->acceptHeaderValue = 'application/vnd.github.luke-cage-preview+json';
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/branches/'.rawurlencode($branch).'/protection');
}
@@ -51,6 +47,9 @@ class Protection extends AbstractApi
*/
public function update($username, $repository, $branch, array $params = [])
{
// Preview endpoint
$this->acceptHeaderValue = 'application/vnd.github.luke-cage-preview+json';
return $this->put('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/branches/'.rawurlencode($branch).'/protection', $params);
}

View File

@@ -65,7 +65,7 @@ class Releases extends AbstractApi
*/
public function show($username, $repository, $id)
{
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id));
return $this->get('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id);
}
/**
@@ -100,7 +100,7 @@ class Releases extends AbstractApi
*/
public function edit($username, $repository, $id, array $params)
{
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id), $params);
return $this->patch('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id, $params);
}
/**
@@ -114,7 +114,7 @@ class Releases extends AbstractApi
*/
public function remove($username, $repository, $id)
{
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.rawurlencode($id));
return $this->delete('/repos/'.rawurlencode($username).'/'.rawurlencode($repository).'/releases/'.$id);
}
/**
@@ -122,6 +122,6 @@ class Releases extends AbstractApi
*/
public function assets()
{
return new Assets($this->client);
return new Assets($this->getClient());
}
}

View File

@@ -22,12 +22,12 @@ class Stargazers extends AbstractApi
*
* @param string $bodyType
*
* @return self
* @return $this
*/
public function configure($bodyType = null)
{
if ('star' === $bodyType) {
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.star+json', $this->client->getApiVersion());
$this->acceptHeaderValue = sprintf('application/vnd.github.%s.star+json', $this->getApiVersion());
}
return $this;

View File

@@ -61,6 +61,21 @@ class Search extends AbstractApi
return $this->get('/search/code', ['q' => $q, 'sort' => $sort, 'order' => $order]);
}
/**
* Search code by filter (q), but will return additional data to highlight
* the matched results.
*
* @link https://docs.github.com/en/rest/reference/search#text-match-metadata
*
* @return array list of code found
*/
public function codeWithMatch(string $q, string $sort = 'updated', string $order = 'desc'): array
{
$this->acceptHeaderValue = 'application/vnd.github.v3.text-match+json';
return $this->code($q, $sort, $order);
}
/**
* Search users by filter (q).
*
@@ -90,14 +105,14 @@ class Search extends AbstractApi
*/
public function commits($q, $sort = null, $order = 'desc')
{
//This api is in preview mode, so set the correct accept-header
// This api is in preview mode, so set the correct accept-header
$this->acceptHeaderValue = 'application/vnd.github.cloak-preview';
return $this->get('/search/commits', ['q' => $q, 'sort' => $sort, 'order' => $order]);
}
/**
* Search commits by filter (q).
* Search topics by filter (q).
*
* @link https://developer.github.com/v3/search/#search-topics
*
@@ -107,7 +122,7 @@ class Search extends AbstractApi
*/
public function topics($q)
{
//This api is in preview mode, so set the correct accept-header
// This api is in preview mode, so set the correct accept-header
$this->acceptHeaderValue = 'application/vnd.github.mercy-preview+json';
return $this->get('/search/topics', ['q' => $q]);

View File

@@ -12,21 +12,6 @@ namespace Github\Api;
*/
class User extends AbstractApi
{
/**
* Search users by username.
*
* @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-users
*
* @param string $keyword the keyword to search
*
* @return array list of users found
*/
public function find($keyword)
{
return $this->get('/legacy/user/search/'.rawurlencode($keyword));
}
/**
* Request all users.
*
@@ -42,7 +27,7 @@ class User extends AbstractApi
return $this->get('/users');
}
return $this->get('/users', ['since' => rawurldecode($id)]);
return $this->get('/users', ['since' => $id]);
}
/**
@@ -59,6 +44,21 @@ class User extends AbstractApi
return $this->get('/users/'.rawurlencode($username));
}
/**
* Get extended information about a user by its id.
* Note: at time of writing this is an undocumented feature but GitHub support have advised that it can be relied on.
*
* @link http://developer.github.com/v3/users/
*
* @param int $id the id of the user to show
*
* @return array information about the user
*/
public function showById($id)
{
return $this->get('/user/'.$id);
}
/**
* Get extended information about a user by its username.
*
@@ -117,20 +117,6 @@ class User extends AbstractApi
return $this->get('/users/'.rawurlencode($username).'/followers', $parameters, $requestHeaders);
}
/**
* Request the repository that a specific user is watching.
*
* @deprecated see subscriptions method
*
* @param string $username the username
*
* @return array list of watched repositories
*/
public function watched($username)
{
return $this->get('/users/'.rawurlencode($username).'/watched');
}
/**
* Request starred repositories that a specific user has starred.
*
@@ -248,4 +234,16 @@ class User extends AbstractApi
{
return $this->get('/users/'.rawurlencode($username).'/events/public');
}
/**
* List events performed by an authenticated user.
*
* @link https://docs.github.com/en/rest/reference/activity#list-events-for-the-authenticated-user
*
* @return array
*/
public function events(string $username)
{
return $this->get('/users/'.rawurlencode($username).'/events');
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Github;
final class AuthMethod
{
/**
* Authenticate using a client_id/client_secret combination.
*
* @var string
*/
public const CLIENT_ID = 'client_id_header';
/**
* Authenticate using a GitHub access token.
*
* @var string
*/
public const ACCESS_TOKEN = 'access_token_header';
/**
* Constant for authentication method.
*
* Indicates JSON Web Token authentication required for GitHub apps access
* to the API.
*
* @var string
*/
public const JWT = 'jwt';
}

View File

@@ -2,7 +2,7 @@
namespace Github;
use Github\Api\ApiInterface;
use Github\Api\AbstractApi;
use Github\Exception\BadMethodCallException;
use Github\Exception\InvalidArgumentException;
use Github\HttpClient\Builder;
@@ -10,58 +10,58 @@ use Github\HttpClient\Plugin\Authentication;
use Github\HttpClient\Plugin\GithubExceptionThrower;
use Github\HttpClient\Plugin\History;
use Github\HttpClient\Plugin\PathPrepend;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\Common\HttpMethodsClientInterface;
use Http\Client\Common\Plugin;
use Http\Client\HttpClient;
use Http\Discovery\UriFactoryDiscovery;
use Http\Discovery\Psr17FactoryDiscovery;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
/**
* Simple yet very cool PHP GitHub client.
*
* @method Api\CurrentUser currentUser()
* @method Api\CurrentUser me()
* @method Api\Enterprise ent()
* @method Api\Enterprise enterprise()
* @method Api\Miscellaneous\CodeOfConduct codeOfConduct()
* @method Api\Miscellaneous\Emojis emojis()
* @method Api\Miscellaneous\Licenses licenses()
* @method Api\GitData git()
* @method Api\GitData gitData()
* @method Api\Gists gist()
* @method Api\Gists gists()
* @method Api\Miscellaneous\Gitignore gitignore()
* @method Api\Integrations integration() (deprecated)
* @method Api\Integrations integrations() (deprecated)
* @method Api\Apps apps()
* @method Api\Issue issue()
* @method Api\Issue issues()
* @method Api\Markdown markdown()
* @method Api\Notification notification()
* @method Api\Notification notifications()
* @method Api\Organization organization()
* @method Api\Organization organizations()
* @method Api\Organization\Projects orgProject()
* @method Api\Organization\Projects orgProjects()
* @method Api\Organization\Projects organizationProject()
* @method Api\Organization\Projects organizationProjects()
* @method Api\PullRequest pr()
* @method Api\PullRequest pullRequest()
* @method Api\PullRequest pullRequests()
* @method Api\RateLimit rateLimit()
* @method Api\Repo repo()
* @method Api\Repo repos()
* @method Api\Repo repository()
* @method Api\Repo repositories()
* @method Api\Search search()
* @method Api\Organization\Teams team()
* @method Api\Organization\Teams teams()
* @method Api\User user()
* @method Api\User users()
* @method Api\Authorizations authorization()
* @method Api\Authorizations authorizations()
* @method Api\Meta meta()
* @method Api\GraphQL graphql()
* @method Api\CurrentUser currentUser()
* @method Api\CurrentUser me()
* @method Api\Enterprise ent()
* @method Api\Enterprise enterprise()
* @method Api\Miscellaneous\CodeOfConduct codeOfConduct()
* @method Api\Miscellaneous\Emojis emojis()
* @method Api\Miscellaneous\Licenses licenses()
* @method Api\GitData git()
* @method Api\GitData gitData()
* @method Api\Gists gist()
* @method Api\Gists gists()
* @method Api\Miscellaneous\Gitignore gitignore()
* @method Api\Apps apps()
* @method Api\Issue issue()
* @method Api\Issue issues()
* @method Api\Markdown markdown()
* @method Api\Notification notification()
* @method Api\Notification notifications()
* @method Api\Organization organization()
* @method Api\Organization organizations()
* @method Api\Organization\Projects orgProject()
* @method Api\Organization\Projects orgProjects()
* @method Api\Organization\Projects organizationProject()
* @method Api\Organization\Projects organizationProjects()
* @method Api\Organization\OutsideCollaborators outsideCollaborators()
* @method Api\PullRequest pr()
* @method Api\PullRequest pullRequest()
* @method Api\PullRequest pullRequests()
* @method Api\RateLimit rateLimit()
* @method Api\Repo repo()
* @method Api\Repo repos()
* @method Api\Repo repository()
* @method Api\Repo repositories()
* @method Api\Search search()
* @method Api\Organization\Teams team()
* @method Api\Organization\Teams teams()
* @method Api\User user()
* @method Api\User users()
* @method Api\Authorizations authorization()
* @method Api\Authorizations authorizations()
* @method Api\Meta meta()
* @method Api\GraphQL graphql()
*
* @author Joseph Bielawski <stloyd@gmail.com>
*
@@ -70,34 +70,34 @@ use Psr\Cache\CacheItemPoolInterface;
class Client
{
/**
* Constant for authentication method. Indicates the default, but deprecated
* login with username and token in URL.
* Authenticate using a client_id/client_secret combination.
*
* @var string
*
* @deprecated Use the AuthMethod const
*/
const AUTH_URL_TOKEN = 'url_token';
const AUTH_CLIENT_ID = AuthMethod::CLIENT_ID;
/**
* Constant for authentication method. Not indicates the new login, but allows
* usage of unauthenticated rate limited requests for given client_id + client_secret.
* Authenticate using a GitHub access token.
*
* @var string
*
* @deprecated Use the AuthMethod const
*/
const AUTH_URL_CLIENT_ID = 'url_client_id';
const AUTH_ACCESS_TOKEN = AuthMethod::ACCESS_TOKEN;
/**
* Constant for authentication method. Indicates the new favored login method
* with username and password via HTTP Authentication.
* Constant for authentication method.
*
* Indicates JSON Web Token authentication required for GitHub apps access
* to the API.
*
* @var string
*
* @deprecated Use the AuthMethod const
*/
const AUTH_HTTP_PASSWORD = 'http_password';
/**
* Constant for authentication method. Indicates the new login method with
* with username and token via HTTP Authentication.
*/
const AUTH_HTTP_TOKEN = 'http_token';
/**
* Constant for authentication method. Indicates JSON Web Token
* authentication required for integration access to the API.
*/
const AUTH_JWT = 'jwt';
const AUTH_JWT = AuthMethod::JWT;
/**
* @var string
@@ -124,32 +124,31 @@ class Client
public function __construct(Builder $httpClientBuilder = null, $apiVersion = null, $enterpriseUrl = null)
{
$this->responseHistory = new History();
$this->httpClientBuilder = $builder = $httpClientBuilder ?: new Builder();
$this->httpClientBuilder = $builder = $httpClientBuilder ?? new Builder();
$this->apiVersion = $apiVersion ?: 'v3';
$builder->addPlugin(new GithubExceptionThrower());
$builder->addPlugin(new Plugin\HistoryPlugin($this->responseHistory));
$builder->addPlugin(new Plugin\RedirectPlugin());
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://api.github.com')));
$builder->addPlugin(new Plugin\AddHostPlugin(Psr17FactoryDiscovery::findUriFactory()->createUri('https://api.github.com')));
$builder->addPlugin(new Plugin\HeaderDefaultsPlugin([
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)',
'Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion),
]));
$this->apiVersion = $apiVersion ?: 'v3';
$builder->addHeaderValue('Accept', sprintf('application/vnd.github.%s+json', $this->apiVersion));
if ($enterpriseUrl) {
$this->setEnterpriseUrl($enterpriseUrl);
}
}
/**
* Create a Github\Client using a HttpClient.
* Create a Github\Client using a HTTP client.
*
* @param HttpClient $httpClient
* @param ClientInterface $httpClient
*
* @return Client
*/
public static function createWithHttpClient(HttpClient $httpClient)
public static function createWithHttpClient(ClientInterface $httpClient): self
{
$builder = new Builder($httpClient);
@@ -161,9 +160,9 @@ class Client
*
* @throws InvalidArgumentException
*
* @return ApiInterface
* @return AbstractApi
*/
public function api($name)
public function api($name): AbstractApi
{
switch ($name) {
case 'me':
@@ -204,11 +203,6 @@ class Client
$api = new Api\Miscellaneous\Gitignore($this);
break;
case 'integration':
case 'integrations':
$api = new Api\Integrations($this);
break;
case 'apps':
$api = new Api\Apps($this);
break;
@@ -300,6 +294,11 @@ class Client
$api = new Api\GraphQL($this);
break;
case 'outsideCollaborators':
case 'outside_collaborators':
$api = new Api\Organization\OutsideCollaborators($this);
break;
default:
throw new InvalidArgumentException(sprintf('Undefined api instance called: "%s"', $name));
}
@@ -311,24 +310,22 @@ class Client
* Authenticate a user for all next requests.
*
* @param string $tokenOrLogin GitHub private token/username/client ID
* @param null|string $password GitHub password/secret (optionally can contain $authMethod)
* @param null|string $authMethod One of the AUTH_* class constants
* @param string|null $password GitHub password/secret (optionally can contain $authMethod)
* @param string|null $authMethod One of the AUTH_* class constants
*
* @throws InvalidArgumentException If no authentication method was given
*
* @return void
*/
public function authenticate($tokenOrLogin, $password = null, $authMethod = null)
public function authenticate($tokenOrLogin, $password = null, $authMethod = null): void
{
if (null === $password && null === $authMethod) {
throw new InvalidArgumentException('You need to specify authentication method!');
}
if (null === $authMethod && in_array($password, [self::AUTH_URL_TOKEN, self::AUTH_URL_CLIENT_ID, self::AUTH_HTTP_PASSWORD, self::AUTH_HTTP_TOKEN, self::AUTH_JWT], true)) {
if (null === $authMethod && (AuthMethod::JWT === $password || AuthMethod::ACCESS_TOKEN === $password)) {
$authMethod = $password;
$password = null;
}
if (null === $authMethod) {
$authMethod = self::AUTH_HTTP_PASSWORD;
throw new InvalidArgumentException('You need to specify authentication method!');
}
$this->getHttpClientBuilder()->removePlugin(Authentication::class);
@@ -339,21 +336,30 @@ class Client
* Sets the URL of your GitHub Enterprise instance.
*
* @param string $enterpriseUrl URL of the API in the form of http(s)://hostname
*
* @return void
*/
private function setEnterpriseUrl($enterpriseUrl)
private function setEnterpriseUrl($enterpriseUrl): void
{
$builder = $this->getHttpClientBuilder();
$builder->removePlugin(Plugin\AddHostPlugin::class);
$builder->removePlugin(PathPrepend::class);
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri($enterpriseUrl)));
$builder->addPlugin(new PathPrepend(sprintf('/api/%s', $this->getApiVersion())));
$builder->addPlugin(new Plugin\AddHostPlugin(Psr17FactoryDiscovery::findUriFactory()->createUri($enterpriseUrl)));
// For GHE, v4 API endpoint is at `api/graphql` so we don't want to add the version number
// For earlier versions add the version number after /api
if ($this->getApiVersion() === 'v4') {
$builder->addPlugin(new PathPrepend('/api'));
} else {
$builder->addPlugin(new PathPrepend(sprintf('/api/%s', $this->getApiVersion())));
}
}
/**
* @return string
*/
public function getApiVersion()
public function getApiVersion(): string
{
return $this->apiVersion;
}
@@ -363,28 +369,31 @@ class Client
*
* @param CacheItemPoolInterface $cachePool
* @param array $config
*
* @return void
*/
public function addCache(CacheItemPoolInterface $cachePool, array $config = [])
public function addCache(CacheItemPoolInterface $cachePool, array $config = []): void
{
$this->getHttpClientBuilder()->addCache($cachePool, $config);
}
/**
* Remove the cache plugin.
*
* @return void
*/
public function removeCache()
public function removeCache(): void
{
$this->getHttpClientBuilder()->removeCache();
}
/**
* @param string $name
* @param array $args
*
* @throws BadMethodCallException
*
* @return ApiInterface
* @return AbstractApi
*/
public function __call($name, $args)
public function __call($name, $args): AbstractApi
{
try {
return $this->api($name);
@@ -396,15 +405,15 @@ class Client
/**
* @return null|\Psr\Http\Message\ResponseInterface
*/
public function getLastResponse()
public function getLastResponse(): ?ResponseInterface
{
return $this->responseHistory->getLastResponse();
}
/**
* @return HttpMethodsClient
* @return HttpMethodsClientInterface
*/
public function getHttpClient()
public function getHttpClient(): HttpMethodsClientInterface
{
return $this->getHttpClientBuilder()->getHttpClient();
}
@@ -412,7 +421,7 @@ class Client
/**
* @return Builder
*/
protected function getHttpClientBuilder()
protected function getHttpClientBuilder(): Builder
{
return $this->httpClientBuilder;
}

View File

@@ -2,17 +2,25 @@
namespace Github\Exception;
use Throwable;
/**
* ApiLimitExceedException.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class ApiLimitExceedException extends RuntimeException
{
/** @var int */
private $limit;
/** @var int */
private $reset;
public function __construct($limit = 5000, $reset = 1800, $code = 0, $previous = null)
/**
* @param int $limit
* @param int $reset
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(int $limit = 5000, int $reset = 1800, int $code = 0, Throwable $previous = null)
{
$this->limit = (int) $limit;
$this->reset = (int) $reset;
@@ -20,12 +28,18 @@ class ApiLimitExceedException extends RuntimeException
parent::__construct(sprintf('You have reached GitHub hourly limit! Actual limit is: %d', $limit), $code, $previous);
}
public function getLimit()
/**
* @return int
*/
public function getLimit(): int
{
return $this->limit;
}
public function getResetTime()
/**
* @return int
*/
public function getResetTime(): int
{
return $this->reset;
}

View File

@@ -3,8 +3,6 @@
namespace Github\Exception;
/**
* BadMethodCallException.
*
* @author James Brooks <jbrooksuk@me.com>
*/
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface

View File

@@ -3,8 +3,6 @@
namespace Github\Exception;
/**
* ErrorException.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class ErrorException extends \ErrorException implements ExceptionInterface

View File

@@ -3,8 +3,6 @@
namespace Github\Exception;
/**
* InvalidArgumentException.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface

View File

@@ -2,19 +2,24 @@
namespace Github\Exception;
use Throwable;
/**
* MissingArgumentException.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class MissingArgumentException extends ErrorException
{
public function __construct($required, $code = 0, $previous = null)
/**
* @param string|array $required
* @param int $code
* @param Throwable|null $previous
*/
public function __construct($required, int $code = 0, Throwable $previous = null)
{
if (is_string($required)) {
$required = [$required];
}
parent::__construct(sprintf('One or more of required ("%s") parameters is missing!', implode('", "', $required)), $code, $previous);
parent::__construct(sprintf('One or more of required ("%s") parameters is missing!', implode('", "', $required)), $code, 1, __FILE__, __LINE__, $previous);
}
}

View File

@@ -3,8 +3,6 @@
namespace Github\Exception;
/**
* RuntimeException.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class RuntimeException extends \RuntimeException implements ExceptionInterface

View File

@@ -0,0 +1,31 @@
<?php
namespace Github\Exception;
use Throwable;
class SsoRequiredException extends RuntimeException
{
/** @var string */
private $url;
/**
* @param string $url
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(string $url, int $code = 0, Throwable $previous = null)
{
$this->url = $url;
parent::__construct('Resource protected by organization SAML enforcement. You must grant your personal token access to this organization.', $code, $previous);
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
}

View File

@@ -2,17 +2,28 @@
namespace Github\Exception;
use Throwable;
class TwoFactorAuthenticationRequiredException extends RuntimeException
{
/** @var string */
private $type;
public function __construct($type, $code = 0, $previous = null)
/**
* @param string $type
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(string $type, int $code = 0, Throwable $previous = null)
{
$this->type = $type;
parent::__construct('Two factor authentication is enabled on this account', $code, $previous);
}
public function getType()
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}

View File

@@ -3,16 +3,16 @@
namespace Github\HttpClient;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\Common\HttpMethodsClientInterface;
use Http\Client\Common\Plugin;
use Http\Client\Common\Plugin\Cache\Generator\HeaderCacheKeyGenerator;
use Http\Client\Common\PluginClientFactory;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\StreamFactoryDiscovery;
use Http\Message\RequestFactory;
use Http\Message\StreamFactory;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
/**
* A builder that builds the API client.
@@ -25,24 +25,24 @@ class Builder
/**
* The object that sends HTTP messages.
*
* @var HttpClient
* @var ClientInterface
*/
private $httpClient;
/**
* A HTTP client with all our plugins.
*
* @var HttpMethodsClient
* @var HttpMethodsClientInterface
*/
private $pluginClient;
/**
* @var RequestFactory
* @var RequestFactoryInterface
*/
private $requestFactory;
/**
* @var StreamFactory
* @var StreamFactoryInterface
*/
private $streamFactory;
@@ -73,24 +73,24 @@ class Builder
private $headers = [];
/**
* @param HttpClient $httpClient
* @param RequestFactory $requestFactory
* @param StreamFactory $streamFactory
* @param ClientInterface|null $httpClient
* @param RequestFactoryInterface|null $requestFactory
* @param StreamFactoryInterface|null $streamFactory
*/
public function __construct(
HttpClient $httpClient = null,
RequestFactory $requestFactory = null,
StreamFactory $streamFactory = null
ClientInterface $httpClient = null,
RequestFactoryInterface $requestFactory = null,
StreamFactoryInterface $streamFactory = null
) {
$this->httpClient = $httpClient ?: HttpClientDiscovery::find();
$this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find();
$this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
$this->httpClient = $httpClient ?? Psr18ClientDiscovery::find();
$this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory();
$this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory();
}
/**
* @return HttpMethodsClient
* @return HttpMethodsClientInterface
*/
public function getHttpClient()
public function getHttpClient(): HttpMethodsClientInterface
{
if ($this->httpClientModified) {
$this->httpClientModified = false;
@@ -102,7 +102,8 @@ class Builder
$this->pluginClient = new HttpMethodsClient(
(new PluginClientFactory())->createClient($this->httpClient, $plugins),
$this->requestFactory
$this->requestFactory,
$this->streamFactory
);
}
@@ -113,8 +114,10 @@ class Builder
* Add a new plugin to the end of the plugin chain.
*
* @param Plugin $plugin
*
* @return void
*/
public function addPlugin(Plugin $plugin)
public function addPlugin(Plugin $plugin): void
{
$this->plugins[] = $plugin;
$this->httpClientModified = true;
@@ -124,8 +127,10 @@ class Builder
* Remove a plugin by its fully qualified class name (FQCN).
*
* @param string $fqcn
*
* @return void
*/
public function removePlugin($fqcn)
public function removePlugin(string $fqcn): void
{
foreach ($this->plugins as $idx => $plugin) {
if ($plugin instanceof $fqcn) {
@@ -137,8 +142,10 @@ class Builder
/**
* Clears used headers.
*
* @return void
*/
public function clearHeaders()
public function clearHeaders(): void
{
$this->headers = [];
@@ -148,8 +155,10 @@ class Builder
/**
* @param array $headers
*
* @return void
*/
public function addHeaders(array $headers)
public function addHeaders(array $headers): void
{
$this->headers = array_merge($this->headers, $headers);
@@ -160,8 +169,10 @@ class Builder
/**
* @param string $header
* @param string $headerValue
*
* @return void
*/
public function addHeaderValue($header, $headerValue)
public function addHeaderValue(string $header, string $headerValue): void
{
if (!isset($this->headers[$header])) {
$this->headers[$header] = $headerValue;
@@ -178,8 +189,10 @@ class Builder
*
* @param CacheItemPoolInterface $cachePool
* @param array $config
*
* @return void
*/
public function addCache(CacheItemPoolInterface $cachePool, array $config = [])
public function addCache(CacheItemPoolInterface $cachePool, array $config = []): void
{
if (!isset($config['cache_key_generator'])) {
$config['cache_key_generator'] = new HeaderCacheKeyGenerator(['Authorization', 'Cookie', 'Accept', 'Content-type']);
@@ -190,8 +203,10 @@ class Builder
/**
* Remove the cache plugin.
*
* @return void
*/
public function removeCache()
public function removeCache(): void
{
$this->cachePlugin = null;
$this->httpClientModified = true;

View File

@@ -5,7 +5,7 @@ namespace Github\HttpClient\Message;
use Github\Exception\ApiLimitExceedException;
use Psr\Http\Message\ResponseInterface;
class ResponseMediator
final class ResponseMediator
{
/**
* @param ResponseInterface $response
@@ -28,19 +28,21 @@ class ResponseMediator
/**
* @param ResponseInterface $response
*
* @return array|void
* @return array<string,string>
*/
public static function getPagination(ResponseInterface $response)
public static function getPagination(ResponseInterface $response): array
{
if (!$response->hasHeader('Link')) {
return;
$header = self::getHeader($response, 'Link');
if (null === $header) {
return [];
}
$header = self::getHeader($response, 'Link');
$pagination = [];
foreach (explode(',', $header) as $link) {
preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match);
/** @var string[] $match */
if (3 === count($match)) {
$pagination[$match[2]] = $match[1];
}
@@ -52,17 +54,23 @@ class ResponseMediator
/**
* @param ResponseInterface $response
*
* @return null|string
* @return string|null
*/
public static function getApiLimit(ResponseInterface $response)
public static function getApiLimit(ResponseInterface $response): ?string
{
$remainingCalls = self::getHeader($response, 'X-RateLimit-Remaining');
$remainingCallsHeader = self::getHeader($response, 'X-RateLimit-Remaining');
if (null !== $remainingCalls && 1 > $remainingCalls) {
if (null === $remainingCallsHeader) {
return null;
}
$remainingCalls = (int) $remainingCallsHeader;
if (1 > $remainingCalls) {
throw new ApiLimitExceedException($remainingCalls);
}
return $remainingCalls;
return $remainingCallsHeader;
}
/**
@@ -73,7 +81,7 @@ class ResponseMediator
*
* @return string|null
*/
public static function getHeader(ResponseInterface $response, $name)
public static function getHeader(ResponseInterface $response, string $name): ?string
{
$headers = $response->getHeader($name);

View File

@@ -2,9 +2,10 @@
namespace Github\HttpClient\Plugin;
use Github\Client;
use Github\AuthMethod;
use Github\Exception\RuntimeException;
use Http\Client\Common\Plugin;
use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;
/**
@@ -12,13 +13,29 @@ use Psr\Http\Message\RequestInterface;
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Authentication implements Plugin
final class Authentication implements Plugin
{
/**
* @var string
*/
private $tokenOrLogin;
/**
* @var string|null
*/
private $password;
/**
* @var string|null
*/
private $method;
public function __construct($tokenOrLogin, $password, $method)
/**
* @param string $tokenOrLogin GitHub private token/username/client ID
* @param string|null $password GitHub password/secret (optionally can contain $method)
* @param string|null $method One of the AUTH_* class constants
*/
public function __construct(string $tokenOrLogin, ?string $password, ?string $method)
{
$this->tokenOrLogin = $tokenOrLogin;
$this->password = $password;
@@ -26,60 +43,29 @@ class Authentication implements Plugin
}
/**
* {@inheritdoc}
* @return Promise
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
{
switch ($this->method) {
case Client::AUTH_HTTP_PASSWORD:
$request = $request->withHeader(
'Authorization',
sprintf('Basic %s', base64_encode($this->tokenOrLogin.':'.$this->password))
);
break;
case Client::AUTH_HTTP_TOKEN:
$request = $request->withHeader('Authorization', sprintf('token %s', $this->tokenOrLogin));
break;
case Client::AUTH_URL_CLIENT_ID:
$uri = $request->getUri();
$query = $uri->getQuery();
$parameters = [
'client_id' => $this->tokenOrLogin,
'client_secret' => $this->password,
];
$query .= empty($query) ? '' : '&';
$query .= utf8_encode(http_build_query($parameters, '', '&'));
$uri = $uri->withQuery($query);
$request = $request->withUri($uri);
break;
case Client::AUTH_URL_TOKEN:
$uri = $request->getUri();
$query = $uri->getQuery();
$parameters = ['access_token' => $this->tokenOrLogin];
$query .= empty($query) ? '' : '&';
$query .= utf8_encode(http_build_query($parameters, '', '&'));
$uri = $uri->withQuery($query);
$request = $request->withUri($uri);
break;
case Client::AUTH_JWT:
$request = $request->withHeader('Authorization', sprintf('Bearer %s', $this->tokenOrLogin));
break;
default:
throw new RuntimeException(sprintf('%s not yet implemented', $this->method));
break;
}
$request = $request->withHeader(
'Authorization',
$this->getAuthorizationHeader()
);
return $next($request);
}
private function getAuthorizationHeader(): string
{
switch ($this->method) {
case AuthMethod::CLIENT_ID:
return sprintf('Basic %s', base64_encode($this->tokenOrLogin.':'.$this->password));
case AuthMethod::ACCESS_TOKEN:
return sprintf('token %s', $this->tokenOrLogin);
case AuthMethod::JWT:
return sprintf('Bearer %s', $this->tokenOrLogin);
default:
throw new RuntimeException(sprintf('%s not yet implemented', $this->method));
}
}
}

View File

@@ -5,10 +5,12 @@ namespace Github\HttpClient\Plugin;
use Github\Exception\ApiLimitExceedException;
use Github\Exception\ErrorException;
use Github\Exception\RuntimeException;
use Github\Exception\SsoRequiredException;
use Github\Exception\TwoFactorAuthenticationRequiredException;
use Github\Exception\ValidationFailedException;
use Github\HttpClient\Message\ResponseMediator;
use Http\Client\Common\Plugin;
use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
@@ -16,23 +18,25 @@ use Psr\Http\Message\ResponseInterface;
* @author Joseph Bielawski <stloyd@gmail.com>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class GithubExceptionThrower implements Plugin
final class GithubExceptionThrower implements Plugin
{
/**
* {@inheritdoc}
* @return Promise
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
{
return $next($request)->then(function (ResponseInterface $response) use ($request) {
if ($response->getStatusCode() < 400 || $response->getStatusCode() > 600) {
$this->checkGraphqlErrors($response);
return $response;
}
// If error:
$remaining = ResponseMediator::getHeader($response, 'X-RateLimit-Remaining');
if (null !== $remaining && 1 > $remaining && 'rate_limit' !== substr($request->getRequestTarget(), 1, 10)) {
$limit = ResponseMediator::getHeader($response, 'X-RateLimit-Limit');
$reset = ResponseMediator::getHeader($response, 'X-RateLimit-Reset');
if ((429 === $response->getStatusCode()) && null !== $remaining && 1 > $remaining && 'rate_limit' !== substr($request->getRequestTarget(), 1, 10)) {
$limit = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Limit');
$reset = (int) ResponseMediator::getHeader($response, 'X-RateLimit-Reset');
throw new ApiLimitExceedException($limit, $reset);
}
@@ -46,13 +50,13 @@ class GithubExceptionThrower implements Plugin
$content = ResponseMediator::getContent($response);
if (is_array($content) && isset($content['message'])) {
if (400 === $response->getStatusCode()) {
throw new ErrorException($content['message'], 400);
throw new ErrorException(sprintf('%s (%s)', $content['message'], $response->getReasonPhrase()), 400);
}
if (422 === $response->getStatusCode() && isset($content['errors'])) {
$errors = [];
foreach ($content['errors'] as $error) {
switch ($error['code']) {
switch ($error['code'] ?? null) {
case 'missing':
$errors[] = sprintf('The %s %s does not exist, for resource "%s"', $error['field'], $error['value'], $error['resource']);
break;
@@ -74,13 +78,24 @@ class GithubExceptionThrower implements Plugin
break;
default:
$errors[] = $error['message'];
if (is_string($error)) {
$errors[] = $error;
break;
}
if (isset($error['message'])) {
$errors[] = $error['message'];
}
break;
}
}
throw new ValidationFailedException('Validation Failed: '.implode(', ', $errors), 422);
throw new ValidationFailedException(
$errors ? 'Validation Failed: '.implode(', ', $errors) : 'Validation Failed',
422
);
}
}
@@ -95,7 +110,51 @@ class GithubExceptionThrower implements Plugin
throw new RuntimeException(implode(', ', $errors), 502);
}
if ((403 === $response->getStatusCode()) && $response->hasHeader('X-GitHub-SSO') && 0 === strpos((string) ResponseMediator::getHeader($response, 'X-GitHub-SSO'), 'required;')) {
// The header will look something like this:
// required; url=https://github.com/orgs/octodocs-test/sso?authorization_request=AZSCKtL4U8yX1H3sCQIVnVgmjmon5fWxks5YrqhJgah0b2tlbl9pZM4EuMz4
// So we strip out the first 14 characters, leaving only the URL.
// @see https://developer.github.com/v3/auth/#authenticating-for-saml-sso
$url = substr((string) ResponseMediator::getHeader($response, 'X-GitHub-SSO'), 14);
throw new SsoRequiredException($url);
}
throw new RuntimeException(isset($content['message']) ? $content['message'] : $content, $response->getStatusCode());
});
}
/**
* The graphql api doesn't return a 5xx http status for errors. Instead it returns a 200 with an error body.
*
* @throws RuntimeException
*/
private function checkGraphqlErrors(ResponseInterface $response): void
{
if ($response->getStatusCode() !== 200) {
return;
}
$content = ResponseMediator::getContent($response);
if (!is_array($content)) {
return;
}
if (!isset($content['errors']) || !is_array($content['errors'])) {
return;
}
$errors = [];
foreach ($content['errors'] as $error) {
if (isset($error['message'])) {
$errors[] = $error['message'];
}
}
if (empty($errors)) {
return;
}
throw new RuntimeException(implode(', ', $errors));
}
}

View File

@@ -3,7 +3,7 @@
namespace Github\HttpClient\Plugin;
use Http\Client\Common\Plugin\Journal;
use Http\Client\Exception;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
@@ -12,27 +12,33 @@ use Psr\Http\Message\ResponseInterface;
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class History implements Journal
final class History implements Journal
{
/**
* @var ResponseInterface
* @var ResponseInterface|null
*/
private $lastResponse;
/**
* @return ResponseInterface|null
*/
public function getLastResponse()
public function getLastResponse(): ?ResponseInterface
{
return $this->lastResponse;
}
public function addSuccess(RequestInterface $request, ResponseInterface $response)
/**
* @return void
*/
public function addSuccess(RequestInterface $request, ResponseInterface $response): void
{
$this->lastResponse = $response;
}
public function addFailure(RequestInterface $request, Exception $exception)
/**
* @return void
*/
public function addFailure(RequestInterface $request, ClientExceptionInterface $exception): void
{
}
}

View File

@@ -3,6 +3,7 @@
namespace Github\HttpClient\Plugin;
use Http\Client\Common\Plugin;
use Http\Promise\Promise;
use Psr\Http\Message\RequestInterface;
/**
@@ -10,22 +11,29 @@ use Psr\Http\Message\RequestInterface;
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class PathPrepend implements Plugin
final class PathPrepend implements Plugin
{
/**
* @var string
*/
private $path;
/**
* @param string $path
*/
public function __construct($path)
public function __construct(string $path)
{
$this->path = $path;
}
/**
* {@inheritdoc}
* @param RequestInterface $request
* @param callable $next
* @param callable $first
*
* @return Promise
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise
{
$currentPath = $request->getUri()->getPath();
if (strpos($currentPath, $this->path) !== 0) {

View File

@@ -2,36 +2,51 @@
namespace Github;
use Github\Api\ApiInterface;
use Github\Api\Search;
use Closure;
use Generator;
use Github\Api\AbstractApi;
use Github\HttpClient\Message\ResponseMediator;
use ValueError;
/**
* Pager class for supporting pagination in github classes.
*
* @author Ramon de la Fuente <ramon@future500.nl>
* @author Mitchel Verschoof <mitchel@future500.nl>
* @author Graham Campbell <graham@alt-three.com>
*/
class ResultPager implements ResultPagerInterface
{
/**
* The GitHub Client to use for pagination.
* The default number of entries to request per page.
*
* @var \Github\Client
* @var int
*/
protected $client;
private const PER_PAGE = 100;
/**
* Comes from pagination headers in Github API results.
* The client to use for pagination.
*
* @var array
* @var Client
*/
protected $pagination;
private $client;
/**
* The Github client to use for pagination.
* The number of entries to request per page.
*
* This must be the same instance that you got the Api instance from.
* @var int
*/
private $perPage;
/**
* The pagination result from the API.
*
* @var array<string,string>
*/
private $pagination;
/**
* Create a new result pager instance.
*
* Example code:
*
@@ -39,90 +54,103 @@ class ResultPager implements ResultPagerInterface
* $api = $client->api('someApi');
* $pager = new \Github\ResultPager($client);
*
* @param \Github\Client $client
* @param Client $client
* @param int|null $perPage
*
* @return void
*/
public function __construct(Client $client)
public function __construct(Client $client, int $perPage = null)
{
$this->client = $client;
}
/**
* {@inheritdoc}
*/
public function getPagination()
{
return $this->pagination;
}
/**
* {@inheritdoc}
*/
public function fetch(ApiInterface $api, $method, array $parameters = [])
{
$result = $this->callApi($api, $method, $parameters);
$this->postFetch();
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchAll(ApiInterface $api, $method, array $parameters = [])
{
$isSearch = $api instanceof Search;
// get the perPage from the api
$perPage = $api->getPerPage();
// set parameters per_page to GitHub max to minimize number of requests
$api->setPerPage(100);
try {
$result = $this->callApi($api, $method, $parameters);
$this->postFetch();
if ($isSearch) {
$result = isset($result['items']) ? $result['items'] : $result;
}
while ($this->hasNext()) {
$next = $this->fetchNext();
if ($isSearch) {
$result = array_merge($result, $next['items']);
} else {
$result = array_merge($result, $next);
}
}
} finally {
// restore the perPage
$api->setPerPage($perPage);
if (null !== $perPage && ($perPage < 1 || $perPage > 100)) {
throw new ValueError(sprintf('%s::__construct(): Argument #2 ($perPage) must be between 1 and 100, or null', self::class));
}
$this->client = $client;
$this->perPage = $perPage ?? self::PER_PAGE;
$this->pagination = [];
}
/**
* {@inheritdoc}
*/
public function fetch(AbstractApi $api, string $method, array $parameters = []): array
{
$paginatorPerPage = $this->perPage;
$closure = Closure::bind(function (AbstractApi $api) use ($paginatorPerPage) {
$clone = clone $api;
$clone->perPage = $paginatorPerPage;
return $clone;
}, null, AbstractApi::class);
$api = $closure($api);
$result = $api->$method(...$parameters);
$this->postFetch(true);
return $result;
}
/**
* {@inheritdoc}
*/
public function postFetch()
public function fetchAll(AbstractApi $api, string $method, array $parameters = []): array
{
$this->pagination = ResponseMediator::getPagination($this->client->getLastResponse());
return iterator_to_array($this->fetchAllLazy($api, $method, $parameters));
}
/**
* {@inheritdoc}
*/
public function hasNext()
public function fetchAllLazy(AbstractApi $api, string $method, array $parameters = []): Generator
{
return $this->has('next');
$result = $this->fetch($api, $method, $parameters);
foreach ($result['items'] ?? $result as $key => $item) {
if (is_string($key)) {
yield $key => $item;
} else {
yield $item;
}
}
while ($this->hasNext()) {
$result = $this->fetchNext();
foreach ($result['items'] ?? $result as $key => $item) {
if (is_string($key)) {
yield $key => $item;
} else {
yield $item;
}
}
}
}
/**
* {@inheritdoc}
*/
public function fetchNext()
public function postFetch(/* $skipDeprecation = false */): void
{
if (func_num_args() === 0 || (func_num_args() > 0 && false === func_get_arg(0))) {
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "%s" method is deprecated and will be removed.', __METHOD__);
}
$this->setPagination();
}
/**
* {@inheritdoc}
*/
public function hasNext(): bool
{
return isset($this->pagination['next']);
}
/**
* {@inheritdoc}
*/
public function fetchNext(): array
{
return $this->get('next');
}
@@ -130,15 +158,15 @@ class ResultPager implements ResultPagerInterface
/**
* {@inheritdoc}
*/
public function hasPrevious()
public function hasPrevious(): bool
{
return $this->has('prev');
return isset($this->pagination['prev']);
}
/**
* {@inheritdoc}
*/
public function fetchPrevious()
public function fetchPrevious(): array
{
return $this->get('prev');
}
@@ -146,7 +174,7 @@ class ResultPager implements ResultPagerInterface
/**
* {@inheritdoc}
*/
public function fetchFirst()
public function fetchFirst(): array
{
return $this->get('first');
}
@@ -154,41 +182,31 @@ class ResultPager implements ResultPagerInterface
/**
* {@inheritdoc}
*/
public function fetchLast()
public function fetchLast(): array
{
return $this->get('last');
}
/**
* @param string $key
*/
protected function has($key)
{
return !empty($this->pagination) && isset($this->pagination[$key]);
}
/**
* @param string $key
*/
protected function get($key)
{
if ($this->has($key)) {
$result = $this->client->getHttpClient()->get($this->pagination[$key]);
$this->postFetch();
return ResponseMediator::getContent($result);
}
}
/**
* @param ApiInterface $api
* @param string $method
* @param array $parameters
*
* @return mixed
* @return array
*/
protected function callApi(ApiInterface $api, $method, array $parameters)
protected function get(string $key): array
{
return call_user_func_array([$api, $method], $parameters);
if (!isset($this->pagination[$key])) {
return [];
}
$result = $this->client->getHttpClient()->get($this->pagination[$key]);
$this->postFetch(true);
return ResponseMediator::getContent($result);
}
private function setPagination(): void
{
$this->pagination = ResponseMediator::getPagination($this->client->getLastResponse());
}
}

View File

@@ -2,89 +2,103 @@
namespace Github;
use Github\Api\ApiInterface;
use Generator;
use Github\Api\AbstractApi;
/**
* Pager interface.
*
* @author Ramon de la Fuente <ramon@future500.nl>
* @author Mitchel Verschoof <mitchel@future500.nl>
* @author Graham Campbell <graham@alt-three.com>
*/
interface ResultPagerInterface
{
/**
* @return null|array pagination result of last request
*/
public function getPagination();
/**
* Fetch a single result (page) from an api call.
*
* @param ApiInterface $api the Api instance
* @param string $method the method name to call on the Api instance
* @param array $parameters the method parameters in an array
* @param AbstractApi $api the Api instance
* @param string $method the method name to call on the Api instance
* @param array $parameters the method parameters in an array
*
* @return array returns the result of the Api::$method() call
*/
public function fetch(ApiInterface $api, $method, array $parameters = []);
public function fetch(AbstractApi $api, string $method, array $parameters = []): array;
/**
* Fetch all results (pages) from an api call.
*
* Use with care - there is no maximum.
*
* @param ApiInterface $api the Api instance
* @param string $method the method name to call on the Api instance
* @param array $parameters the method parameters in an array
* @param AbstractApi $api the Api instance
* @param string $method the method name to call on the Api instance
* @param array $parameters the method parameters in an array
*
* @return array returns a merge of the results of the Api::$method() call
*/
public function fetchAll(ApiInterface $api, $method, array $parameters = []);
public function fetchAll(AbstractApi $api, string $method, array $parameters = []): array;
/**
* Lazily fetch all results (pages) from an api call.
*
* Use with care - there is no maximum.
*
* @param AbstractApi $api the Api instance
* @param string $method the method name to call on the Api instance
* @param array $parameters the method parameters in an array
*
* @return \Generator returns a merge of the results of the Api::$method() call
*/
public function fetchAllLazy(AbstractApi $api, string $method, array $parameters = []): Generator;
/**
* Method that performs the actual work to refresh the pagination property.
*
* @deprecated since 3.2 and will be removed in 4.0.
*
* @return void
*/
public function postFetch();
public function postFetch(): void;
/**
* Check to determine the availability of a next page.
*
* @return bool
*/
public function hasNext();
public function hasNext(): bool;
/**
* Check to determine the availability of a previous page.
*
* @return bool
*/
public function hasPrevious();
public function hasPrevious(): bool;
/**
* Fetch the next page.
*
* @return array
*/
public function fetchNext();
public function fetchNext(): array;
/**
* Fetch the previous page.
*
* @return array
*/
public function fetchPrevious();
public function fetchPrevious(): array;
/**
* Fetch the first page.
*
* @return array
*/
public function fetchFirst();
public function fetchFirst(): array;
/**
* Fetch the last page.
*
* @return array
*/
public function fetchLast();
public function fetchLast(): array;
}

View File

@@ -0,0 +1,15 @@
parameters:
checkMissingIterableValueType: false
level: 6
paths:
- lib
ignoreErrors:
# Ignore typehint errors on api classes
-
message: '#Method (.*) with no typehint specified\.#'
path: lib/Github/Api
-
message: '#Method (.*) has no return typehint specified\.#'
path: lib/Github/Api