SoftDeleting Entities in CakePHP 3
When creating CMS-like software, it is useful to have “undo” triggers in your application. Sometimes you want to revert to a previous version of a record, or undo a hasty delete. For the latter case, it is often useful to implement some form of a “softdelete” functionality.
Here is a lovely plugin for 3.x that you can use to implement soft-delete. Let’s install it!
# install using composer composer require muffin/trash:1.0.0 # require it using the plugin:load shell I just found out about bin/cake plugin load Muffin/Trash
This plugin depends upon us having a
trashed field in our database table. Lets create a migration for our
# generate the migration using the migrations plugin bin/cake bake migration add_deleted_to_posts deleted:datetime # migrate the table bin/cake migrations migrate
And now we can add the behavior to our Table class:
We could have also used a custom field like
deleted_at, but that requires more configuration, and I’m lazy so that’s not going to happen.
Next, lets see how we can use this behavior:
$table = $this->loadModel('Posts'); $post = $table->get(1); // simply marks the entity as in the trash $table->trash($post); // this fails because it's already in the trash $table->trash($post); // When the behavior is attached, `delete()` is the same as `trash()` $table->delete($post); // "recycle's" things from the trash $table->restoreTrash($post); // by default, all your trash is excluded $posts = $table->find()->all(); // but you can find everything, including things in the trash $posts = $table->find()->withTrashed()->all();
If you want to disable the overriding of
trash(), you can attach the behavior like so:
// Useful if you bake actions for soft-delete and force-delete $this->addBehavior('Muffin/Trash.Trash', [ 'events' => ['Model.beforeFind'] ]);
The plugin is already quite useful - in fact, I’m using it in 2 applications already - and can probably take care of 90% of your soft-deletion needs.