+ $deletions = Deletion::all();
+ $deleteCount = 0;
+ foreach ($deletions as $deletion) {
+ $deleteCount += $this->destroyFromDeletion($deletion);
+ }
+ return $deleteCount;
+ }
+
+ /**
+ * Destroy an element from the given deletion model.
+ * @throws Exception
+ */
+ public function destroyFromDeletion(Deletion $deletion): int
+ {
+ // We directly load the deletable element here just to ensure it still
+ // exists in the event it has already been destroyed during this request.
+ $entity = $deletion->deletable()->first();
+ $count = 0;
+ if ($entity) {
+ $count = $this->destroyEntity($deletion->deletable);
+ }
+ $deletion->delete();
+ return $count;
+ }
+
+ /**
+ * Restore the content within the given deletion.
+ * @throws Exception
+ */
+ public function restoreFromDeletion(Deletion $deletion): int
+ {
+ $shouldRestore = true;
+ $restoreCount = 0;
+ $parent = $deletion->deletable->getParent();
+
+ if ($parent && $parent->trashed()) {
+ $shouldRestore = false;
+ }
+
+ if ($shouldRestore) {
+ $restoreCount = $this->restoreEntity($deletion->deletable);
+ }
+
+ $deletion->delete();
+ return $restoreCount;
+ }
+
+ /**
+ * Automatically clear old content from the recycle bin
+ * depending on the configured lifetime.
+ * Returns the total number of deleted elements.
+ * @throws Exception
+ */
+ public function autoClearOld(): int
+ {
+ $lifetime = intval(config('app.recycle_bin_lifetime'));
+ if ($lifetime < 0) {
+ return 0;
+ }
+
+ $clearBeforeDate = Carbon::now()->addSeconds(10)->subDays($lifetime);
+ $deleteCount = 0;
+
+ $deletionsToRemove = Deletion::query()->where('created_at', '<', $clearBeforeDate)->get();
+ foreach ($deletionsToRemove as $deletion) {
+ $deleteCount += $this->destroyFromDeletion($deletion);
+ }
+
+ return $deleteCount;
+ }
+
+ /**
+ * Restore an entity so it is essentially un-deleted.
+ * Deletions on restored child elements will be removed during this restoration.
+ */
+ protected function restoreEntity(Entity $entity): int
+ {
+ $count = 1;
+ $entity->restore();
+
+ $restoreAction = function ($entity) use (&$count) {
+ if ($entity->deletions_count > 0) {
+ $entity->deletions()->delete();