Refactor SDK: entity contracts, new entities, and docs - #17
Conversation
…ntation Introduce CRUD contracts (Creatable, Deletable, Gettable, Listable, Updatable) as interfaces to replace monolithic Entity base class. Add Playlist, Playout, and Subtitle entities. Remove MediaClipList (consolidated into MediaClip). Update Channel and MediaClip with full CRUD support. Rewrite README with comprehensive usage documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r edge cases Cover the remaining untested paths to reach 100% class coverage: - Test getResponseBody() on HTTPRequestException (via assertIsOk) - Test uploadProgressGenerator maxIterations exceeded - Test getAbsoluteVideoPathAsync directly - Test executeUploadAsync missing required keys validation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover the last uncovered line: the UnexpectedValueException thrown when the mediaclip response does not contain a 'src' field. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- create-release-branch: manual dispatch to create release/v*.* branches - create-release: manual dispatch from release branch to create GitHub Release with auto-incrementing patch version Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ghultink
left a comment
There was a problem hiding this comment.
Looks good overall — clean contract design, consistent new entities, good security improvement with LIBXML_NONET.
One bug to fix: removing the CRUD methods from the Entity base class introduces an infinite recursion risk. For entities that don't implement CRUD contracts (e.g. Thumbnail), calling $sdk->thumbnail->get(1) will cause AutoAsyncToSyncCaller::__call to check method_exists($this, 'getAsync') → false → falls through to call_user_func_array([$this, 'get'], ...) → triggers __call again → stack overflow.
Previously the base class threw NotImplementedException. Consider adding a guard in __call (e.g. check for recursion or throw a clean error when the async method doesn't exist or re-adding minimal fallbacks to the base class.
EOF
)
ghultink
left a comment
There was a problem hiding this comment.
Additional issue: the Playout entity maps to /sapi/player, but player and playout are separate SAPI entities. This should use /sapi/playout instead.
…date dependencies - Fix AutoAsyncToSyncCaller to throw BadMethodCallException for undefined methods instead of recursing, while preserving access to protected methods - Fix Playout entity to use /sapi/playout instead of /sapi/player - Update composer dependencies to resolve PHP 8.4 deprecation warnings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover the previously untested code path where __call throws BadMethodCallException for methods that don't exist and have no async counterpart. Fixes 100% class coverage requirement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Creatable,Deletable,Gettable,Listable,Updatable) as interfaces, replacing the monolithic Entity base classPlaylist,Playout, andSubtitlewith full CRUD supportMediaClipList(consolidated intoPlaylist), updateChannelandMediaClipwith contract-based CRUDResponseandHTTPRequestExceptionPlaylistTest,PlayoutTest,SubtitleTest)Test plan
composer testto verify all unit tests pass🤖 Generated with Claude Code