mrjthedifferent/laravel-foundation
Laravel Foundation provides reusable base classes, helpers, and conventions for Laravel apps, streamlining setup, reducing boilerplate, and keeping project structure consistent. A practical starting point for teams bootstrapping common patterns across projects.
This release is a patch on two surfaces you will touch early: the Settings page/form and the admin user page that renders user documents.
composer update vendor/package
php artisan view:clear && php artisan config:clear && php artisan cache:clear
resources/views/vendor/<package>/settings/* (or wherever your published Settings page lives) and confirm the input names are settings[{key}]. That is the new contract.lead.default_status), save it from the Settings page, and re-read it — it should round-trip. Before v3.5.2 this silently failed.document_type is a value your DocumentType enum does not list. It should render a readable label rather than a 500.Bind dotted settings through the array field name, not the key. The whole point of the fix is that PHP mangles . to _ in top-level form field names. Use:
<input name="settings[lead.default_status]" value="{{ old('settings.lead.default_status', $value) }}">
<select name="settings[lead.default_status][]" multiple> ... </select>
Validation and old() then use dot notation on the settings array (settings.lead.default_status), which is the idiomatic Laravel shape and keeps your FormRequest rules readable:
'settings' => ['array'],
'settings.*' => ['nullable'],
Migrate any project-owned copy of the Settings page. If you published and customised the view, dotted keys will keep silently dropping until you rename its fields. Keys without dots continue to work with name="{key}", so a partial migration is fine — do it page by page, starting with whichever settings screen owns your dotted keys.
Treat UserDocument::document_type as a mixed value now. The property is still a DocumentType case for the listed types, but any stored value outside that list returns the raw string. Write consumers defensively:
$doc->document_type instanceof DocumentType
? $doc->document_type->value
: $doc->document_type;
Better: never branch on the type at all in views and exports — use $doc->typeLabel() for display and keep raw comparisons for filtering.
Prefer typeLabel() as the single display path. It handles both the enum case and the legacy string, so it removes a whole class of match/when duplication in Blade, Filament/Nova columns, PDF templates and API resources. Wrap it in an accessor if you want one consistent shape:
protected function documentTypeLabel(): Attribute
{
return Attribute::get(fn () => $this->typeLabel());
}
Audit before and after, not just after. A quick command that lists distinct document_type values against your enum cases is cheap insurance and tells you whether old data (or a project-added type) is the reason the page used to blow up:
UserDocument::query()->distinct()->pluck('document_type');
settings[...] rather than emitting name="{{ $key }}".[] inside the brackets: settings[lead.default_status][]. Missing the trailing [] gives you a scalar where the package expects an array and the save may be rejected or truncated.old() keys keep dots, request keys do not. After a validation failure you can spend a while wondering why old('lead.default_status') is empty — the value lives at old('settings.lead.default_status'). Check your error bag keys too.document_type is now an enum-or-string union. Static analysis and strict == comparisons against DocumentType::cases() still compile but can miss. Anything doing ->value directly on the property is a latent Error for legacy rows — grep for it after upgrading.DocumentType (a common reason the crash appeared), keep the enum as the source of truth for display and let typeLabel() handle the strays, rather than widening the enum and breaking every exhaustive match.trade_license becomes "Trade License"; values with unexpected casing or embedded IDs will look odd. If labels matter for compliance output, map them explicitly instead of relying on the humaniser.How can I help you explore Laravel packages today?