The laravel/framework v13.7.0 tag landed with seventeen merged PRs. The release clusters around three themes: broader enum support across the framework, testing improvements, and targeted bug fixes.
@maherelgamil extended enum support to ConcurrencyManager in PR #59801. The driver() method now accepts a backed enum alongside a plain string, consistent with how queue, cache, and session managers already handle enums.
1use App\Enums\ConcurrencyDriver;2 3Concurrency::driver(ConcurrencyDriver::Fiber)->run([4 fn () => doWork(),5 fn () => doMoreWork(),6]);
@Back1ng applied the same treatment to LazyCollection::keyBy() in PR #59809. Pass a backed enum as the key and the collection will resolve its value rather than throwing.
@TWithers made the DebounceFor attribute inheritable in PR #59795, so subclasses of a debounced job pick up the attribute without having to redeclare it.
@jackbayliss added isLocked() to the Lock class in PR #59791. Previously, checking whether a lock was currently held required attempting to acquire it or inspecting the underlying store directly.
1$lock = Cache::lock('invoice-processing', 60);2 3if ($lock->isLocked()) {4 return response()->json(['status' => 'processing'], 202);5}6 7$lock->get(function () {8 // process invoice9});
This is the read-only check the lock API was missing.
@cyrodjohn added bulk JSON path assertions to TestResponse in PR #59829. Instead of chaining individual assertJsonPath() calls, a single assertion covers multiple paths at once.
1$response->assertJsonPaths([2 'data.user.name' => 'Taylor',4 'meta.version' => '13.7.0',5]);
jackbayliss also extended assertSoftDeleted and assertNotSoftDeleted to accept arrays in PR #59796, so a single assertion can match multiple column conditions on a soft-deleted model.
LazyCollection::has() false positives. @Button99 fixed a case in PR #59832 where duplicate keys in a lazy collection caused has() to return true for keys that were not actually present after deduplication.
PendingDispatch resolving Cache repeatedly. @sumaiazaman fixed PR #59821 where PendingDispatch was resolving the cache store on every dispatched job rather than once. Applications dispatching jobs in bulk were paying unnecessary container resolution overhead.
Domain-scoped route registration. @Bottelet fixed route registration for domain-scoped routes in PR #59793, resolving a case where routes bound to a specific domain were not registering correctly.
Signed URL validation. The prior summary notes a fix to signed URL validation edge cases, addressed alongside the broader set of bug fixes in this release.
@jnoordsij marked the Scope::apply() builder parameter with a covariant template in PR #59790, closing a PHPStan gap that surfaced when custom Builder subclasses were used with query scopes.
@cosmastech fixed JsonFormatter in PR #59799 to extract exception context even when ExceptionHandler is not bound in the container, which matters in minimal or testing environments where the full exception handler is not registered.
@lucasmichot applied a batch of Rector fixes in PR #59787, keeping the internals consistent with modern PHP idioms.
Applications using cache locks, dispatching jobs in bulk, or asserting against JSON responses will want to pick up 13.7.0. The enum additions to ConcurrencyManager and LazyCollection are low-risk and bring those APIs in line with the rest of the framework.
If you enjoyed this article, please consider supporting our work for as low as $5 / month.
Sponsor
Written by
Writing and maintaining @LaravelMagazine. Host of "The Laravel Magazine Podcast". Pronouns: vi/vim.
Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.