Skip to content

FLUX-911 - Support Laravel 13 - #14

Merged
qschmick merged 3 commits into
10.xfrom
FLUX-911/laravel-13
Oct 12, 2026
Merged

qschmick merged 3 commits into
10.xfrom
FLUX-911/laravel-13

Conversation

@qschmick

@qschmick qschmick commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Summary

New major line 10.x (cut from 9.x) for Laravel 13. 9.x stays on Laravel 11/12.

  • Constraints: laravel/framework ^12.0|^13.0 and always-open/laravel-process-stamps ^8.0|^9.0 (process-stamps 9.x is its Laravel 13 line). Laravel 11 is dropped because Composer refuses every 11.x release over a security advisory. Dev deps: testbench ^10.0|^11.0, phpunit ^11.0|^12.0. fico7489/laravel-pivot is replaced by always-open/laravel-pivot ^4.0 (see Blocked). awobaz/compoships ^2.0.3 is unchanged, because 2.5.5 already allows Laravel <14.
  • Observer fix (behaviour-preserving): Laravel 13 throws LogicException: … may not be called on model … while it is being booted when a model calls observe() while it is booting, and observe() instantiates the model. bootAuditLoggable() now defers registration with static::whenBooted(...), which Laravel 12 and 13 both run right after boot. On Laravel 13 the suite had 47 errors before this change; afterwards it matches Laravel 12.
  • Tests use #[Test]. PHPUnit 12 no longer reads /** @test */.
  • CI is now PHP 8.2–8.5 × Laravel 12/13. PHP 8.2 runs on Laravel 12 only.
  • The three tests that already failed on 9.x (see FLUX-839 - Test PHP 8.5 in CI #13) are fixed:
    • ConfigurableNamespaceTest ×2 called getModelNamespace(). Fix custom namespace audit loggable resolution #11 renamed it to generateModelNamespace(), and the tests now use that name.
    • BaseModelTest::it_gets_correct_subject_model_classname_with_custom_suffix expected a suffix-stripped name for an audit log that sets $auditLoggableModel, which Fix custom namespace audit loggable resolution #11 made take precedence. It now checks both paths: an explicit $auditLoggableModel ignores the suffix, and TagAuditLog (no explicit model) has the suffix stripped.
  • Bug fix (behaviour change) found by that test: getSubjectModelClassname() used str_replace(), which also removed the suffix from namespace segments. AlwaysOpen\AuditLog\…\TagAuditLog with suffix Log resolved to AlwaysOpen\Audit\…\TagAudit, a class that doesn't exist. It now uses Str::replaceEnd(). Only audit-log classes that don't set $auditLoggableModel and whose namespace contains the suffix are affected, and those resolved to a missing class before.

Local runs (process-stamps v9.0.0; laravel-pivot from always-open/laravel-pivot#1 via a path repository at 4.0.0; composer update --prefer-stable --with laravel/framework:<v>, then vendor/bin/phpunit):

PHP Laravel Testbench Result
8.4.23 12.69.3 10.12.0 54 tests, 136 assertions, exit 0
8.5.8 12.69.3 10.12.0 54 tests, 136 assertions, exit 0
8.4.23 13.35.0 11.3.0 54 tests, 136 assertions, exit 0
8.5.8 13.35.0 11.3.0 54 tests, 136 assertions, exit 0

Unblocked

  • Needs always-open/laravel-pivot v4.0.0 on Packagist: published (FLUX-911 - Laravel 13 support as always-open/laravel-pivot 4.x laravel-pivot#1). fico7489/laravel-pivot is unmaintained and has no Laravel 13 release, so this PR requires the always-open fork (^4.0), which keeps the Fico7489\Laravel\Pivot namespace (no code changes). CI now resolves always-open/laravel-pivot v4.0.0 and passes on every leg (54 tests, 136 assertions on Laravel 13.35.0).
    • Why not stay on fico7489/laravel-pivot ^3.0.1: on Laravel 13 Composer quietly picked its 3.0.3 from 2019, whose >5.5.0 constraint happens to allow 13 but which lacks later fixes such as cancelling pivotAttaching/pivotDetaching.
  • Needs FLUX-911 - Support Laravel 13 laravel-process-stamps#9: merged and tagged v9.0.0.

Release: tag v10.0.0 from 10.x once both are unblocked.

Ticket: FLUX-911

Allow laravel/framework ^12.0|^13.0 and laravel-process-stamps ^8.0|^9.0
(process-stamps 9.x is its Laravel 13 line). Laravel 11 is dropped because
Composer refuses every 11.x release over a security advisory. Testbench
moves to ^10.0|^11.0 and PHPUnit to ^11.0|^12.0.

Laravel 13 throws when a model calls observe() while it is booting, and
observe() instantiates the model. bootAuditLoggable() now registers the
observer through whenBooted(), which runs right after boot on both
Laravel 12 and 13.

PHPUnit 12 no longer reads @test docblocks, so the tests use #[Test].
CI now runs Laravel 12 and 13 on PHP 8.2 to 8.5 (8.2 on 12 only).
ConfigurableNamespaceTest called MakeModelAuditLogTable::getModelNamespace(),
which #11 renamed to generateModelNamespace(). The tests now call the new name.

The custom-suffix test asserted a suffix-stripped name for an audit log that
sets $auditLoggableModel, which #11 made take precedence. It now checks both
paths: an explicit $auditLoggableModel ignores the suffix, and a model
without one has the suffix stripped.

That second check exposed a bug: getSubjectModelClassname() used
str_replace(), which also removed the suffix from namespace segments
(AlwaysOpen\AuditLog\...\TagAuditLog with suffix "Log" resolved to
AlwaysOpen\Audit\...\TagAudit). It now strips the suffix from the end only.
fico7489/laravel-pivot is unmaintained and has no Laravel 13 release.
Composer was quietly falling back to its 3.0.3 from 2019, whose loose
constraint happens to allow Laravel 13 but which lacks later fixes such as
cancelling pivotAttaching/pivotDetaching. Require the always-open fork
instead. It keeps the Fico7489\Laravel\Pivot namespace, so no code changes.
@qschmick
qschmick marked this pull request as ready for review October 12, 2026 13:18
@qschmick
qschmick merged commit eea5cf0 into 10.x Oct 12, 2026
14 of 28 checks passed
@qschmick
qschmick deleted the FLUX-911/laravel-13 branch October 12, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant