]> BookStack Code Mirror - bookstack/blob - app/Entities/Controllers/PageRevisionController.php
Played around with a new app structure
[bookstack] / app / Entities / Controllers / PageRevisionController.php
1 <?php
2
3 namespace BookStack\Entities\Controllers;
4
5 use BookStack\Activity\ActivityType;
6 use BookStack\Entities\Models\PageRevision;
7 use BookStack\Entities\Repos\PageRepo;
8 use BookStack\Entities\Tools\PageContent;
9 use BookStack\Exceptions\NotFoundException;
10 use BookStack\Facades\Activity;
11 use BookStack\Http\Controllers\Controller;
12 use BookStack\Util\SimpleListOptions;
13 use Illuminate\Http\Request;
14 use Ssddanbrown\HtmlDiff\Diff;
15
16 class PageRevisionController extends Controller
17 {
18     protected PageRepo $pageRepo;
19
20     public function __construct(PageRepo $pageRepo)
21     {
22         $this->pageRepo = $pageRepo;
23     }
24
25     /**
26      * Shows the last revisions for this page.
27      *
28      * @throws NotFoundException
29      */
30     public function index(Request $request, string $bookSlug, string $pageSlug)
31     {
32         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
33         $listOptions = SimpleListOptions::fromRequest($request, 'page_revisions', true)->withSortOptions([
34             'id' => trans('entities.pages_revisions_sort_number')
35         ]);
36
37         $revisions = $page->revisions()->select([
38                 'id', 'page_id', 'name', 'created_at', 'created_by', 'updated_at',
39                 'type', 'revision_number', 'summary',
40             ])
41             ->selectRaw("IF(markdown = '', false, true) as is_markdown")
42             ->with(['page.book', 'createdBy'])
43             ->reorder('id', $listOptions->getOrder())
44             ->reorder('created_at', $listOptions->getOrder())
45             ->paginate(50);
46
47         $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName' => $page->getShortName()]));
48
49         return view('pages.revisions', [
50             'revisions'   => $revisions,
51             'page'        => $page,
52             'listOptions' => $listOptions,
53         ]);
54     }
55
56     /**
57      * Shows a preview of a single revision.
58      *
59      * @throws NotFoundException
60      */
61     public function show(string $bookSlug, string $pageSlug, int $revisionId)
62     {
63         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
64         /** @var ?PageRevision $revision */
65         $revision = $page->revisions()->where('id', '=', $revisionId)->first();
66         if ($revision === null) {
67             throw new NotFoundException();
68         }
69
70         $page->fill($revision->toArray());
71         // TODO - Refactor PageContent so we don't need to juggle this
72         $page->html = $revision->html;
73         $page->html = (new PageContent($page))->render();
74
75         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
76
77         return view('pages.revision', [
78             'page'     => $page,
79             'book'     => $page->book,
80             'diff'     => null,
81             'revision' => $revision,
82         ]);
83     }
84
85     /**
86      * Shows the changes of a single revision.
87      *
88      * @throws NotFoundException
89      */
90     public function changes(string $bookSlug, string $pageSlug, int $revisionId)
91     {
92         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
93         /** @var ?PageRevision $revision */
94         $revision = $page->revisions()->where('id', '=', $revisionId)->first();
95         if ($revision === null) {
96             throw new NotFoundException();
97         }
98
99         $prev = $revision->getPrevious();
100         $prevContent = $prev->html ?? '';
101         $diff = Diff::excecute($prevContent, $revision->html);
102
103         $page->fill($revision->toArray());
104         // TODO - Refactor PageContent so we don't need to juggle this
105         $page->html = $revision->html;
106         $page->html = (new PageContent($page))->render();
107         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
108
109         return view('pages.revision', [
110             'page'     => $page,
111             'book'     => $page->book,
112             'diff'     => $diff,
113             'revision' => $revision,
114         ]);
115     }
116
117     /**
118      * Restores a page using the content of the specified revision.
119      *
120      * @throws NotFoundException
121      */
122     public function restore(string $bookSlug, string $pageSlug, int $revisionId)
123     {
124         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
125         $this->checkOwnablePermission('page-update', $page);
126
127         $page = $this->pageRepo->restoreRevision($page, $revisionId);
128
129         return redirect($page->getUrl());
130     }
131
132     /**
133      * Deletes a revision using the id of the specified revision.
134      *
135      * @throws NotFoundException
136      */
137     public function destroy(string $bookSlug, string $pageSlug, int $revId)
138     {
139         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
140         $this->checkOwnablePermission('page-delete', $page);
141
142         $revision = $page->revisions()->where('id', '=', $revId)->first();
143         if ($revision === null) {
144             throw new NotFoundException("Revision #{$revId} not found");
145         }
146
147         // Check if it's the latest revision, cannot delete the latest revision.
148         if (intval($page->currentRevision->id ?? null) === intval($revId)) {
149             $this->showErrorNotification(trans('entities.revision_cannot_delete_latest'));
150
151             return redirect($page->getUrl('/revisions'));
152         }
153
154         $revision->delete();
155         Activity::add(ActivityType::REVISION_DELETE, $revision);
156         $this->showSuccessNotification(trans('entities.revision_delete_success'));
157
158         return redirect($page->getUrl('/revisions'));
159     }
160 }