From 72b2f2a178cab778e40be1d0c58f3f5379fc4231 Mon Sep 17 00:00:00 2001 From: calliostro Date: Thu, 1 Jan 2026 16:24:17 +0100 Subject: [PATCH 1/3] Add support for spotify-web-api-php v7 and migrate to PHP config - Add support for `jwilsson/spotify-web-api-php` v6 and v7 - Migrate service configuration from XML to PHP format (fixes Symfony 7.4+ deprecation) - Align CI workflow with comprehensive PHP 8.2-8.5 and Symfony 6.4-8.0 test matrix --- .github/workflows/ci.yml | 87 +++++++++---------- README.md | 5 +- composer.json | 2 +- .../CalliostroSpotifyWebApiExtension.php | 6 +- src/Resources/config/services.php | 37 ++++++++ src/Resources/config/services.xml | 27 ------ 6 files changed, 87 insertions(+), 77 deletions(-) create mode 100644 src/Resources/config/services.php delete mode 100644 src/Resources/config/services.xml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 781a014..87f435d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,17 @@ name: CI on: push: - branches: [ master, main ] + branches: + - 'main' + - 'legacy/*' + - 'feature/*' + - 'hotfix/*' + - 'release/*' pull_request: - branches: [ master, main ] + branches: + - 'main' + - 'legacy/*' + workflow_dispatch: jobs: test: @@ -14,65 +22,60 @@ jobs: fail-fast: false matrix: include: - # Core PHP version testing - - php: '8.1' - allowed-to-fail: false + # Symfony 6.4 LTS compatibility - php: '8.2' + symfony-version: '6.4.*' allowed-to-fail: false - php: '8.3' + symfony-version: '6.4.*' allowed-to-fail: false - php: '8.4' + symfony-version: '6.4.*' allowed-to-fail: false - # Symfony 6.4 LTS compatibility + # Symfony 7.x current versions - php: '8.2' - symfony-version: '^6.4' + symfony-version: '7.0.*' allowed-to-fail: false - php: '8.3' - symfony-version: '^6.4' + symfony-version: '7.0.*' allowed-to-fail: false - php: '8.4' - symfony-version: '^6.4' - allowed-to-fail: false - - # Symfony 7.x current versions - - php: '8.2' - symfony-version: '^7.0' + symfony-version: '7.0.*' allowed-to-fail: false - php: '8.3' - symfony-version: '^7.0' + symfony-version: '7.1.*' allowed-to-fail: false - - php: '8.2' - symfony-version: '^7.1' + - php: '8.4' + symfony-version: '7.1.*' allowed-to-fail: false - - php: '8.3' - symfony-version: '^7.1' + - php: '8.4' + symfony-version: '7.2.*' allowed-to-fail: false - - php: '8.3' - symfony-version: '^7.2' + - php: '8.4' + symfony-version: '7.3.*' allowed-to-fail: false - - php: '8.3' - symfony-version: '^7.3' + - php: '8.4' + symfony-version: '7.4.*' allowed-to-fail: false - # Future releases (November 2025) - PHP 8.5 + Symfony 8.0 - - php: '8.5' - symfony-version: '^8.0' - stability: 'dev' - allowed-to-fail: true - - # Additional future compatibility tests + # Symfony 8.0 - Requires PHP 8.4+ - php: '8.4' - symfony-version: '^8.0' - stability: 'dev' - allowed-to-fail: true + symfony-version: '8.0.*' + allowed-to-fail: false - # Development stability test - - php: '8.4' - stability: 'dev' - allowed-to-fail: true + # PHP 8.5 with various Symfony versions + - php: '8.5' + symfony-version: '7.3.*' + allowed-to-fail: false + - php: '8.5' + symfony-version: '7.4.*' + allowed-to-fail: false + - php: '8.5' + symfony-version: '8.0.*' + allowed-to-fail: false - name: "PHP ${{ matrix.php }}${{ matrix.symfony-version && format(' | Symfony {0}', matrix.symfony-version) || '' }}${{ matrix.composer-flags && format(' | {0}', matrix.composer-flags) || '' }}${{ matrix.stability && format(' | {0}', matrix.stability) || '' }}" + name: "PHP ${{ matrix.php }}${{ matrix.symfony-version && format(' | Symfony {0}', matrix.symfony-version) || '' }}" continue-on-error: ${{ matrix.allowed-to-fail }} @@ -99,12 +102,6 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Configure stability - if: matrix.stability - run: | - composer config minimum-stability ${{ matrix.stability }} - composer config prefer-stable true - - name: Configure Symfony version if: matrix.symfony-version run: | @@ -118,7 +115,7 @@ jobs: run: rm -f composer.lock - name: Install dependencies - run: composer update ${{ matrix.composer-flags }} --prefer-dist --no-interaction --no-progress + run: composer update --prefer-dist --no-interaction --no-progress - name: Validate composer.json run: composer validate --strict --no-check-lock diff --git a/README.md b/README.md index 730cbca..d1b7f9d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ ## ✨ Features - Simple integration with Symfony 6.4, 7 & 8 +- Supports [jwilsson/spotify-web-api-php](https://github.com/jwilsson/spotify-web-api-php) v6 & v7 - Supports Client Credentials & Authorization Code flows - Autowire Spotify API services - Customizable token provider @@ -54,7 +55,7 @@ return [ ## ⚙️ Configuration -First, you must register your application at https://developer.spotify.com/dashboard/applications to obtain the `client_id` and `client_secret`. +First, you must register your application at to obtain the `client_id` and `client_secret`. If you want to access user-related endpoints, the user must grant access to your application. Spotify provides OAuth 2.0 for this purpose. You need to register the `redirect_uri` in the Spotify dashboard. For the following example, you would add `https://127.0.0.1:8000/callback/` to the allowlist addresses. @@ -202,9 +203,11 @@ Implemented a missing feature? You can request it. And creating a pull request i --- ## 🏁 Quick Start + 1. Install the bundle with Composer 2. Configure your Spotify credentials 3. Autowire the service and start using the API! ## 💬 Support + For questions or help, feel free to open an issue or reach out! 😊 diff --git a/composer.json b/composer.json index c6ba11c..5c790e2 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ ], "require": { "php": "^8.1", - "jwilsson/spotify-web-api-php": "^6.0", + "jwilsson/spotify-web-api-php": "^6.0|^7.0", "symfony/config": "^6.4|^7.0|^8.0", "symfony/dependency-injection": "^6.4|^7.0|^8.0", "symfony/http-kernel": "^6.4|^7.0|^8.0" diff --git a/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php b/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php index c52753e..8cf85a0 100644 --- a/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php +++ b/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php @@ -5,15 +5,15 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; -use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; final class CalliostroSpotifyWebApiExtension extends Extension { public function load(array $configs, ContainerBuilder $container): void { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.xml'); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader->load('services.php'); $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); diff --git a/src/Resources/config/services.php b/src/Resources/config/services.php new file mode 100644 index 0000000..c8cd64d --- /dev/null +++ b/src/Resources/config/services.php @@ -0,0 +1,37 @@ +services(); + + $services->set('calliostro_spotify_web_api.session', Session::class) + ->public() + ->args([ + null, // client_id - set by extension + null, // client_secret - set by extension + null, // redirect_uri - set by extension + ]); + + $services->set('calliostro_spotify_web_api.token_provider', TokenProvider::class) + ->args([ + null, // session - set by extension + ]); + + $services->set('calliostro_spotify_web_api', SpotifyWebAPI::class) + ->public() + ->factory([SpotifyWebApiFactory::class, 'factory']) + ->args([ + null, // token_provider - set by extension + null, // options - set by extension + ]); + + // Aliases for autowiring + $services->alias(Session::class, 'calliostro_spotify_web_api.session'); + $services->alias(SpotifyWebAPI::class, 'calliostro_spotify_web_api'); +}; diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml deleted file mode 100644 index 6e097bf..0000000 --- a/src/Resources/config/services.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - From 155f66a2014dece7fc7aa157112c5155414e71ad Mon Sep 17 00:00:00 2001 From: calliostro Date: Thu, 1 Jan 2026 16:39:54 +0100 Subject: [PATCH 2/3] Fix PHPStan issues by removing null placeholders from service config Remove ull argument placeholders from services.php to avoid PHPStan errors in consuming projects. Use setArguments() instead of eplaceArgument() in the extension since arguments are no longer predefined. --- .../CalliostroSpotifyWebApiExtension.php | 19 +++++++++++------ src/Resources/config/services.php | 21 ++++++------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php b/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php index 8cf85a0..f0defc0 100644 --- a/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php +++ b/src/DependencyInjection/CalliostroSpotifyWebApiExtension.php @@ -18,16 +18,23 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); + // Set arguments instead of replacing them since services.php doesn't define them $container->getDefinition('calliostro_spotify_web_api.session') - ->replaceArgument(0, $config['client_id']) - ->replaceArgument(1, $config['client_secret']) - ->replaceArgument(2, $config['redirect_uri']); + ->setArguments([ + $config['client_id'], + $config['client_secret'], + $config['redirect_uri'], + ]); $container->getDefinition('calliostro_spotify_web_api.token_provider') - ->replaceArgument(0, new Reference('calliostro_spotify_web_api.session')); + ->setArguments([ + new Reference('calliostro_spotify_web_api.session'), + ]); $container->getDefinition('calliostro_spotify_web_api') - ->replaceArgument(0, new Reference($config['token_provider'])) - ->replaceArgument(1, $config['options']); + ->setArguments([ + new Reference($config['token_provider']), + $config['options'], + ]); } } diff --git a/src/Resources/config/services.php b/src/Resources/config/services.php index c8cd64d..c065244 100644 --- a/src/Resources/config/services.php +++ b/src/Resources/config/services.php @@ -10,26 +10,17 @@ return static function (ContainerConfigurator $configurator): void { $services = $configurator->services(); + // Session service - arguments will be set by the extension $services->set('calliostro_spotify_web_api.session', Session::class) - ->public() - ->args([ - null, // client_id - set by extension - null, // client_secret - set by extension - null, // redirect_uri - set by extension - ]); + ->public(); - $services->set('calliostro_spotify_web_api.token_provider', TokenProvider::class) - ->args([ - null, // session - set by extension - ]); + // Token provider - arguments will be set by the extension + $services->set('calliostro_spotify_web_api.token_provider', TokenProvider::class); + // Main Spotify Web API service - arguments will be set by the extension $services->set('calliostro_spotify_web_api', SpotifyWebAPI::class) ->public() - ->factory([SpotifyWebApiFactory::class, 'factory']) - ->args([ - null, // token_provider - set by extension - null, // options - set by extension - ]); + ->factory([SpotifyWebApiFactory::class, 'factory']); // Aliases for autowiring $services->alias(Session::class, 'calliostro_spotify_web_api.session'); From cab46ada11da33f27eecb5e0407855f17eb72e59 Mon Sep 17 00:00:00 2001 From: calliostro Date: Thu, 1 Jan 2026 17:13:10 +0100 Subject: [PATCH 3/3] Add PHP 8.1 support with Symfony 6.4 compatibility in CI configuration --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87f435d..fb0f241 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,9 @@ jobs: matrix: include: # Symfony 6.4 LTS compatibility + - php: '8.1' + symfony-version: '6.4.*' + allowed-to-fail: false - php: '8.2' symfony-version: '6.4.*' allowed-to-fail: false