Support Laravel 13#1487
Conversation
WalkthroughThis pull request upgrades Winter CMS to PHP 8.3 and Laravel 13. CI workflows update PHP versions in setup steps and test matrices. Composer manifests across the root project and system, backend, and CMS modules raise PHP requirements from ^8.2 to ^8.3 and Laravel from ^12.0 to ^13.0. Winter module dependencies shift to dev-wip/1.3-laravel-13 branches with repository configurations updated accordingly. Additionally, VersionManager refactors getCurrentVersionNote() to use the Arr::last utility with a type predicate for selecting comment history entries. Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
8194129 to
f24ee4f
Compare
Builds on the Laravel 12 work (wintercms#1366). Bumps laravel/framework ^12 -> ^13 and PHP ^8.2 -> ^8.3 in the root and modules/{system,backend,cms}. Points winter/storm and the three modules at the Laravel 13 branch (dev-wip/1.3-laravel-13). Adds path repositories for the in-repo modules so composer resolves the Laravel 13 module manifests locally (the published split packages still pin Laravel 12), and a VCS repository for the Storm Laravel 13 branch. CI matrices dropped to PHP 8.3/8.4. No module code changes were required (all system/backend/cms suites pass on Laravel 13).
f24ee4f to
c9c1ba4
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Depends on wintercms/storm#228 (Storm Laravel 13 support). Until that lands on
wintercms/storm, this PR resolves Storm from theaustinderrick/stormwip/1.3-laravel-13branch via a temporary VCS repository incomposer.json.Builds on #1366 (Laravel 12 support). Adds Laravel 13 support on top of the Laravel 12 work.
Summary
Targets Laravel 13 (released 2026-03-17, PHP 8.3+ minimum). No module code changes were required — the system, backend and cms PHPUnit suites all pass on Laravel 13 unchanged. The change is dependency + CI only.
Dependency changes
composer.json:php^8.2→^8.3;laravel/framework^12.0→^13.0modules/{system,backend,cms}/composer.json: samephp/laravel/frameworkbumpswinter/stormand the three modules now targetdev-wip/1.3-laravel-13modules/{system,backend,cms}so composer resolves the Laravel 13 module manifests directly from the checkout (the published split packages still pin Laravel 12). The CI "Reset modules" step keeps the committed modules; composer reports "Source already present" rather than overwriting them.CI
tests.ymlPHP matrix: dropped 8.2 →['8.3', '8.4']; frontend job PHP8.2→8.3code-quality.yaml: PHP8.2→8.3manifest.ymlalready runs on PHP 8.4 (unchanged)Breaking changes
These are the breaking changes surfaced while upgrading WinterCMS (and a real downstream app) to Laravel 13. Plugin and theme authors should review these.
PHP 8.3 minimum
Laravel 13 requires PHP 8.3+ (the 1.3 / Laravel 12 line allowed 8.2). CI matrices drop 8.2.
Models may not be instantiated while booting (
LogicException)Laravel 13 throws
LogicException: The [Model::bootIfNotBooted] method may not be called on model [X] while it is being bootedwhen a model is instantiated during its own boot — i.e.new static,new self,(new self()),self::instance(), or anything that constructs the model (includingstatic::insert()/static::query()) inside that model'sboot()or a trait'sboot<TraitName>()method.ArraySourcetrait was affected — fixed in Support Laravel 13 storm#228 (datasource setup deferred to first connection resolution).static::extend(fn ($model) => ...)(runs per instance after construction) or a deferredbootedevent. (In a real downstream app this hit several model traits that did(new self())->hasRelation(...)/self::instance()validation inboot<Trait>().)Laravel Debugbar 4 required (Winter.Debugbar)
Laravel 13 requires
barryvdh/laravel-debugbar ^4, a significant break for anything integrating with it — fixed for the plugin in wintercms/wn-debugbar-plugin#27:Barryvdh\Debugbar\*→Fruitcake\LaravelDebugbar\*(the Composer package name staysbarryvdh/laravel-debugbar). Any code usingBarryvdh\Debugbar\Facades\Debugbar,Barryvdh\Debugbar\LaravelDebugbar,Barryvdh\Debugbar\DataCollector\*, etc. must switch toFruitcake\LaravelDebugbar\....Barryvdh\Debugbar\SymfonyHttpDriverremoved (v4 configures its ownLaravelHttpDriver).LaravelDebugbar::__construct()now requires(Application $app, Request $request)— resolve via the container, notnew LaravelDebugbar($app).DataCollectorInterfaceis now typed:collect(): array,getName(): string,getWidgets(): array. Custom collectors must add these return types.formatDuration()convenience method was removed from php-debugbar'sDataCollectorbase; use$this->getDataFormatter()->formatDuration().DebugBar\Bridge\TwigProfileCollector/NamespacedTwigProfileCollector); guard withclass_exists().Storm container
logaliasStorm aliased the
'log'service toIlluminate\Log\Logger, but'log'is aLogManager. Laravel 13 (and Laravel Debugbar 4's log collector, which type-hintsIlluminate\Log\Logger) expose this — resolvingIlluminate\Log\Loggerreturned aLogManager, throwing aTypeError. Fixed in wintercms/storm#228 to alias'log'toIlluminate\Log\LogManager(matching Laravel core), soIlluminate\Log\Loggerautowires to a realLogger.General Laravel 13 changes
Also review the upstream Laravel 12 → 13 upgrade guide: CSRF middleware renamed
VerifyCsrfToken→PreventRequestForgery(deprecated aliases kept);symfony/polyfill-php85now defines globalarray_first()/array_last()(single-arg — preferWinter\Storm\Support\Arr::first()/Arr::last()); cacheserializable_classesnow defaults tofalse; Bootstrap pagination view names renamed;down --with-secrethandling.Testing
php artisan winter:test -m system: 280 tests, 0 failuresphp artisan winter:test -m backend: 72 tests, 0 failuresphp artisan winter:test -m cms: 113 tests, 0 failuresvendor/bin/phpunit, i.e. PHPUnit 11.5.x)Notes for reviewers
library-switcherCI steps only fire fordevelop/1.xbase branches; this PR targetswip/1.3, so the Storm requirement incomposer.jsonis used as-is (no switch).dms/phpunit-arraysubset-asserts/meyfa/phpunit-assert-gdhelpers support it.Related WinterCMS Laravel 13 PRs