]> BookStack Code Mirror - bookstack/blob - app/Entities/Managers/TrashCan.php
Started implementation of recycle bin functionality
[bookstack] / app / Entities / Managers / TrashCan.php
1 <?php namespace BookStack\Entities\Managers;
2
3 use BookStack\Entities\Book;
4 use BookStack\Entities\Bookshelf;
5 use BookStack\Entities\Chapter;
6 use BookStack\Entities\DeleteRecord;
7 use BookStack\Entities\Entity;
8 use BookStack\Entities\HasCoverImage;
9 use BookStack\Entities\Page;
10 use BookStack\Exceptions\NotifyException;
11 use BookStack\Facades\Activity;
12 use BookStack\Uploads\AttachmentService;
13 use BookStack\Uploads\ImageService;
14 use Exception;
15
16 class TrashCan
17 {
18
19     /**
20      * Send a shelf to the recycle bin.
21      */
22     public function softDestroyShelf(Bookshelf $shelf)
23     {
24         DeleteRecord::createForEntity($shelf);
25         $shelf->delete();
26     }
27
28     /**
29      * Send a book to the recycle bin.
30      * @throws Exception
31      */
32     public function softDestroyBook(Book $book)
33     {
34         DeleteRecord::createForEntity($book);
35
36         foreach ($book->pages as $page) {
37             $this->softDestroyPage($page, false);
38         }
39
40         foreach ($book->chapters as $chapter) {
41             $this->softDestroyChapter($chapter, false);
42         }
43
44         $book->delete();
45     }
46
47     /**
48      * Send a chapter to the recycle bin.
49      * @throws Exception
50      */
51     public function softDestroyChapter(Chapter $chapter, bool $recordDelete = true)
52     {
53         if ($recordDelete) {
54             DeleteRecord::createForEntity($chapter);
55         }
56
57         if (count($chapter->pages) > 0) {
58             foreach ($chapter->pages as $page) {
59                 $this->softDestroyPage($page, false);
60             }
61         }
62
63         $chapter->delete();
64     }
65
66     /**
67      * Send a page to the recycle bin.
68      * @throws Exception
69      */
70     public function softDestroyPage(Page $page, bool $recordDelete = true)
71     {
72         if ($recordDelete) {
73             DeleteRecord::createForEntity($page);
74         }
75
76         // Check if set as custom homepage & remove setting if not used or throw error if active
77         $customHome = setting('app-homepage', '0:');
78         if (intval($page->id) === intval(explode(':', $customHome)[0])) {
79             if (setting('app-homepage-type') === 'page') {
80                 throw new NotifyException(trans('errors.page_custom_home_deletion'), $page->getUrl());
81             }
82             setting()->remove('app-homepage');
83         }
84
85         $page->delete();
86     }
87
88     /**
89      * Remove a bookshelf from the system.
90      * @throws Exception
91      */
92     public function destroyShelf(Bookshelf $shelf)
93     {
94         $this->destroyCommonRelations($shelf);
95         $shelf->forceDelete();
96     }
97
98     /**
99      * Remove a book from the system.
100      * Destroys any child chapters and pages.
101      * @throws Exception
102      */
103     public function destroyBook(Book $book)
104     {
105         $pages = $book->pages()->withTrashed()->get();
106         foreach ($pages as $page) {
107             $this->destroyPage($page);
108         }
109
110         $chapters = $book->chapters()->withTrashed()->get();
111         foreach ($chapters as $chapter) {
112             $this->destroyChapter($chapter);
113         }
114
115         $this->destroyCommonRelations($book);
116         $book->forceDelete();
117     }
118
119     /**
120      * Remove a chapter from the system.
121      * Destroys all pages within.
122      * @throws Exception
123      */
124     public function destroyChapter(Chapter $chapter)
125     {
126         $pages = $chapter->pages()->withTrashed()->get();
127         if (count($pages)) {
128             foreach ($pages as $page) {
129                 $this->destroyPage($page);
130             }
131         }
132
133         $this->destroyCommonRelations($chapter);
134         $chapter->forceDelete();
135     }
136
137     /**
138      * Remove a page from the system.
139      * @throws Exception
140      */
141     public function destroyPage(Page $page)
142     {
143         $this->destroyCommonRelations($page);
144
145         // Delete Attached Files
146         $attachmentService = app(AttachmentService::class);
147         foreach ($page->attachments as $attachment) {
148             $attachmentService->deleteFile($attachment);
149         }
150
151         $page->forceDelete();
152     }
153
154     /**
155      * Update entity relations to remove or update outstanding connections.
156      */
157     protected function destroyCommonRelations(Entity $entity)
158     {
159         Activity::removeEntity($entity);
160         $entity->views()->delete();
161         $entity->permissions()->delete();
162         $entity->tags()->delete();
163         $entity->comments()->delete();
164         $entity->jointPermissions()->delete();
165         $entity->searchTerms()->delete();
166         $entity->deleteRecords()->delete();
167
168         if ($entity instanceof HasCoverImage && $entity->cover) {
169             $imageService = app()->make(ImageService::class);
170             $imageService->destroy($entity->cover);
171         }
172     }
173 }