]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/PageRevisionController.php
Organised activity types and moved most to repos
[bookstack] / app / Http / Controllers / PageRevisionController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Actions\ActivityType;
4 use BookStack\Entities\Managers\PageContent;
5 use BookStack\Entities\Repos\PageRepo;
6 use BookStack\Exceptions\NotFoundException;
7 use BookStack\Facades\Activity;
8 use GatherContent\Htmldiff\Htmldiff;
9
10 class PageRevisionController extends Controller
11 {
12
13     protected $pageRepo;
14
15     /**
16      * PageRevisionController constructor.
17      */
18     public function __construct(PageRepo $pageRepo)
19     {
20         $this->pageRepo = $pageRepo;
21         parent::__construct();
22     }
23
24     /**
25      * Shows the last revisions for this page.
26      * @throws NotFoundException
27      */
28     public function index(string $bookSlug, string $pageSlug)
29     {
30         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
31         $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
32         return view('pages.revisions', [
33             'page' => $page,
34             'current' => $page
35         ]);
36     }
37
38     /**
39      * Shows a preview of a single revision.
40      * @throws NotFoundException
41      */
42     public function show(string $bookSlug, string $pageSlug, int $revisionId)
43     {
44         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
45         $revision = $page->revisions()->where('id', '=', $revisionId)->first();
46         if ($revision === null) {
47             throw new NotFoundException();
48         }
49
50         $page->fill($revision->toArray());
51         // TODO - Refactor PageContent so we don't need to juggle this
52         $page->html = $revision->html;
53         $page->html = (new PageContent($page))->render();
54
55         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
56         return view('pages.revision', [
57             'page' => $page,
58             'book' => $page->book,
59             'diff' => null,
60             'revision' => $revision
61         ]);
62     }
63
64     /**
65      * Shows the changes of a single revision.
66      * @throws NotFoundException
67      */
68     public function changes(string $bookSlug, string $pageSlug, int $revisionId)
69     {
70         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
71         $revision = $page->revisions()->where('id', '=', $revisionId)->first();
72         if ($revision === null) {
73             throw new NotFoundException();
74         }
75
76         $prev = $revision->getPrevious();
77         $prevContent = $prev->html ?? '';
78         $diff = (new Htmldiff)->diff($prevContent, $revision->html);
79
80         $page->fill($revision->toArray());
81         // TODO - Refactor PageContent so we don't need to juggle this
82         $page->html = $revision->html;
83         $page->html = (new PageContent($page))->render();
84         $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
85
86         return view('pages.revision', [
87             'page' => $page,
88             'book' => $page->book,
89             'diff' => $diff,
90             'revision' => $revision
91         ]);
92     }
93
94     /**
95      * Restores a page using the content of the specified revision.
96      * @throws NotFoundException
97      */
98     public function restore(string $bookSlug, string $pageSlug, int $revisionId)
99     {
100         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
101         $this->checkOwnablePermission('page-update', $page);
102
103         $page = $this->pageRepo->restoreRevision($page, $revisionId);
104
105         return redirect($page->getUrl());
106     }
107
108     /**
109      * Deletes a revision using the id of the specified revision.
110      * @throws NotFoundException
111      */
112     public function destroy(string $bookSlug, string $pageSlug, int $revId)
113     {
114         $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
115         $this->checkOwnablePermission('page-delete', $page);
116
117         $revision = $page->revisions()->where('id', '=', $revId)->first();
118         if ($revision === null) {
119             throw new NotFoundException("Revision #{$revId} not found");
120         }
121
122         // Get the current revision for the page
123         $currentRevision = $page->getCurrentRevision();
124
125         // Check if its the latest revision, cannot delete latest revision.
126         if (intval($currentRevision->id) === intval($revId)) {
127             $this->showErrorNotification(trans('entities.revision_cannot_delete_latest'));
128             return redirect($page->getUrl('/revisions'));
129         }
130
131         $revision->delete();
132         $this->showSuccessNotification(trans('entities.revision_delete_success'));
133         return redirect($page->getUrl('/revisions'));
134     }
135 }