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