v3.15.0
What's Changed
v3.15.0 ships the biggest architectural change in the plugin's history: ModelMetadataRegistry, a single per-model metadata store that replaces the ad-hoc reflection and private caches every Eloquent handler used to maintain on its own. This release builds three new model-correctness diagnostics on top of it, validating attributes and relationships on your models, plus a more precise serialization inference — and it's the foundation a lot more diagnostics are planned to build on next.
Upgrade impact
UnknownModelAttributeandUndefinedModelRelationreport atinfoby default. Opt intoerrorwith<experimental value="true" />.UnresolvableAppendedModelAttributereports aterrorby default: a$appendsentry with no matching accessor or cast now fails analysis. Downgrade it with a standardissueHandlersentry if that doesn't fit your codebase yet.attributesToArray()/toArray()now infer a precise array shape. Always active, no config needed.
Features
- Add
ModelMetadataRegistry, a per-model metadata store warmed once duringAfterCodebasePopulatedand shared read-only across every Eloquent handler (#1081, #1201) - Add the
experimentalconfig flag to promote experimental diagnostics toerror(#1248) - Add
UnknownModelAttribute: flags acreate()/fill()/update()key with no backing column, cast, accessor,$appendsentry, or@property(#1167)
Model::create(['nmae' => 'value']);
-// silently drops the typo, sets nothing
+// UnknownModelAttribute: 'nmae' matches no column, cast, accessor, $appends entry, or @property- Add
UnresolvableAppendedModelAttribute: flags a$appendsentry with no accessor or cast to actually produce it (#1169) - Add
UndefinedModelRelation: validates relation names passed towith()/load()/has()/whereHas()against the resolved model (#1181)
Customer::with('vehicles.typoOnVehicle');
-// no warning, silently ignored at runtime
+// UndefinedModelRelation: Relation 'typoOnVehicle' is not defined on App\Models\Vehicle- Infer a precise array shape for
attributesToArray()/toArray(), honoring casts, hidden, and appended attributes (#1168, #1184)
Fixes
- Handle keyless models with nullable primary-key metadata (#1264)
- Exclude migration files from
UnknownModelAttribute(#1265) - Stop
RelationResolverfrom autoloading related models, fixing an analysis crash (#1272)
Internal changes
- Reset stateful handlers between plugin invocations (#1250)
- Make model metadata warm-up section-isolated, preserving partial metadata after a failure (#1268)
- Allow psalm-delta on fork PRs with a restore-only cache guard (#1269)
Full Changelog: v3.14.1592...v3.15.0