Code The Pixel

CakePHP 4 Soft Delete

Asyraf Wahi Anuar - January 22, 2023
Published in CakePHP 855 Views Email This Article
Estimated reading time: 2 minutes, 16 seconds

A soft delete marks a record as no longer active or valid without deleting it from the database. Soft deletion is a widely used pattern applied for business applications. It allows users to mark some records as deleted without erasure from the database. Effectively, the user prevents a soft-deleted record from being selected; meanwhile, all old records can still refer to it. Hard deletes are hard to recover if something goes wrong (application bug, bad migration, manual query, etc.). This usually involves restoring from a backup, and targeting only the data affected by the bad delete is hard. Soft deletes are easier to recover from once the user determines what happened. This tutorial will demonstrate how to apply the soft delete method in CakePHP 4 using 'useMuffin Trash' plugin. 

Installation
Download using composer:

composer require muffin/trash


Load the plugin:

cake plugin load Muffin/Trash


Usage
You database should have DATETIME column 'deleted' or 'trashed'. If use different name, you need to identify the specific column name in behavior. 

In the table(s) model, add the Trash behavior as shown below:

$this->addBehavior('Muffin/Trash.Trash');


The behaviour will default auto-detect the DATETIME column used to track trashed (soft-deleted) records, but only if you use deleted or trashed names. Otherwise, you could customize that when adding the behaviour:

$this->addBehavior('Muffin/Trash.Trash', [
    'field' => 'deleted_at'
]);


or, at the global level, in bootstrap.php:

Configure::write('Muffin/Trash.field', 'deleted_at');


Add the following code in controller header:

use Muffin\Trash\Model\Behavior\TrashBehavior;
use Cake\ORM\Entity;


To restore all trashed records, add the following function:

public function restoreAllTrash()
{
    $this->Playgrounds->restoreTrash();
    $this->Flash->success(__('All records has been restored'));
    return $this->redirect(['action' => 'index']);
}


To restore a specific trashed entity, use the following function:

public function restoreTrashEntity($id = null)
{
    $this->Playgrounds->restoreTrash(new Entity([
        'id' => $id,
    ], ['markNew' => false, 'markClean' => true]));
    
    return $this->redirect(['action' => 'find-only-trashed']);
}


To transfer all records to trash, use the following code. It will trash all records in the database:

public function trashAll()
{
    $this->Playgrounds->trashAll('1 = 1');
    $this->Flash->success(__('All record has been deleted'));
    return $this->redirect(['action' => 'index']);
}


To list all trashed records, use the following code:

public function findOnlyTrashed()
{
    $this->paginate = [
        'maxLimit' => 10,
    ];
    $playgrounds = $this->paginate($this->Playgrounds->find('onlyTrashed'));
    
    $this->set(compact('playgrounds'));
}


To empty the trashed records, use the following code. This action will hard-delete the records from the database.

public function emptyTrash()
{
    $this->Playgrounds->emptyTrash();
    $this->Flash->success(__('Trash Empty'));
    return $this->redirect(['action' => 'find-only-trashed']);
}


That's all. Happy coding :)

 


Cite this article (APA 6th Edition)