martinmulder / laravel-model-metadata
Attach flexible, typed, polymorphic metadata to any Eloquent model, with class- or scope-based required-field schemas and an optional FilamentPHP v5 integration.
Package info
github.com/MartinMulder/laravel-model-metadata
pkg:composer/martinmulder/laravel-model-metadata
Requires
- php: ^8.3 || ^8.4
- illuminate/support: ^13.0
Requires (Dev)
- orchestra/testbench: ^11.0
- pestphp/pest: ^3.0
Suggests
- filament/filament: Required to use the MetadataRelationManager within FilamentPHP v5 panels.
Provides
None
Conflicts
None
Replaces
None
README
Attach flexible, typed, polymorphic metadata to any Eloquent model — with class-based casting, strict validation, N+1 prevention out of the box, and an optional Filament v5 integration.
Metadata values are stored per-instance from the start (setMetadata()/getMetadata() on a
single record). On top of that, a model can declare which metadata keys are required, what
their allowed values are, and what type they cast to — either statically via a repeatable
#[RequiresMetadata] PHP attribute on the model class, or dynamically via metadata_schemas
database rows scoped per group of instances (e.g. per tenant, per category) — so different
groups of the same model can each have their own set of required fields and options.
Requirements
- PHP ^8.3 or ^8.4
- Laravel 13 (
illuminate/support^13.0) filament/filament^5.0, only if you use the optional Filament relation manager / resource
Installation
You can install the package via composer:
composer require martinmulder/laravel-model-metadata
Quick start
Add the HasMetadata trait to any Eloquent model:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use MartinMulder\LaravelModelMetadata\Traits\HasMetadata; class Product extends Model { use HasMetadata; }
Then set and read metadata per record:
$product = Product::find(1); $product->setMetadata('short_description', 'High quality premium product', 'string'); $product->getMetadata('short_description'); // 'High quality premium product'
That's the basics — see USAGE.md for the full guide, including:
- All built-in value types (
string,integer,boolean,json,badges) and how to register your own. - Declaring required metadata keys, defaults, and allowed options with
#[RequiresMetadata]. - Scope-aware metadata schemas (
metadata_schemas+metadataScope()) for models where different groups of instances need different required fields/options. - The bundled
MetadataRelationManagerandMetadataSchemaResourcefor FilamentPHP v5.
Configuration
Publish the config file if you want to register custom metadata types:
php artisan vendor:publish --tag="laravel-model-metadata-config"
This creates config/laravel-model-metadata.php, which maps type names to the classes that
implement them:
return [ 'types' => [ 'string' => \MartinMulder\LaravelModelMetadata\Types\StringType::class, 'integer' => \MartinMulder\LaravelModelMetadata\Types\IntegerType::class, 'boolean' => \MartinMulder\LaravelModelMetadata\Types\BooleanType::class, 'json' => \MartinMulder\LaravelModelMetadata\Types\JsonType::class, 'badges' => \MartinMulder\LaravelModelMetadata\Types\BadgesType::class, ], ];
Add your own entry here to register a custom type — see USAGE.md for a worked example.
Testing
composer install vendor/bin/pest
License
The MIT License (MIT). Please see the LICENSE file for more information.