]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/RecycleBinApiController.php
Merge pull request #5917 from BookStackApp/copy_references
[bookstack] / app / Entities / Controllers / RecycleBinApiController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Entities\Models\Book;
6 use BookStack\Entities\Models\BookChild;
7 use BookStack\Entities\Models\Chapter;
8 use BookStack\Entities\Models\Deletion;
9 use BookStack\Entities\Models\Page;
10 use BookStack\Entities\Repos\DeletionRepo;
11 use BookStack\Http\ApiController;
12 use BookStack\Permissions\Permission;
13 use Illuminate\Database\Eloquent\Builder;
14 use Illuminate\Database\Eloquent\Relations\HasMany;
15
16 class RecycleBinApiController extends ApiController
17 {
18     public function __construct()
19     {
20         $this->middleware(function ($request, $next) {
21             $this->checkPermission(Permission::SettingsManage);
22             $this->checkPermission(Permission::RestrictionsManageAll);
23
24             return $next($request);
25         });
26     }
27
28     /**
29      * Get a top-level listing of the items in the recycle bin.
30      * The "deletable" property will reflect the main item deleted.
31      * For books and chapters, counts of child pages/chapters will
32      * be loaded within this "deletable" data.
33      * For chapters & pages, the parent item will be loaded within this "deletable" data.
34      * Requires permission to manage both system settings and permissions.
35      */
36     public function list()
37     {
38         return $this->apiListingResponse(Deletion::query()->with('deletable'), [
39             'id',
40             'deleted_by',
41             'created_at',
42             'updated_at',
43             'deletable_type',
44             'deletable_id',
45         ], [$this->listFormatter(...)]);
46     }
47
48     /**
49      * Restore a single deletion from the recycle bin.
50      * Requires permission to manage both system settings and permissions.
51      */
52     public function restore(DeletionRepo $deletionRepo, string $deletionId)
53     {
54         $restoreCount = $deletionRepo->restore(intval($deletionId));
55
56         return response()->json(['restore_count' => $restoreCount]);
57     }
58
59     /**
60      * Remove a single deletion from the recycle bin.
61      * Use this endpoint carefully as it will entirely remove the underlying deleted items from the system.
62      * Requires permission to manage both system settings and permissions.
63      */
64     public function destroy(DeletionRepo $deletionRepo, string $deletionId)
65     {
66         $deleteCount = $deletionRepo->destroy(intval($deletionId));
67
68         return response()->json(['delete_count' => $deleteCount]);
69     }
70
71     /**
72      * Load some related details for the deletion listing.
73      */
74     protected function listFormatter(Deletion $deletion): void
75     {
76         $deletable = $deletion->deletable;
77
78         if ($deletable instanceof BookChild) {
79             $parent = $deletable->getParent();
80             $parent->setAttribute('type', $parent->getType());
81             $deletable->setRelation('parent', $parent);
82         }
83
84         if ($deletable instanceof Book || $deletable instanceof Chapter) {
85             $countsToLoad = ['pages' => static::withTrashedQuery(...)];
86             if ($deletable instanceof Book) {
87                 $countsToLoad['chapters'] = static::withTrashedQuery(...);
88             }
89             $deletable->loadCount($countsToLoad);
90         }
91     }
92
93     /**
94      * @param Builder<Chapter|Page> $query
95      */
96     protected static function withTrashedQuery(Builder $query): void
97     {
98         $query->withTrashed();
99     }
100 }