PHPackages                             bkwld/cloner - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. bkwld/cloner

ActiveLibrary[Database &amp; ORM](/categories/database)

bkwld/cloner
============

A trait for Laravel Eloquent models that lets you clone of a model and it's relationships, including files.

3.15.0(1mo ago)4912.3M↓37.2%54[17 issues](https://github.com/BKWLD/cloner/issues)6MITPHPPHP &gt;=7.1CI failing

Since Jul 28Pushed 1mo ago13 watchersCompare

[ Source](https://github.com/BKWLD/cloner)[ Packagist](https://packagist.org/packages/bkwld/cloner)[ RSS](/packages/bkwld-cloner/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (10)Dependencies (21)Versions (34)Used By (6)

Cloner
======

[](#cloner)

[![Packagist](https://camo.githubusercontent.com/c65dad5019de49b91d294d43b7a022d3cf7b3a810d2c4586820b196f57c0110d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f424b574c442f636c6f6e65722e737667)](https://packagist.org/packages/bkwld/cloner) [![Build Status](https://camo.githubusercontent.com/6ddedbc4243b8019611eeea64d5e1467633c93193c5cf188ef103d30041dd45c/68747470733a2f2f7472617669732d63692e6f72672f424b574c442f636c6f6e65722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/BKWLD/cloner) [![Coverage Status](https://camo.githubusercontent.com/c93fd2e58b04f2a48a5b3206643a8043532c78fdafcf2ae39fb45f1979bd4205/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f424b574c442f636c6f6e65722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/BKWLD/cloner?branch=master)

A trait for Laravel Eloquent models that lets you clone a model and it's relationships, including files. Even to another database.

Installation
------------

[](#installation)

To get started with Cloner, use Composer to add the package to your project's dependencies:

```
composer require bkwld/cloner

```

> Note: The Below step is optional in Laravel 5.5 or above!

After installing the cloner package, register the service provider.

```
Bkwld\Cloner\ServiceProvider::class,
```

in your `config/app.php` configuration file:

```
'providers' => [
    /*
    * Package Service Providers...
    */
    Bkwld\Cloner\ServiceProvider::class,
],
```

Usage
-----

[](#usage)

Your model should now look like this:

```
class Article extends Eloquent {

   use \Bkwld\Cloner\Cloneable;
}
```

You can clone an Article model like so:

```
$clone = Article::first()->duplicate();
```

In this example, `$clone` is a new `Article` that has been saved to the database. To clone to a different database:

```
$clone = Article::first()->duplicateTo('production');
```

Where `production` is the [connection name](https://laravel.com/docs/6.x/database#using-multiple-database-connections) of a different Laravel database connection.

#### Cloning Relationships

[](#cloning-relationships)

Lets say your `Article` has many `Photos` (a one to many relationship) and can have more than one `Authors` (a many to many relationship). Now, your `Article` model should look like this:

```
class Article extends Eloquent {
   use \Bkwld\Cloner\Cloneable;

   protected $cloneable_relations = ['photos', 'authors'];

   public function photos() {
       return $this->hasMany('Photo');
   }

   public function authors() {
        return $this->belongsToMany('Author');
   }
}
```

The `$cloneable_relations` informs the `Cloneable` as to which relations it should follow when cloning. Now when you call `Article::first()->duplicate()`, all of the `Photo` rows of the original will be copied and associated with the new `Article`. And new pivot rows will be created associating the new `Article` with the `Authors` of the original (because it is a many to many relationship, no new `Author` rows are created). Furthermore, if the `Photo` model has many of some other model, you can specify `$cloneable_relations` in its class and `Cloner` will continue replicating them as well.

> **Note:** Many to many relationships will not be cloned to a *different* database because the related instance may not exist in the other database or could have a different primary key.

### Customizing the cloned attributes

[](#customizing-the-cloned-attributes)

By default, `Cloner` does not copy the `id` (or whatever you've defined as the `key` for the model) field; it assumes a new value will be auto-incremented. It also does not copy the `created_at` or `updated_at`. You can add additional attributes to ignore as follows:

```
class Photo extends Eloquent {
   use \Bkwld\Cloner\Cloneable;

   protected $clone_exempt_attributes = ['uid', 'source'];

   public function article() {
        return $this->belongsTo('Article');
   }

   public function onCloning($src, $child = null) {
        $this->uid = str_random();
        if($child) echo 'This was cloned as a relation!';
        echo 'The original key is: '.$src->getKey();
   }
}
```

The `$clone_exempt_attributes` adds to the defaults. If you want to replace the defaults altogether, override the trait's `getCloneExemptAttributes()` method and return an array.

Also, note the `onCloning()` method in the example. It is being used to make sure a unique column stays unique. The `Cloneable` trait adds to no-op callbacks that get called immediately before a model is saved during a duplication and immediately after: `onCloning()` and `onCloned()`. The `$child` parameter allows you to customize the behavior based on if it's being cloned as a relation or direct.

In addition, Cloner fires the following Laravel events during cloning:

- `cloner::cloning: ModelClass`
- `cloner::cloned: ModelClass`

`ModelClass` is the classpath of the model being cloned. The event payload contains the clone and the original model instances.

### Cloning files

[](#cloning-files)

If your model references files saved disk, you'll probably want to duplicate those files and update the references. Otherwise, if the clone is deleted and it cascades delets, you will delete files referenced by your original model. `Cloner` allows you to specify a file attachment adapter and ships with support for [Bkwld\\Upchuck](https://github.com/BKWLD/upchuck). Here's some example usage:

```
class Photo extends Eloquent {
   use \Bkwld\Cloner\Cloneable;

   protected $cloneable_file_attributes = ['image'];

   public function article() {
        return $this->belongsTo('Article');
   }
}
```

The `$cloneable_file_attributes` property is used by the `Cloneable` trait to identify which columns contain files. Their values are passed to the attachment adapter, which is responsible for duplicating the files and returning the path to the new file.

If you don't use [Bkwld\\Upchuck](https://github.com/BKWLD/upchuck) you can write your own implementation of the `Bkwld\Cloner\AttachmentAdapter` trait and wrap it in a Laravel IoC container named 'cloner.attachment-adapter'. For instance, put this in your `app/start/global.php`:

```
App::singleton('cloner.attachment-adapter', function($app) {
   return new CustomAttachmentAdapter;
});
```

###  Health Score

68

—

FairBetter than 99% of packages

Maintenance91

Actively maintained with recent releases

Popularity63

Solid adoption and visibility

Community38

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 60.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~127 days

Recently: every ~112 days

Total

32

Last Release

37d ago

Major Versions

1.0.0 → 2.0.02016-02-29

2.1.0 → 3.0.02016-08-24

PHP version history (4 changes)1.0.0PHP &gt;=5.4.0

2.1.0PHP &gt;=5.5.0

3.5.1PHP &gt;=7.0

3.15.0PHP &gt;=7.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/77567?v=4)[Robert Reinhard](/maintainers/weotch)[@weotch](https://github.com/weotch)

---

Top Contributors

[![weotch](https://avatars.githubusercontent.com/u/77567?v=4)](https://github.com/weotch "weotch (77 commits)")[![EcoinTest](https://avatars.githubusercontent.com/u/153815470?v=4)](https://github.com/EcoinTest "EcoinTest (6 commits)")[![denisdulici](https://avatars.githubusercontent.com/u/5254835?v=4)](https://github.com/denisdulici "denisdulici (5 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![espensgr](https://avatars.githubusercontent.com/u/3862891?v=4)](https://github.com/espensgr "espensgr (4 commits)")[![wimski](https://avatars.githubusercontent.com/u/12373573?v=4)](https://github.com/wimski "wimski (4 commits)")[![korridor](https://avatars.githubusercontent.com/u/26689068?v=4)](https://github.com/korridor "korridor (3 commits)")[![dragonfire1119](https://avatars.githubusercontent.com/u/1289128?v=4)](https://github.com/dragonfire1119 "dragonfire1119 (3 commits)")[![pavel-mironchik](https://avatars.githubusercontent.com/u/7408605?v=4)](https://github.com/pavel-mironchik "pavel-mironchik (2 commits)")[![eriksanders86](https://avatars.githubusercontent.com/u/48481732?v=4)](https://github.com/eriksanders86 "eriksanders86 (2 commits)")[![denitsa-md](https://avatars.githubusercontent.com/u/21036599?v=4)](https://github.com/denitsa-md "denitsa-md (2 commits)")[![liamduckett](https://avatars.githubusercontent.com/u/116881406?v=4)](https://github.com/liamduckett "liamduckett (2 commits)")[![ben-everly](https://avatars.githubusercontent.com/u/1105188?v=4)](https://github.com/ben-everly "ben-everly (1 commits)")[![Putr](https://avatars.githubusercontent.com/u/616239?v=4)](https://github.com/Putr "Putr (1 commits)")[![rasmuscnielsen](https://avatars.githubusercontent.com/u/8465957?v=4)](https://github.com/rasmuscnielsen "rasmuscnielsen (1 commits)")[![realrashid](https://avatars.githubusercontent.com/u/15607685?v=4)](https://github.com/realrashid "realrashid (1 commits)")[![ricardosierra](https://avatars.githubusercontent.com/u/5499444?v=4)](https://github.com/ricardosierra "ricardosierra (1 commits)")[![robert-stanciu](https://avatars.githubusercontent.com/u/17193524?v=4)](https://github.com/robert-stanciu "robert-stanciu (1 commits)")[![SebastianSchoeps](https://avatars.githubusercontent.com/u/44115562?v=4)](https://github.com/SebastianSchoeps "SebastianSchoeps (1 commits)")[![ukeloop](https://avatars.githubusercontent.com/u/45733259?v=4)](https://github.com/ukeloop "ukeloop (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/bkwld-cloner/health.svg)

```
[![Health](https://phpackages.com/badges/bkwld-cloner/health.svg)](https://phpackages.com/packages/bkwld-cloner)
```

###  Alternatives

[illuminate/database

The Illuminate Database package.

2.8k54.9M11.6k](/packages/illuminate-database)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8793.2M25](/packages/yajra-laravel-oci8)[glushkovds/phpclickhouse-laravel

Adapter of the most popular library https://github.com/smi2/phpClickHouse to Laravel

2051.5M2](/packages/glushkovds-phpclickhouse-laravel)[lemaur/eloquent-publishing

218.1k1](/packages/lemaur-eloquent-publishing)[laravel-liberu/laravel-gedcom

A package that converts gedcom files to Eloquent models

782.5k1](/packages/laravel-liberu-laravel-gedcom)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
