diff --git a/.gitattributes b/.gitattributes
index cfad1e0..bdc74d0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,11 +2,10 @@
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# Ignore all test and documentation with "export-ignore".
-/.github export-ignore
-/tests export-ignore
-/.editorconfig export-ignore
-/.gitattributes export-ignore
-/.gitignore export-ignore
-/.php_cs.dist export-ignore
-/.php_cs.dist export-ignore
-/phpunit.xml.dist export-ignore
+/.github export-ignore
+/tests export-ignore
+/.editorconfig export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.php-cs-fixer.dist.php export-ignore
+/phpunit.xml.dist export-ignore
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 75108e4..d81e0bf 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,31 +14,33 @@ jobs:
strategy:
fail-fast: false
matrix:
- php-version: [ '7.4', '8.0' ]
+ php-version: [ '8.1', '8.2' ]
allow-failure: [ false ]
coverage: [ false ]
composer-flags: [ '' ]
include:
- - php-version: '7.3'
- coverage: true
- php-version: '8.1'
+ coverage: true
+ - php-version: '8.2'
allow-failure: true
composer-flags: '--ignore-platform-req php'
steps:
- - uses: actions/checkout@v2
+ - name: checkout
+ uses: actions/checkout@v3
- name: php-setup
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
+ coverage: xdebug
- name: composer-validate
run: composer validate
- name: composer-cache
id: composer-cache
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
@@ -53,14 +55,16 @@ jobs:
continue-on-error: ${{ matrix.allow-failure }}
env:
PHP_CS_FIXER_IGNORE_ENV: ${{ matrix.allow-failure }}
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --verbose --config=.php_cs.dist
+ run: vendor/bin/php-cs-fixer fix --dry-run --diff --verbose
- name: phpunit
+ env:
+ XDEBUG_MODE: coverage
run: composer run-script phpunit
- name: coverage
if: ${{ matrix.coverage }}
- uses: codecov/codecov-action@v1
+ uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: ./build
diff --git a/.gitignore b/.gitignore
index ba9bc44..bfbafb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
-build/
-vendor/
+/build/
+/vendor/
composer.lock
-.php_cs
-.php_cs.cache
+.php-cs-fixer.cache
.phpunit.result.cache
phpunit.xml
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
new file mode 100644
index 0000000..4e54172
--- /dev/null
+++ b/.php-cs-fixer.dist.php
@@ -0,0 +1,15 @@
+in(__DIR__)
+;
+
+return (new PhpCsFixer\Config())
+ ->setRules([
+ '@Symfony' => true,
+ '@Symfony:risky' => true,
+ 'declare_strict_types' => true,
+ ])
+ ->setRiskyAllowed(true)
+ ->setFinder($finder)
+;
diff --git a/.php_cs.dist b/.php_cs.dist
deleted file mode 100644
index e65f99b..0000000
--- a/.php_cs.dist
+++ /dev/null
@@ -1,37 +0,0 @@
-in(__DIR__ . '/src')
- ->in(__DIR__ . '/tests')
-;
-
-return PhpCsFixer\Config::create()
- ->setRiskyAllowed(true)
- ->setRules([
- '@Symfony' => true,
- '@PHP71Migration' => true,
- 'binary_operator_spaces' => array(
- 'align_equals' => false,
- 'align_double_arrow' => false,
- ),
- '@Symfony:risky' => true,
- '@PHP71Migration:risky' => true,
- 'array_syntax' => ['syntax' => 'short'],
- 'linebreak_after_opening_tag' => true,
- 'mb_str_functions' => true,
- 'no_php4_constructor' => true,
- 'no_unreachable_default_argument_value' => true,
- 'no_useless_else' => true,
- 'no_useless_return' => true,
- 'ordered_imports' => true,
- 'php_unit_strict' => true,
- 'phpdoc_order' => true,
- 'semicolon_after_instruction' => true,
- 'strict_comparison' => true,
- 'strict_param' => true,
- 'concat_space' => ['spacing' => 'one'],
- 'trailing_comma_in_multiline_array' => true,
- 'yoda_style' => false
- ])
- ->setFinder($finder)
- ->setCacheFile(__DIR__.'/.php_cs.cache');
diff --git a/README.md b/README.md
index 2c9101d..896f150 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
@@ -52,7 +52,7 @@ if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl([
'scope' => [
- Kerox\OAuth2\Client\Provider\Spotify::SCOPE_USER_READ_EMAIL,
+ Kerox\OAuth2\Client\Provider\SpotifyScope::USER_READ_EMAIL->value,
]
]);
@@ -108,26 +108,35 @@ echo '';
### Authorization Scopes
-All scopes described in the [official documentation](https://developer.spotify.com/documentation/general/guides/scopes/) are available through public constants in `\Kerox\OAuth2\Client\Provider\Spotify`:
-
-* SCOPE_UGC_IMAGE_UPLOAD
-* SCOPE_USER_MODIFY_PLAYBACK_STATE
-* SCOPE_USER_READ_PLAYBACK_STATE
-* SCOPE_USER_READ_CURRENTLY_PLAYING
-* SCOPE_USER_TOP_READ
-* SCOPE_USER_READ_RECENTLY_PLAYED
-* SCOPE_USER_LIBRARY_MODIFY
-* SCOPE_USER_LIBRARY_READ
-* SCOPE_USER_FOLLOW_MODIFY
-* SCOPE_USER_FOLLOW_READ
-* SCOPE_PLAYLIST_READ_PRIVATE
-* SCOPE_PLAYLIST_MODIFY_PUBLIC
-* SCOPE_PLAYLIST_MODIFY_PRIVATE
-* SCOPE_PLAYLIST_READ_COLLABORATIVE
-* SCOPE_USER_READ_PRIVATE
-* SCOPE_USER_READ_EMAIL
-* SCOPE_APP_REMOTE_CONTROL
-* SCOPE_STREAMING
+All scopes described in the [official documentation](https://developer.spotify.com/documentation/general/guides/authorization/scopes/) are available through the `\Kerox\OAuth2\Client\Provider\SpotifyScope` enumeration:
+
+- Images
+ * UGC_IMAGE_UPLOAD
+- Spotify Connect
+ * USER_READ_PLAYBACK_STATE
+ * USER_MODIFY_PLAYBACK_STATE
+ * USER_READ_CURRENTLY_PLAYING
+- Playback
+ * APP_REMOTE_CONTROL
+ * STREAMING
+- Playlists
+ * PLAYLIST_READ_PRIVATE
+ * PLAYLIST_READ_COLLABORATIVE
+ * PLAYLIST_MODIFY_PRIVATE
+ * PLAYLIST_MODIFY_PUBLIC
+- Follow
+ * USER_FOLLOW_MODIFY
+ * USER_FOLLOW_READ
+- Listening History
+ * USER_READ_PLAYBACK_POSITION
+ * USER_TOP_READ
+ * USER_READ_RECENTLY_PLAYED
+- Library
+ * USER_LIBRARY_MODIFY
+ * USER_LIBRARY_READ
+- Users
+ * USER_READ_PRIVATE
+ * USER_READ_EMAIL
## Contributing
diff --git a/composer.json b/composer.json
index d9f2b5d..3722db4 100644
--- a/composer.json
+++ b/composer.json
@@ -21,12 +21,12 @@
}
],
"require": {
- "php": ">=7.3",
+ "php": ">=8.1",
"league/oauth2-client": "^2.6"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^2.17",
- "phpunit/phpunit": "^9.0"
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "phpunit/phpunit": "^9.5"
},
"config": {
"optimize-autoloader": true,
@@ -43,7 +43,7 @@
}
},
"scripts": {
- "php-cs-fixer": "vendor/bin/php-cs-fixer fix --diff --verbose --config=.php_cs",
+ "php-cs-fixer": "vendor/bin/php-cs-fixer fix --diff --verbose",
"phpunit": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml"
}
}
diff --git a/src/Provider/Spotify.php b/src/Provider/Spotify.php
index 1cdd629..1014dbd 100644
--- a/src/Provider/Spotify.php
+++ b/src/Provider/Spotify.php
@@ -19,45 +19,9 @@ class Spotify extends AbstractProvider
public const BASE_SPOTIFY_URL = 'https://accounts.spotify.com/';
public const RESPONSE_TYPE = 'code';
- // Available scopes.
-
- // Images
- public const SCOPE_UGC_IMAGE_UPLOAD = 'ugc-image-upload';
-
- // Spotify Connect
- public const SCOPE_USER_MODIFY_PLAYBACK_STATE = 'user-modify-playback-state';
- public const SCOPE_USER_READ_PLAYBACK_STATE = 'user-read-playback-state';
- public const SCOPE_USER_READ_CURRENTLY_PLAYING = 'user-read-currently-playing';
-
- // Listening History
- public const SCOPE_USER_TOP_READ = 'user-top-read';
- public const SCOPE_USER_READ_RECENTLY_PLAYED = 'user-read-recently-played';
-
- // Library
- public const SCOPE_USER_LIBRARY_MODIFY = 'user-library-modify';
- public const SCOPE_USER_LIBRARY_READ = 'user-library-read';
-
- // Follow
- public const SCOPE_USER_FOLLOW_MODIFY = 'user-follow-modify';
- public const SCOPE_USER_FOLLOW_READ = 'user-follow-read';
-
- // Playlist
- public const SCOPE_PLAYLIST_READ_PRIVATE = 'playlist-read-private';
- public const SCOPE_PLAYLIST_MODIFY_PUBLIC = 'playlist-modify-public';
- public const SCOPE_PLAYLIST_MODIFY_PRIVATE = 'playlist-modify-private';
- public const SCOPE_PLAYLIST_READ_COLLABORATIVE = 'playlist-read-collaborative';
-
- // User
- public const SCOPE_USER_READ_PRIVATE = 'user-read-private';
- public const SCOPE_USER_READ_EMAIL = 'user-read-email';
-
- // Playback
- public const SCOPE_APP_REMOTE_CONTROL = 'app-remote-control';
- public const SCOPE_STREAMING = 'streaming';
-
public function __construct(array $options = [], array $collaborators = [])
{
- if (!isset($options['responseType']) || $options['responseType'] !== self::RESPONSE_TYPE) {
+ if (!isset($options['responseType']) || self::RESPONSE_TYPE !== $options['responseType']) {
$options['responseType'] = self::RESPONSE_TYPE;
}
@@ -69,7 +33,7 @@ public function __construct(array $options = [], array $collaborators = [])
*/
public function getBaseAuthorizationUrl(): string
{
- return self::BASE_SPOTIFY_URL . 'authorize';
+ return self::BASE_SPOTIFY_URL.'authorize';
}
/**
@@ -77,7 +41,7 @@ public function getBaseAuthorizationUrl(): string
*/
public function getBaseAccessTokenUrl(array $params): string
{
- return self::BASE_SPOTIFY_URL . 'api/token';
+ return self::BASE_SPOTIFY_URL.'api/token';
}
/**
diff --git a/src/Provider/SpotifyResourceOwner.php b/src/Provider/SpotifyResourceOwner.php
index 7a07db9..ad818c1 100644
--- a/src/Provider/SpotifyResourceOwner.php
+++ b/src/Provider/SpotifyResourceOwner.php
@@ -8,10 +8,7 @@
class SpotifyResourceOwner implements ResourceOwnerInterface
{
- /**
- * @var array
- */
- protected $data;
+ protected array $data;
public function __construct(array $response)
{
@@ -79,7 +76,7 @@ public function getUri(): string
}
/**
- * Return all of the owner details available as an array.
+ * Return all the owner details available as an array.
*/
public function toArray(): array
{
diff --git a/src/Provider/SpotifyScope.php b/src/Provider/SpotifyScope.php
new file mode 100644
index 0000000..67634aa
--- /dev/null
+++ b/src/Provider/SpotifyScope.php
@@ -0,0 +1,43 @@
+resourceOwner = new SpotifyResourceOwner($user);
}
@@ -45,7 +42,7 @@ public function testGetter(): void
public function testToArray(): void
{
- $array = json_decode(file_get_contents(__DIR__ . '/../Mocks/user.json'), true, 512, \JSON_THROW_ON_ERROR);
+ $array = json_decode(file_get_contents(__DIR__.'/../Mocks/user.json'), true, 512, \JSON_THROW_ON_ERROR);
self::assertSame($array, $this->resourceOwner->toArray());
}
diff --git a/tests/Provider/SpotifyTest.php b/tests/Provider/SpotifyTest.php
index 05c19c3..70f4c2f 100644
--- a/tests/Provider/SpotifyTest.php
+++ b/tests/Provider/SpotifyTest.php
@@ -15,16 +15,13 @@ class FooSpotifyProvider extends Spotify
{
protected function fetchResourceOwnerDetails(AccessToken $token)
{
- return json_decode(file_get_contents(__DIR__ . '/../Mocks/user.json'), true, 512, \JSON_THROW_ON_ERROR);
+ return json_decode(file_get_contents(__DIR__.'/../Mocks/user.json'), true, 512, \JSON_THROW_ON_ERROR);
}
}
class SpotifyTest extends TestCase
{
- /**
- * @var \Kerox\OAuth2\Client\Provider\Spotify
- */
- protected $provider;
+ protected Spotify $provider;
protected function setUp(): void
{
@@ -161,12 +158,7 @@ public function testCheckResponseFailureWithRegularError(): void
$this->callMethod('checkResponse', [$response, $data]);
}
- /**
- * @param $name
- *
- * @return mixed|null
- */
- protected function callMethod($name, array $args = [])
+ protected function callMethod(string $name, array $args = []): mixed
{
try {
$reflection = new \ReflectionMethod(\get_class($this->provider), $name);