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