Installation:
composer require coliving/laravel-duplicate
Publish the config (if needed) with:
php artisan vendor:publish --provider="Neurony\Duplicate\DuplicateServiceProvider"
Basic Setup:
Add the HasDuplicates trait and implement getDuplicateOptions() in your Eloquent model:
use Neurony\Duplicate\Traits\HasDuplicates;
use Neurony\Duplicate\Options\DuplicateOptions;
class Post extends Model
{
use HasDuplicates;
public function getDuplicateOptions(): DuplicateOptions
{
return DuplicateOptions::instance();
}
}
First Use Case: Duplicate a model instance with relationships:
$originalPost = Post::find(1);
$duplicatedPost = $originalPost->duplicate();
Basic Duplication:
$original = Post::with('author', 'comments')->find(1);
$duplicate = $original->duplicate(); // Recursively duplicates all supported relationships
Excluding Relationships:
public function getDuplicateOptions(): DuplicateOptions
{
return DuplicateOptions::instance()
->exclude('comments'); // Skip duplicating comments
}
Customizing Duplication Logic:
public function getDuplicateOptions(): DuplicateOptions
{
return DuplicateOptions::instance()
->customize('author', function ($original, $duplicate) {
$duplicate->name = 'Copied ' . $original->name;
});
}
Bulk Duplication:
$posts = Post::where('published', false)->get();
$duplicates = $posts->map->duplicate();
Service Layer: Encapsulate duplication logic in a service to handle business rules:
class PostService {
public function duplicateDraft(int $postId): Post {
$post = Post::findOrFail($postId);
$duplicate = $post->duplicate();
$duplicate->status = 'draft';
$duplicate->save();
return $duplicate;
}
}
API Endpoints:
Route::post('/posts/{post}/duplicate', function (Post $post) {
return response()->json($post->duplicate());
});
Admin Panels: Use with Laravel Nova or Filament for UI duplication buttons:
// Filament example
public static function getDuplicateOptions(): DuplicateOptions
{
return DuplicateOptions::instance()
->exclude('deleted_at'); // Skip soft deletes
}
Circular Relationships:
belongsToMany or self-referential relationships.getDuplicateOptions().Primary Key Conflicts:
DuplicateOptions::instance()->incrementPrimaryKey();
Event Side Effects:
withoutEvents():
$duplicate = $original->duplicate()->withoutEvents();
Polymorphic Relationships:
morphTo/morphMany may not duplicate correctly if not configured.HasDuplicates.Log Duplication: Enable debug mode in config:
'debug' => env('DUPLICATE_DEBUG', false),
Then check Laravel logs for duplication steps.
Verify Relationships:
Use dd($original->getRelations()) to inspect relationships before duplication.
Test Edge Cases:
// Test with empty relationships
$emptyPost = Post::find(1)->withoutRelations()->duplicate();
Custom Duplicate Logic:
Override the duplicate() method in your model:
public function duplicate(array $attributes = [], array $relations = [])
{
$duplicate = parent::duplicate($attributes, $relations);
$duplicate->slug = Str::slug('Copy of ' . $this->title);
return $duplicate;
}
Event Handling: Listen for duplication events:
// In EventServiceProvider
protected $listen = [
'Neurony\Duplicate\Events\Duplicating' => [
'App\Listeners\LogDuplication',
],
];
Custom Storage: Duplicate to a different database/table:
DuplicateOptions::instance()
->connection('secondary')
->table('posts_archive');
Performance: For large datasets, use chunking:
Post::chunk(100, function ($posts) {
foreach ($posts as $post) {
$post->duplicate();
}
});
How can I help you explore Laravel packages today?