Soft Delete and Hard Delete
XELOS provides the SoftDeleteInterface
and the SoftDeleteTrait
to move documents in a trash when they are deleted.
Trashed documents can be restored if they are a DocumentModel
.
Trash
The related document index of the deleted document can be found in the audit log. The audit log can be used to restore the document.
Hard Delete
When a document model is marked as soft deleted, the related document index stores the date for the scheduled removal based on the config variable "Trash Folder TTL".
If the variable is changed the scheduled removal is unchanged. However, if the variable was increased, the deletion is delayed until the deleted_at
property of the document index is so many days in the past.
E.g. A document is deleted and the document index is marked for deletion in 30 days on the 30th January. If the "Trash Folder TTL" is reduced to 20, the document will still be deleted on the 30th. If the variable is increased to 50, the document won't be deleted before the 19th February.
Implementation
The document model has to implement both the interface and the trait:
use XELOS\Framework\Module\Model\Interfaces\SoftDeleteInterface;
use XELOS\Framework\Module\Model\Traits\SoftDeleteTrait;
class Page extends DocumentModel implements SoftDeleteInterface {
use SoftDeleteTrait;
}
The database.yml for the model table has to be extended with the deleted_at
property which is automatically created as a timestamp column if added to the YAML file:
page:
id:
title: {type: varchar, size: 100}
created_at:
updated_at:
deleted_at:
This implementation causes the delete
method to always set the deleted_at
column, instead of deleting the document.
Finding deleted models
Deleted models are not returned by the find_by
methods.
The SoftDeleteTrait
provides the scope withDeleted
which enables searching for deleted documents:
$this->mod->model->page->withDeleted()->find_by_id(42);
Deleting related documents
If a model has related documents, it can implement the delete events defined in the
SoftDeleteInterface
, e.g. the Wiki page has many history entries and links.
The related documents have to implement the interface and the trait and add the deleted_at
column to the database table.
class Page {
/**
* Restore the history and links.
*/
public function onRestore() {
$this->mod->model->page_history->withDeleted()->find_all_by_page_id($this->id)->invoke('restore');
$this->mod->model->page_link->withDeleted()->find_all_by_from_page_id($this->id)->invoke('restore');
}
/**
* Delete the history and links.
*/
public function onForceDelete() {
$this->mod->model->page_history->withDeleted()->find_all_by_page_id($this->id)->invoke('forceDelete');
$this->mod->model->page_link->withDeleted()->find_all_by_from_page_id($this->id)->invoke('forceDelete');
}
}
Make sure to only implement the event in one model to prevent circular calls.