]> BookStack Code Mirror - bookstack/blobdiff - app/Entities/Managers/TrashCan.php
LDAP: Added TLS support
[bookstack] / app / Entities / Managers / TrashCan.php
index aedf4d7afc3c32b487adae6264d3c292f81e4687..48768ab9375ee81acb1a99e6ce19a60e3de112d2 100644 (file)
@@ -13,6 +13,7 @@ use BookStack\Facades\Activity;
 use BookStack\Uploads\AttachmentService;
 use BookStack\Uploads\ImageService;
 use Exception;
+use Illuminate\Support\Carbon;
 
 class TrashCan
 {
@@ -90,7 +91,7 @@ class TrashCan
      * Remove a bookshelf from the system.
      * @throws Exception
      */
-    public function destroyShelf(Bookshelf $shelf): int
+    protected function destroyShelf(Bookshelf $shelf): int
     {
         $this->destroyCommonRelations($shelf);
         $shelf->forceDelete();
@@ -102,7 +103,7 @@ class TrashCan
      * Destroys any child chapters and pages.
      * @throws Exception
      */
-    public function destroyBook(Book $book): int
+    protected function destroyBook(Book $book): int
     {
         $count = 0;
         $pages = $book->pages()->withTrashed()->get();
@@ -127,7 +128,7 @@ class TrashCan
      * Destroys all pages within.
      * @throws Exception
      */
-    public function destroyChapter(Chapter $chapter): int
+    protected function destroyChapter(Chapter $chapter): int
     {
         $count = 0;
         $pages = $chapter->pages()->withTrashed()->get();
@@ -147,7 +148,7 @@ class TrashCan
      * Remove a page from the system.
      * @throws Exception
      */
-    public function destroyPage(Page $page): int
+    protected function destroyPage(Page $page): int
     {
         $this->destroyCommonRelations($page);
 
@@ -180,24 +181,110 @@ class TrashCan
 
     /**
      * Destroy all items that have pending deletions.
+     * @throws Exception
      */
-    public function destroyFromAllDeletions(): int
+    public function empty(): int
     {
         $deletions = Deletion::all();
         $deleteCount = 0;
         foreach ($deletions as $deletion) {
-            // For each one we load in the relation since it may have already
-            // been deleted as part of another deletion in this loop.
-            $entity = $deletion->deletable()->first();
-            if ($entity) {
-                $count = $this->destroyEntity($deletion->deletable);
-                $deleteCount += $count;
-            }
-            $deletion->delete();
+            $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();
+            }
+
+            $entity->restore();
+            $count++;
+        };
+
+        if ($entity->isA('chapter') || $entity->isA('book')) {
+            $entity->pages()->withTrashed()->withCount('deletions')->get()->each($restoreAction);
+        }
+
+        if ($entity->isA('book')) {
+            $entity->chapters()->withTrashed()->withCount('deletions')->get()->each($restoreAction);
+        }
+
+        return $count;
+    }
+
     /**
      * Destroy the given entity.
      */