]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/RecycleBinController.php
Pages: Redirect user to view if they can't edit
[bookstack] / app / Entities / Controllers / RecycleBinController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Activity\ActivityType;
6 use BookStack\Entities\Models\Deletion;
7 use BookStack\Entities\Models\Entity;
8 use BookStack\Entities\Repos\DeletionRepo;
9 use BookStack\Entities\Tools\TrashCan;
10 use BookStack\Http\Controller;
11
12 class RecycleBinController extends Controller
13 {
14     protected string $recycleBinBaseUrl = '/settings/recycle-bin';
15
16     /**
17      * On each request to a method of this controller check permissions
18      * using a middleware closure.
19      */
20     public function __construct()
21     {
22         $this->middleware(function ($request, $next) {
23             $this->checkPermission('settings-manage');
24             $this->checkPermission('restrictions-manage-all');
25
26             return $next($request);
27         });
28     }
29
30     /**
31      * Show the top-level listing for the recycle bin.
32      */
33     public function index()
34     {
35         $deletions = Deletion::query()->with(['deletable', 'deleter'])->paginate(10);
36
37         $this->setPageTitle(trans('settings.recycle_bin'));
38
39         return view('settings.recycle-bin.index', [
40             'deletions' => $deletions,
41         ]);
42     }
43
44     /**
45      * Show the page to confirm a restore of the deletion of the given id.
46      */
47     public function showRestore(string $id)
48     {
49         /** @var Deletion $deletion */
50         $deletion = Deletion::query()->findOrFail($id);
51
52         // Walk the parent chain to find any cascading parent deletions
53         $currentDeletable = $deletion->deletable;
54         $searching = true;
55         while ($searching && $currentDeletable instanceof Entity) {
56             $parent = $currentDeletable->getParent();
57             if ($parent && $parent->trashed()) {
58                 $currentDeletable = $parent;
59             } else {
60                 $searching = false;
61             }
62         }
63
64         /** @var ?Deletion $parentDeletion */
65         $parentDeletion = ($currentDeletable === $deletion->deletable) ? null : $currentDeletable->deletions()->first();
66
67         return view('settings.recycle-bin.restore', [
68             'deletion'       => $deletion,
69             'parentDeletion' => $parentDeletion,
70         ]);
71     }
72
73     /**
74      * Restore the element attached to the given deletion.
75      *
76      * @throws \Exception
77      */
78     public function restore(DeletionRepo $deletionRepo, string $id)
79     {
80         $restoreCount = $deletionRepo->restore((int) $id);
81
82         $this->showSuccessNotification(trans('settings.recycle_bin_restore_notification', ['count' => $restoreCount]));
83
84         return redirect($this->recycleBinBaseUrl);
85     }
86
87     /**
88      * Show the page to confirm a Permanent deletion of the element attached to the deletion of the given id.
89      */
90     public function showDestroy(string $id)
91     {
92         /** @var Deletion $deletion */
93         $deletion = Deletion::query()->findOrFail($id);
94
95         return view('settings.recycle-bin.destroy', [
96             'deletion' => $deletion,
97         ]);
98     }
99
100     /**
101      * Permanently delete the content associated with the given deletion.
102      *
103      * @throws \Exception
104      */
105     public function destroy(DeletionRepo $deletionRepo, string $id)
106     {
107         $deleteCount = $deletionRepo->destroy((int) $id);
108
109         $this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
110
111         return redirect($this->recycleBinBaseUrl);
112     }
113
114     /**
115      * Empty out the recycle bin.
116      *
117      * @throws \Exception
118      */
119     public function empty(TrashCan $trash)
120     {
121         $deleteCount = $trash->empty();
122
123         $this->logActivity(ActivityType::RECYCLE_BIN_EMPTY);
124         $this->showSuccessNotification(trans('settings.recycle_bin_destroy_notification', ['count' => $deleteCount]));
125
126         return redirect($this->recycleBinBaseUrl);
127     }
128 }