| Install | |
|---|---|
composer require grazulex/laravel-draftable |
|
| Latest Version: | v1.0.0 |
| PHP: | ^8.3 |
Production-ready drafts, versioning, and publication flow for any Eloquent model
A comprehensive package for managing content lifecycle with enterprise-grade quality
Laravel Draftable is a production-ready package that adds comprehensive drafts, versioning, and publication workflows to any Eloquent model in Laravel. Perfect for content management systems, blog platforms, documentation sites, e-commerce products, and any application where you need reliable content lifecycle management with version control capabilities.
Install the package via Composer:
composer require grazulex/laravel-draftable
💡 Auto-Discovery: The service provider will be automatically registered thanks to Laravel's package auto-discovery.
use Grazulex\LaravelDraftable\Traits\HasDrafts;
// Add to your model
class Post extends Model
{
use HasDrafts;
protected $fillable = ['title', 'content', 'status'];
}
// Create and manage drafts
$post = Post::create(['title' => 'My First Post']);
// Make changes and save as draft
$post->title = 'Updated Title';
$post->content = 'Draft content here...';
$post->saveDraft();
// Publish when ready
$post->publishDraft();
// View version history
$versions = $post->drafts;
// Compare versions using the service
$draftDiff = app(\Grazulex\LaravelDraftable\Services\DraftDiff::class);
$diff = $draftDiff->compare($version1, $version2);
// Restore previous version
$post->restoreVersion(2);
For comprehensive documentation, examples, and advanced usage guides, visit our Wiki:
The wiki includes:
Laravel Draftable includes powerful CLI commands for draft management:
# List all drafts with filtering options
php artisan draftable:list --model=Post --unpublished --limit=20
# Compare two specific versions of a model
php artisan draftable:diff Post 1 1 2 --format=json
# Clean up old drafts with safety checks
php artisan draftable:clear-old --days=30 --dry-run
use Grazulex\LaravelDraftable\Services\DraftDiff;
$draftDiff = app(DraftDiff::class);
$differences = $draftDiff->compare($draft1, $draft2);
// Example output:
[
'title' => [
'type' => 'modified',
'old' => 'Original Title',
'new' => 'Updated Title'
],
'content' => [
'type' => 'added',
'old' => null,
'new' => 'New content here'
]
]
use Grazulex\LaravelDraftable\Events\{DraftCreated, DraftPublished, VersionRestored};
// Listen for draft events
Event::listen(DraftCreated::class, function ($event) {
// Handle draft creation
});
Event::listen(DraftPublished::class, function ($event) {
// Handle draft publication
});
Event::listen(VersionRestored::class, function ($event) {
// Handle version restoration
});
The package includes an optimized migration:
Schema::create('drafts', function (Blueprint $table) {
$table->id();
$table->morphs('draftable');
$table->json('payload');
$table->unsignedBigInteger('version')->default(1);
$table->foreignId('created_by')->nullable()->constrained('users');
$table->timestamp('published_at')->nullable();
$table->timestamps();
// Performance indexes
$table->index(['draftable_type', 'draftable_id']);
$table->index('published_at');
$table->index('version');
});
Laravel Draftable maintains exceptional quality standards:
Perfect for:
Future enhancements planned:
Please see CONTRIBUTING.md for details.
If you discover any security-related issues, please email jms@grazulex.be instead of using the issue tracker.
Please see RELEASES.md for more information on what has changed recently.
The MIT License (MIT). Please see License File for more information.
Built with ❤️ following SOLID principles and clean code practices.