diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 3d0ed82..0502928 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -1,8 +1,8 @@ in(__DIR__.'/src') - ->in(__DIR__.'/tests') + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') ->exclude('vendor'); $config = new PhpCsFixer\Config(); @@ -11,7 +11,9 @@ '@PSR12' => true, '@PSR12:risky' => true, ]) - ->setRiskyAllowed(true) - ->setUnsupportedPhpVersionAllowed(true); + ->setRiskyAllowed(true); + +// @phpstan-ignore-next-line Method exists but not detected by static analysis +$config->setUnsupportedPhpVersionAllowed(true); return $config; diff --git a/CHANGELOG.md b/CHANGELOG.md index d6beb7e..623a78b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## [3.0.1](https://github.com/calliostro/php-discogs-api/releases/tag/v3.0.1) – 2025-09-09 + +### Added + +- Complete PHPDoc coverage for all 62 Discogs API endpoints +- Missing @method annotations for 22 additional API methods +- Full IDE autocomplete support for inventory, collection, and marketplace operations + +### Fixed + +- Incorrect legacy method mappings in UPGRADE guide +- Missing PHPDoc annotations causing incomplete IDE support +- PSR-12 compliance issues in documentation examples +- Broken `collectionFolder()` method annotation (replaced with working `collectionFolderGet()`) + +### Documentation + +- Updated README with accurate API coverage information +- Enhanced code examples with proper formatting standards +- Collection folder management methods are now properly documented + ## [3.0.0](https://github.com/calliostro/php-discogs-api/releases/tag/v3.0.0) – 2025-09-08 ### Added diff --git a/README.md b/README.md index b3b7786..e4f7554 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ [![Total Downloads](https://img.shields.io/packagist/dt/calliostro/php-discogs-api.svg)](https://packagist.org/packages/calliostro/php-discogs-api) [![License](https://poser.pugx.org/calliostro/php-discogs-api/license)](https://packagist.org/packages/calliostro/php-discogs-api) [![PHP Version](https://img.shields.io/badge/php-%5E8.1-blue.svg)](https://php.net) +[![Guzzle](https://img.shields.io/badge/guzzle-%5E6.5%7C%5E7.0-orange.svg)](https://docs.guzzlephp.org/) [![CI](https://github.com/calliostro/php-discogs-api/actions/workflows/ci.yml/badge.svg)](https://github.com/calliostro/php-discogs-api/actions/workflows/ci.yml) [![Code Coverage](https://codecov.io/gh/calliostro/php-discogs-api/graph/badge.svg?token=0SV4IXE9V1)](https://codecov.io/gh/calliostro/php-discogs-api) [![PHPStan Level](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg)](https://phpstan.org/) [![Code Style](https://img.shields.io/badge/code%20style-PSR12-brightgreen.svg)](https://github.com/FriendsOfPHP/PHP-CS-Fixer) -> **🚀 ONLY 2 CLASSES!** The most lightweight Discogs API client for PHP. Zero bloats, maximum performance. +> **🚀 ONLY 2 CLASSES!** The most lightweight Discogs API client for PHP. Zero bloat, maximum performance. An **ultra-minimalist** Discogs API client that proves you don't need 20+ classes to build a great API client. Built with modern PHP 8.1+ features, service descriptions, and powered by Guzzle. @@ -53,13 +54,31 @@ echo "Release: " . $release['title'] . "\n"; ### Collection and Marketplace ```php +collectionFolders(['username' => 'your-username']); +$folder = $discogs->collectionFolderGet(['username' => 'your-username', 'folder_id' => '1']); $items = $discogs->collectionItems(['username' => 'your-username', 'folder_id' => '0']); +// Add release to a collection +$addResult = $discogs->collectionAddRelease([ + 'username' => 'your-username', + 'folder_id' => '1', + 'release_id' => '249504' +]); + +// Wantlist management +$wantlist = $discogs->wantlistGet(['username' => 'your-username']); +$addToWantlist = $discogs->wantlistAdd([ + 'username' => 'your-username', + 'release_id' => '249504', + 'notes' => 'Looking for mint condition' +]); + // Marketplace operations $inventory = $discogs->inventoryGet(['username' => 'your-username']); $orders = $discogs->ordersGet(['status' => 'Shipped']); @@ -68,13 +87,17 @@ $orders = $discogs->ordersGet(['status' => 'Shipped']); $listing = $discogs->listingCreate([ 'release_id' => '249504', 'condition' => 'Near Mint (NM or M-)', - 'price' => '25.00' + 'sleeve_condition' => 'Very Good Plus (VG+)', + 'price' => '25.00', + 'status' => 'For Sale' ]); ``` ### Database Search and Discovery ```php +search(['q' => 'Pink Floyd', 'type' => 'artist']); $releases = $discogs->artistReleases(['id' => '45031', 'sort' => 'year']); @@ -91,7 +114,7 @@ $labelReleases = $discogs->labelReleases(['id' => '1']); ## ✨ Key Features - **Ultra-Lightweight** – Only 2 classes, ~234 lines of logic + service descriptions -- **Complete API Coverage** – All 65+ Discogs API endpoints supported +- **Complete API Coverage** – All 60+ Discogs API endpoints supported - **Direct API Calls** – `$client->artistGet()` maps to `/artists/{id}`, no abstractions - **Type Safe + IDE Support** – Full PHP 8.1+ types, PHPStan Level 8, method autocomplete - **Future-Ready** – PHP 8.5 compatible (beta/dev testing) @@ -101,16 +124,17 @@ $labelReleases = $discogs->labelReleases(['id' => '1']); ## 🎵 All Discogs API Methods as Direct Calls -- **Database Methods** – search(), artistGet(), releaseGet(), masterGet(), labelGet() -- **Collection Methods** – collectionFolders(), collectionItems(), collectionFolder() -- **Wantlist Methods** – wantlistGet() -- **Marketplace Methods** – inventoryGet(), listingCreate(), listingUpdate(), listingDelete() -- **Order Methods** – ordersGet(), orderGet(), orderUpdate(), orderMessages() -- **User Methods** – identityGet(), userGet() -- **Master Methods** – masterVersions() -- **Label Methods** – labelReleases() +- **Database Methods** – search(), artistGet(), artistReleases(), releaseGet(), releaseRatingGet(), releaseRatingPut(), releaseRatingDelete(), releaseRatingCommunity(), releaseStats(), masterGet(), masterVersions(), labelGet(), labelReleases() +- **User Identity Methods** – identityGet(), userGet(), userEdit(), userSubmissions(), userContributions(), userLists() +- **Collection Methods** – collectionFolders(), collectionFolderGet(), collectionFolderCreate(), collectionFolderEdit(), collectionFolderDelete(), collectionItems(), collectionItemsByRelease(), collectionAddRelease(), collectionEditRelease(), collectionRemoveRelease(), collectionCustomFields(), collectionEditField(), collectionValue() +- **Wantlist Methods** – wantlistGet(), wantlistAdd(), wantlistEdit(), wantlistRemove() +- **Marketplace Methods** – inventoryGet(), listingGet(), listingCreate(), listingUpdate(), listingDelete(), marketplaceFee(), marketplaceFeeCurrency(), marketplacePriceSuggestions(), marketplaceStats() +- **Order Methods** – orderGet(), ordersGet(), orderUpdate(), orderMessages(), orderMessageAdd() +- **Inventory Export Methods** – inventoryExportCreate(), inventoryExportList(), inventoryExportGet(), inventoryExportDownload() +- **Inventory Upload Methods** – inventoryUploadAdd(), inventoryUploadChange(), inventoryUploadDelete(), inventoryUploadList(), inventoryUploadGet() +- **List Methods** – listGet() -*All 65+ Discogs API endpoints are supported with clean documentation — see [Discogs API Documentation](https://www.discogs.com/developers/) for complete method reference* +*All 60+ Discogs API endpoints are supported with clean documentation — see [Discogs API Documentation](https://www.discogs.com/developers/) for complete method reference* ## 📋 Requirements @@ -124,6 +148,8 @@ $labelReleases = $discogs->labelReleases(['id' => '1']); For basic customizations like timeout or User-Agent, use the ClientFactory: ```php +search(['q' => 'Nirvana', 'type' => 'artist']); @@ -80,7 +93,10 @@ $inventory = $client->getInventory(['username' => 'user']); ``` ### After (v3.0): Magic Method Calls + ```php +search(['q' => 'Nirvana', 'type' => 'artist']); @@ -96,45 +112,57 @@ $inventory = $client->inventoryGet(['username' => 'user']); ## Method Name Mapping -| v2.x Command | v3.0 Magic Method | Parameters | -|------------------------------|---------------------|-----------------------------| -| `getArtist` | `artistGet` | `['id' => 'string']` | -| `getArtistReleases` | `artistReleases` | `['id' => 'string']` | -| `getRelease` | `releaseGet` | `['id' => 'string']` | -| `getMaster` | `masterGet` | `['id' => 'string']` | -| `getMasterVersions` | `masterVersions` | `['id' => 'string']` | -| `getLabel` | `labelGet` | `['id' => 'string']` | -| `getLabelReleases` | `labelReleases` | `['id' => 'string']` | -| `search` | `search` | `['q' => 'string']` | -| `getOAuthIdentity` | `identityGet` | `[]` | -| `getProfile` | `userGet` | `['username' => 'string']` | -| `getCollectionFolders` | `collectionFolders` | `['username' => 'string']` | -| `getCollectionFolder` | `collectionFolder` | `['username', 'folder_id']` | -| `getCollectionItemsByFolder` | `collectionItems` | `['username', 'folder_id']` | -| `getInventory` | `inventoryGet` | `['username' => 'string']` | -| `getOrders` | `ordersGet` | `[]` | -| `getOrder` | `orderGet` | `['order_id' => 'string']` | -| `createListing` | `listingCreate` | `[...]` | -| `changeListing` | `listingUpdate` | `[...]` | -| `deleteListing` | `listingDelete` | `[...]` | +| v2.x Command | v3.0 Magic Method | Parameters | +|------------------------------|-------------------------|-----------------------------| +| `getArtist` | `artistGet` | `['id' => 'string']` | +| `getArtistReleases` | `artistReleases` | `['id' => 'string']` | +| `getRelease` | `releaseGet` | `['id' => 'string']` | +| `getMaster` | `masterGet` | `['id' => 'string']` | +| `getMasterVersions` | `masterVersions` | `['id' => 'string']` | +| `getLabel` | `labelGet` | `['id' => 'string']` | +| `getLabelReleases` | `labelReleases` | `['id' => 'string']` | +| `search` | `search` | `['q' => 'string']` | +| `getOAuthIdentity` | `identityGet` | `[]` | +| `getProfile` | `userGet` | `['username' => 'string']` | +| `getCollectionFolders` | `collectionFolders` | `['username' => 'string']` | +| `getCollectionFolder` | `collectionFolderGet` | `['username', 'folder_id']` | +| `getCollectionItemsByFolder` | `collectionItems` | `['username', 'folder_id']` | +| `getInventory` | `inventoryGet` | `['username' => 'string']` | +| `addInventory` | `inventoryUploadAdd` | `[...]` | +| `deleteInventory` | `inventoryUploadDelete` | `[...]` | +| `getOrder` | `orderGet` | `['order_id' => 'string']` | +| `getOrders` | `ordersGet` | `[]` | +| `changeOrder` | `orderUpdate` | `[...]` | +| `getOrderMessages` | `orderMessages` | `['order_id' => 'string']` | +| `addOrderMessage` | `orderMessageAdd` | `[...]` | +| `createListing` | `listingCreate` | `[...]` | +| `changeListing` | `listingUpdate` | `[...]` | +| `deleteListing` | `listingDelete` | `[...]` | +| `getUserLists` | `userLists` | `['username' => 'string']` | +| `getLists` | `listGet` | `['list_id' => 'string']` | +| `getWantlist` | `wantlistGet` | `['username' => 'string']` | ## Configuration Changes ### Service Configuration + - **Before**: Complex Guzzle Services YAML/JSON definitions - **After**: Simple PHP array in `resources/service.php` -### Throttling +### Throttling + - **Before**: `ThrottleSubscriber` with Guzzle middlewares - **After**: Handle rate limiting in your application layer ### Error Handling + - **Before**: Guzzle Services exceptions - **After**: Standard `RuntimeException` with clear messages ## Testing Your Migration 1. **Update composer.json**: + ```json { "require": { diff --git a/composer.json b/composer.json index dbf682d..7ba4c20 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "calliostro/php-discogs-api", - "description": "Ultra-lightweight Discogs API client for PHP 8.1+ — Complete API coverage, minimal dependencies", + "description": "Ultra-lightweight Discogs API client for PHP 8.1+ with modern Guzzle-based implementation — Only two classes, service descriptions, zero bloat", "type": "library", "keywords": [ "php", diff --git a/src/DiscogsApiClient.php b/src/DiscogsApiClient.php index e1c24fa..ec00bdd 100644 --- a/src/DiscogsApiClient.php +++ b/src/DiscogsApiClient.php @@ -17,6 +17,8 @@ * @method array releaseRatingGet(array $params = []) Get release rating — https://www.discogs.com/developers/#page:database,header:database-release-rating-by-user * @method array releaseRatingPut(array $params = []) Set release rating — https://www.discogs.com/developers/#page:database,header:database-release-rating-by-user-post * @method array releaseRatingDelete(array $params = []) Delete release rating — https://www.discogs.com/developers/#page:database,header:database-release-rating-by-user-delete + * @method array releaseRatingCommunity(array $params = []) Get community release rating — https://www.discogs.com/developers/#page:database,header:database-release-rating-community + * @method array releaseStats(array $params = []) Get release statistics — https://www.discogs.com/developers/#page:database,header:database-release-stats * @method array masterGet(array $params = []) Get master release information — https://www.discogs.com/developers/#page:database,header:database-master-release * @method array masterVersions(array $params = []) Get master release versions — https://www.discogs.com/developers/#page:database,header:database-master-release-versions * @method array labelGet(array $params = []) Get label information — https://www.discogs.com/developers/#page:database,header:database-label @@ -27,27 +29,62 @@ * @method array identityGet(array $params = []) Get user identity (OAuth required) — https://www.discogs.com/developers/#page:user-identity * @method array userGet(array $params = []) Get user profile — https://www.discogs.com/developers/#page:user-identity,header:user-identity-profile * @method array userEdit(array $params = []) Edit user profile — https://www.discogs.com/developers/#page:user-identity,header:user-identity-profile-post + * @method array userSubmissions(array $params = []) Get user submissions — https://www.discogs.com/developers/#page:user-identity,header:user-identity-user-submissions + * @method array userContributions(array $params = []) Get user contributions — https://www.discogs.com/developers/#page:user-identity,header:user-identity-user-contributions + * @method array userLists(array $params = []) Get user lists — https://www.discogs.com/developers/#page:user-lists * * Collection methods: * @method array collectionFolders(array $params = []) Get collection folders — https://www.discogs.com/developers/#page:user-collection - * @method array collectionFolder(array $params = []) Get a collection folder — https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-folder + * @method array collectionFolderGet(array $params = []) Get a collection folder — https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-folder + * @method array collectionFolderCreate(array $params = []) Create a collection folder (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-create-folder + * @method array collectionFolderEdit(array $params = []) Edit collection folder (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-edit-folder + * @method array collectionFolderDelete(array $params = []) Delete the collection folder (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-delete-folder * @method array collectionItems(array $params = []) Get collection items by folder — https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-items-by-folder + * @method array collectionItemsByRelease(array $params = []) Get collection instances by release — https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-items-by-release + * @method array collectionAddRelease(array $params = []) Add release to collection (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-add-to-collection-folder + * @method array collectionEditRelease(array $params = []) Edit release in collection (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-change-rating-of-release + * @method array collectionRemoveRelease(array $params = []) Remove release from collection (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-delete-instance-from-folder + * @method array collectionCustomFields(array $params = []) Get collection custom fields — https://www.discogs.com/developers/#page:user-collection,header:user-collection-list-custom-fields + * @method array collectionEditField(array $params = []) Edit collection custom field (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-edit-fields-instance + * @method array collectionValue(array $params = []) Get collection value (OAuth required) — https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-value * * Wantlist methods: * @method array wantlistGet(array $params = []) Get user wantlist — https://www.discogs.com/developers/#page:user-wantlist + * @method array wantlistAdd(array $params = []) Add release to wantlist (OAuth required) — https://www.discogs.com/developers/#page:user-wantlist,header:user-wantlist-add-to-wantlist + * @method array wantlistEdit(array $params = []) Edit wantlist release (OAuth required) — https://www.discogs.com/developers/#page:user-wantlist,header:user-wantlist-edit-notes + * @method array wantlistRemove(array $params = []) Remove release from wantlist (OAuth required) — https://www.discogs.com/developers/#page:user-wantlist,header:user-wantlist-delete-from-wantlist * * Marketplace methods: * @method array inventoryGet(array $params = []) Get user inventory — https://www.discogs.com/developers/#page:marketplace,header:marketplace-inventory - * @method array marketplaceFee(array $params = []) Calculate marketplace fee — https://www.discogs.com/developers/#page:marketplace,header:marketplace-fee * @method array listingGet(array $params = []) Get marketplace listing — https://www.discogs.com/developers/#page:marketplace,header:marketplace-listing * @method array listingCreate(array $params = []) Create marketplace listing (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-new-listing * @method array listingUpdate(array $params = []) Update marketplace listing (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-listing * @method array listingDelete(array $params = []) Delete marketplace listing (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-listing-delete + * @method array marketplaceFee(array $params = []) Calculate marketplace fee — https://www.discogs.com/developers/#page:marketplace,header:marketplace-fee + * @method array marketplaceFeeCurrency(array $params = []) Calculate marketplace fee with currency — https://www.discogs.com/developers/#page:marketplace,header:marketplace-fee-with-currency + * @method array marketplacePriceSuggestions(array $params = []) Get marketplace price suggestions (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-price-suggestions + * @method array marketplaceStats(array $params = []) Get marketplace statistics — https://www.discogs.com/developers/#page:marketplace,header:marketplace-stats * @method array orderGet(array $params = []) Get order details (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-order * @method array ordersGet(array $params = []) Get orders (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-list-orders * @method array orderUpdate(array $params = []) Update order (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-order-post * @method array orderMessages(array $params = []) Get order messages (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-list-order-messages * @method array orderMessageAdd(array $params = []) Add an order message (OAuth required) — https://www.discogs.com/developers/#page:marketplace,header:marketplace-list-order-messages-post + * + * Inventory Export methods: + * @method array inventoryExportCreate(array $params = []) Create inventory export (OAuth required) — https://www.discogs.com/developers/#page:inventory-export + * @method array inventoryExportList(array $params = []) List inventory exports (OAuth required) — https://www.discogs.com/developers/#page:inventory-export + * @method array inventoryExportGet(array $params = []) Get inventory export (OAuth required) — https://www.discogs.com/developers/#page:inventory-export + * @method array inventoryExportDownload(array $params = []) Download inventory export (OAuth required) — https://www.discogs.com/developers/#page:inventory-export + * + * Inventory Upload methods: + * @method array inventoryUploadAdd(array $params = []) Add inventory upload (OAuth required) — https://www.discogs.com/developers/#page:inventory-upload + * @method array inventoryUploadChange(array $params = []) Change inventory upload (OAuth required) — https://www.discogs.com/developers/#page:inventory-upload + * @method array inventoryUploadDelete(array $params = []) Delete inventory upload (OAuth required) — https://www.discogs.com/developers/#page:inventory-upload + * @method array inventoryUploadList(array $params = []) List inventory uploads (OAuth required) — https://www.discogs.com/developers/#page:inventory-upload + * @method array inventoryUploadGet(array $params = []) Get inventory upload (OAuth required) — https://www.discogs.com/developers/#page:inventory-upload + * + * List methods: + * @method array listGet(array $params = []) Get list — https://www.discogs.com/developers/#page:user-lists */ final class DiscogsApiClient {