| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | namespace BookStack\Entities\Tools; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Entities\EntityProvider; | 
					
						
							| 
									
										
										
										
											2020-11-22 08:17:45 +08:00
										 |  |  | use BookStack\Entities\Models\Book; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Bookshelf; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Chapter; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Deletion; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Entity; | 
					
						
							|  |  |  | use BookStack\Entities\Models\HasCoverImage; | 
					
						
							|  |  |  | use BookStack\Entities\Models\Page; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | use BookStack\Exceptions\NotifyException; | 
					
						
							|  |  |  | use BookStack\Facades\Activity; | 
					
						
							|  |  |  | use BookStack\Uploads\AttachmentService; | 
					
						
							|  |  |  | use BookStack\Uploads\ImageService; | 
					
						
							|  |  |  | use Exception; | 
					
						
							| 
									
										
										
										
											2021-11-23 07:33:55 +08:00
										 |  |  | use Illuminate\Database\Eloquent\Builder; | 
					
						
							| 
									
										
										
										
											2020-11-07 21:58:23 +08:00
										 |  |  | use Illuminate\Support\Carbon; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TrashCan | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * Send a shelf to the recycle bin. | 
					
						
							| 
									
										
										
										
											2022-01-11 02:18:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |      * @throws NotifyException | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     public function softDestroyShelf(Bookshelf $shelf) | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |         $this->ensureDeletable($shelf); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         Deletion::createForEntity($shelf); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         $shelf->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * Send a book to the recycle bin. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     public function softDestroyBook(Book $book) | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |         $this->ensureDeletable($book); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         Deletion::createForEntity($book); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         foreach ($book->pages as $page) { | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |             $this->softDestroyPage($page, false); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($book->chapters as $chapter) { | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |             $this->softDestroyChapter($chapter, false); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $book->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * Send a chapter to the recycle bin. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     public function softDestroyChapter(Chapter $chapter, bool $recordDelete = true) | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         if ($recordDelete) { | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |             $this->ensureDeletable($chapter); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             Deletion::createForEntity($chapter); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (count($chapter->pages) > 0) { | 
					
						
							|  |  |  |             foreach ($chapter->pages as $page) { | 
					
						
							|  |  |  |                 $this->softDestroyPage($page, false); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $chapter->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Send a page to the recycle bin. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function softDestroyPage(Page $page, bool $recordDelete = true) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($recordDelete) { | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |             $this->ensureDeletable($page); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             Deletion::createForEntity($page); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |         $page->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Ensure the given entity is deletable. | 
					
						
							|  |  |  |      * Is not for permissions, but logical conditions within the application. | 
					
						
							|  |  |  |      * Will throw if not deletable. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @throws NotifyException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function ensureDeletable(Entity $entity): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $customHomeId = intval(explode(':', setting('app-homepage', '0:'))[0]); | 
					
						
							|  |  |  |         $customHomeActive = setting('app-homepage-type') === 'page'; | 
					
						
							|  |  |  |         $removeCustomHome = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Check custom homepage usage for pages
 | 
					
						
							|  |  |  |         if ($entity instanceof Page && $entity->id === $customHomeId) { | 
					
						
							|  |  |  |             if ($customHomeActive) { | 
					
						
							|  |  |  |                 throw new NotifyException(trans('errors.page_custom_home_deletion'), $entity->getUrl()); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |             $removeCustomHome = true; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 01:04:01 +08:00
										 |  |  |         // Check custom homepage usage within chapters or books
 | 
					
						
							|  |  |  |         if ($entity instanceof Chapter || $entity instanceof Book) { | 
					
						
							|  |  |  |             if ($entity->pages()->where('id', '=', $customHomeId)->exists()) { | 
					
						
							|  |  |  |                 if ($customHomeActive) { | 
					
						
							|  |  |  |                     throw new NotifyException(trans('errors.page_custom_home_deletion'), $entity->getUrl()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 $removeCustomHome = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ($removeCustomHome) { | 
					
						
							|  |  |  |             setting()->remove('app-homepage'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Remove a bookshelf from the system. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-11-06 20:54:39 +08:00
										 |  |  |     protected function destroyShelf(Bookshelf $shelf): int | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->destroyCommonRelations($shelf); | 
					
						
							|  |  |  |         $shelf->forceDelete(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove a book from the system. | 
					
						
							|  |  |  |      * Destroys any child chapters and pages. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-11-06 20:54:39 +08:00
										 |  |  |     protected function destroyBook(Book $book): int | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         $count = 0; | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         $pages = $book->pages()->withTrashed()->get(); | 
					
						
							|  |  |  |         foreach ($pages as $page) { | 
					
						
							|  |  |  |             $this->destroyPage($page); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |             $count++; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         $chapters = $book->chapters()->withTrashed()->get(); | 
					
						
							|  |  |  |         foreach ($chapters as $chapter) { | 
					
						
							|  |  |  |             $this->destroyChapter($chapter); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |             $count++; | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->destroyCommonRelations($book); | 
					
						
							|  |  |  |         $book->forceDelete(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         return $count + 1; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove a chapter from the system. | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * Destroys all pages within. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-11-06 20:54:39 +08:00
										 |  |  |     protected function destroyChapter(Chapter $chapter): int | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         $count = 0; | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         $pages = $chapter->pages()->withTrashed()->get(); | 
					
						
							| 
									
										
										
										
											2021-11-23 07:33:55 +08:00
										 |  |  |         foreach ($pages as $page) { | 
					
						
							|  |  |  |             $this->destroyPage($page); | 
					
						
							|  |  |  |             $count++; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->destroyCommonRelations($chapter); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |         $chapter->forceDelete(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         return $count + 1; | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Remove a page from the system. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-11-06 20:54:39 +08:00
										 |  |  |     protected function destroyPage(Page $page): int | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->destroyCommonRelations($page); | 
					
						
							| 
									
										
										
										
											2021-05-26 23:40:56 +08:00
										 |  |  |         $page->allRevisions()->delete(); | 
					
						
							| 
									
										
										
										
											2020-09-28 06:24:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Delete Attached Files
 | 
					
						
							|  |  |  |         $attachmentService = app(AttachmentService::class); | 
					
						
							|  |  |  |         foreach ($page->attachments as $attachment) { | 
					
						
							|  |  |  |             $attachmentService->deleteFile($attachment); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $page->forceDelete(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get the total counts of those that have been trashed | 
					
						
							|  |  |  |      * but not yet fully deleted (In recycle bin). | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getTrashedCounts(): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $counts = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         foreach ((new EntityProvider())->all() as $key => $instance) { | 
					
						
							| 
									
										
										
										
											2021-11-23 07:33:55 +08:00
										 |  |  |             /** @var Builder<Entity> $query */ | 
					
						
							|  |  |  |             $query = $instance->newQuery(); | 
					
						
							|  |  |  |             $counts[$key] = $query->onlyTrashed()->count(); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $counts; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Destroy all items that have pending deletions. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-11-06 20:54:39 +08:00
										 |  |  |     public function empty(): int | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $deletions = Deletion::all(); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         $deleteCount = 0; | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         foreach ($deletions as $deletion) { | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |             $deleteCount += $this->destroyFromDeletion($deletion); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |         return $deleteCount; | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Destroy an element from the given deletion model. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |      * @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(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |         return $count; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Restore the content within the given deletion. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |      * @throws Exception | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function restoreFromDeletion(Deletion $deletion): int | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $shouldRestore = true; | 
					
						
							|  |  |  |         $restoreCount = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-20 22:03:56 +08:00
										 |  |  |         if ($deletion->deletable instanceof Entity) { | 
					
						
							|  |  |  |             $parent = $deletion->deletable->getParent(); | 
					
						
							|  |  |  |             if ($parent && $parent->trashed()) { | 
					
						
							|  |  |  |                 $shouldRestore = false; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-20 22:03:56 +08:00
										 |  |  |         if ($deletion->deletable instanceof Entity && $shouldRestore) { | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |             $restoreCount = $this->restoreEntity($deletion->deletable); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $deletion->delete(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |         return $restoreCount; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-07 21:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Automatically clear old content from the recycle bin | 
					
						
							|  |  |  |      * depending on the configured lifetime. | 
					
						
							|  |  |  |      * Returns the total number of deleted elements. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-11-07 21:58:23 +08:00
										 |  |  |      * @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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * 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(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-03 06:54:00 +08:00
										 |  |  |         $restoreAction = function ($entity) use (&$count) { | 
					
						
							|  |  |  |             if ($entity->deletions_count > 0) { | 
					
						
							|  |  |  |                 $entity->deletions()->delete(); | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-11-03 06:54:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             $entity->restore(); | 
					
						
							|  |  |  |             $count++; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Chapter || $entity instanceof Book) { | 
					
						
							| 
									
										
										
										
											2020-11-03 06:54:00 +08:00
										 |  |  |             $entity->pages()->withTrashed()->withCount('deletions')->get()->each($restoreAction); | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Book) { | 
					
						
							| 
									
										
										
										
											2020-11-03 06:54:00 +08:00
										 |  |  |             $entity->chapters()->withTrashed()->withCount('deletions')->get()->each($restoreAction); | 
					
						
							| 
									
										
										
										
											2020-11-03 06:47:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $count; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Destroy the given entity. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-10-04 01:53:09 +08:00
										 |  |  |     protected function destroyEntity(Entity $entity): int | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Page) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             return $this->destroyPage($entity); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Chapter) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             return $this->destroyChapter($entity); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Book) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             return $this->destroyBook($entity); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-02-06 21:29:39 +08:00
										 |  |  |         if ($entity instanceof Bookshelf) { | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |             return $this->destroyShelf($entity); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-11-06 00:18:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Update entity relations to remove or update outstanding connections. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function destroyCommonRelations(Entity $entity) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Activity::removeEntity($entity); | 
					
						
							|  |  |  |         $entity->views()->delete(); | 
					
						
							|  |  |  |         $entity->permissions()->delete(); | 
					
						
							|  |  |  |         $entity->tags()->delete(); | 
					
						
							|  |  |  |         $entity->comments()->delete(); | 
					
						
							|  |  |  |         $entity->jointPermissions()->delete(); | 
					
						
							|  |  |  |         $entity->searchTerms()->delete(); | 
					
						
							| 
									
										
										
										
											2020-10-04 01:44:12 +08:00
										 |  |  |         $entity->deletions()->delete(); | 
					
						
							| 
									
										
										
										
											2021-05-23 20:41:56 +08:00
										 |  |  |         $entity->favourites()->delete(); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-23 07:33:55 +08:00
										 |  |  |         if ($entity instanceof HasCoverImage && $entity->cover()->exists()) { | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |             $imageService = app()->make(ImageService::class); | 
					
						
							| 
									
										
										
										
											2021-11-23 07:33:55 +08:00
										 |  |  |             $imageService->destroy($entity->cover()->first()); | 
					
						
							| 
									
										
										
										
											2019-10-05 19:55:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |