Feat: PHP 8.4, Laravel 12/13, a test suite and CI - #3
Merged
Merged
Conversation
The dynamic scopes were half broken. `Post::unpublished()` forwarded the method name to the scope instead of the stamp name, so the scope looked up `unpublished` in the stamp list, found nothing, and queried a column called null; the positive form only worked because there the method name happens to equal the stamp name. A stamp whose name is not all lower case had no working scope at all, and a scope's meaning depended on the order the stamps were declared in. A stamp the model does not declare used to fail quietly: the two questions answered false — which reads as "this record is not published" for what is really a typo — and the two writes and the two scopes raised an undefined array key and then wrote to, or queried, a column named null. It throws a StampNotFoundException now, naming the stamps that do exist. 44 tests, on real Eloquent models on sqlite through Testbench, at 100% line coverage. The package requires PHP 8.4 and Laravel 12 or 13 now, declares types throughout, and is checked by GitHub Actions across PHP 8.4/8.5 x Laravel 12/13 x lowest/highest dependencies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the modernization series across the shetabit packages.
The dynamic scopes were half broken
__call()recognisedPost::unpublished()and then forwarded the method name to the scope instead of the stamp name:scopeUnstamped($query, 'unpublished')then lookedunpublishedup in the stamp list, found nothing, and ranwhereNull(null). The positive form only ever worked because there the method name happens to equal the stamp name.Two more in the same helper:
getStampScope()compared a lower-cased method name against the stamp names as declared, so a stamp namedisVerifiedhad no working scope at all.A stamp that does not exist used to fail quietly
isStampedBy('typo')answeredfalse— which reads as "this record is not published" for what is really a typo.markAsStamped(),markAsUnstamped()and both scopes raised an undefined array key and then wrote to, or queried, a column namednull.They throw
StampNotFoundExceptionnow, and the message names the stamps that do exist.hasStamp()asks the same question without throwing, andgetStampField()resolves a stamp to its column.Also
getFreshTimestamp()is gone; the model's ownfreshTimestamp()is used, so a stamp is written in the same format ascreated_atinstead of adate()string when outside Laravel.__call()no longer carries an unreachable branch forincrement/decrementthat would have called itself until the stack ran out. A test covers that both still work, along with relations, through-calls, dynamic wheres and plain forwarding.Breaking
PHP 8.4 minimum (was 7.1) and Laravel 12/13 only (was 5.1+). Every method of
Contracts\Stampableand of the trait declares its types, so an implementation of the contract has to declare compatible ones. An unknown stamp throws instead of failing quietly.illuminate/databaseis now required explicitly — the trait has always used Eloquent's query builder.Verified
composer cigreen on PHP 8.4 and 8.5 × lowest and highest (4 runs), rector clean,composer validate --strictpasses.🤖 Generated with Claude Code