composer require kolossal-io/laravel-multiplex
php artisan migrate
use Kolossal\Multiplex\HasMeta; to your Eloquent model.
class Post extends Model
{
use HasMeta;
}
Set and retrieve time-sliced metadata on a model:
$post = Post::first();
// Set meta fluently
$post->likes = 24;
// Or use explicit method
$post->setMeta('views', 100);
// Schedule future meta
$post->setMetaAt('likes', 1000, '+1 week');
// Retrieve current meta
$post->likes; // Returns 24 (current value)
config/multiplex.php for allowed keys, default types, and event settings.Kolossal\Multiplex\Events for customization hooks.Fluent Metadata Handling: Use dynamic properties for simplicity:
$user->premium = true; // Automatically saved as meta
Time-Sliced Updates: Schedule future or past changes:
$user->saveMetaAt('subscription', 'cancelled', '+30 days');
Batch Operations: Update multiple keys at once:
$post->setMeta([
'views' => 500,
'likes' => 100,
'comments' => 5
]);
Conditional Retrieval:
Use getMeta() with fallbacks:
$post->getMeta('tags', []); // Returns [] if 'tags' doesn't exist
config/multiplex.php.Post::whereMeta('likes', '>', 100)
->whereDoesntHaveMeta('hidden')
->get();
Time Travel Queries: Retrieve meta as of a specific date:
$post->metaAt('2023-01-01')->pluck('value', 'key');
Event-Driven Extensions:
Listen for MetaHasBeenAdded to trigger side effects:
event(new MetaHasBeenAdded($meta, $model));
Custom Validation:
Override validateMeta() in your model to enforce rules:
protected function validateMeta(array $meta): void
{
if ($meta['likes'] < 0) {
throw new \InvalidArgumentException('Likes cannot be negative.');
}
}
Performance Optimization:
Use pluckMeta() for bulk retrieval:
$posts->pluckMeta(['likes', 'views']); // Returns Collection of arrays
Database Compatibility:
ROW_NUMBER() OVER (...) (MySQL 8.0+, PostgreSQL 9.0+, etc.).Meta Key Conflicts:
metaKeys() to restrict allowed keys:
$model->metaKeys(['likes', 'views']); // Only these keys allowed
Time Zone Handling:
published_at uses the system timezone. Explicitly pass Carbon instances for consistency:
$post->saveMetaAt('event', 'scheduled', Carbon::parse('2023-12-31'));
Dirty State Quirks:
isMetaDirty() may return true even if no meta was changed if the model itself is dirty.saveWithoutMeta() to bypass meta persistence during model saves.Type Casting Issues:
config/multiplex.php.whereRawMeta) bypass type casting; use cautiously.Inspect Meta Records:
Use allMeta to debug all versions (published/unpublished):
$post->allMeta->toArray();
Check Query Logs: Enable Laravel’s query logging to verify window function usage:
\DB::enableQueryLog();
$post->meta; // Inspect generated SQL
Validate Schema:
Ensure the meta table exists and has the correct structure:
php artisan schema:dump
Event Debugging:
Listen for MetaHasBeenAdded to trace meta changes:
MetaHasBeenAdded::dispatch($meta, $model);
Custom Meta Types:
Extend the type system by adding to config/multiplex.php:
'types' => [
'custom_type' => \App\CustomType::class,
],
Override Default Behavior: Publish and modify the package’s config:
php artisan vendor:publish --provider="Kolossal\Multiplex\MultiplexServiceProvider"
Add Query Scopes:
Extend the Meta model:
class Meta extends \Kolossal\Multiplex\Models\Meta
{
public function scopeActive($query)
{
return $query->where('published_at', '<=', now());
}
}
Hook into Events:
Register listeners in EventServiceProvider:
protected $listen = [
\Kolossal\Multiplex\Events\MetaHasBeenAdded::class => [
\App\Listeners\LogMetaChange::class,
],
];
Default Meta Keys:
Set default_meta_keys in config/multiplex.php to auto-include keys:
'default_meta_keys' => ['likes', 'views', 'hidden'],
Strict Mode:
Enable strict_mode to throw exceptions for invalid keys:
'strict_mode' => true,
Fallback Behavior: Disable fallback to database columns by setting:
'fallback_to_columns' => false,
Time Handling:
Customize the default time resolution (e.g., milliseconds) in config/multiplex.php:
'time_resolution' => 'milliseconds',
How can I help you explore Laravel packages today?