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