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