Another way (or in addition to using tokens) is to not expose hard delete functionality to the front-end period.
One thing I've done is to create a 'recycle' table in the database with a unique ID.
Also give every table in your database a deleted column.
If something gets deleted, create a new row in the 'recycle' table and use that ID to populate the 'deleted' column of all the rows that were deleted. This way each delete associates itself to multiple rows.
This offers you the ability to "undo" any delete + all associated rows with the delete from an admin interface that is not exposed publicly to web users.
Another way (or in addition to using tokens) is to not expose hard delete functionality to the front-end period.
One thing I've done is to create a 'recycle' table in the database with a unique ID.
Also give every table in your database a deleted column.
If something gets deleted, create a new row in the 'recycle' table and use that ID to populate the 'deleted' column of all the rows that were deleted. This way each delete associates itself to multiple rows.
This offers you the ability to "undo" any delete + all associated rows with the delete from an admin interface that is not exposed publicly to web users.
This way, you have 3 tiers of protection:
- tokens
- a soft delete that you can easily undo
- backup copy of the db if all else fails