3 namespace BookStack\Http\Controllers;
5 use BookStack\Entities\Repos\PageRepo;
6 use BookStack\Entities\Tools\PageContent;
7 use BookStack\Exceptions\NotFoundException;
8 use Ssddanbrown\HtmlDiff\Diff;
10 class PageRevisionController extends Controller
15 * PageRevisionController constructor.
17 public function __construct(PageRepo $pageRepo)
19 $this->pageRepo = $pageRepo;
23 * Shows the last revisions for this page.
25 * @throws NotFoundException
27 public function index(string $bookSlug, string $pageSlug)
29 $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
30 $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
32 return view('pages.revisions', [
39 * Shows a preview of a single revision.
41 * @throws NotFoundException
43 public function show(string $bookSlug, string $pageSlug, int $revisionId)
45 $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
46 $revision = $page->revisions()->where('id', '=', $revisionId)->first();
47 if ($revision === null) {
48 throw new NotFoundException();
51 $page->fill($revision->toArray());
52 // TODO - Refactor PageContent so we don't need to juggle this
53 $page->html = $revision->html;
54 $page->html = (new PageContent($page))->render();
56 $this->setPageTitle(trans('entities.pages_revision_named', ['pageName' => $page->getShortName()]));
58 return view('pages.revision', [
60 'book' => $page->book,
62 'revision' => $revision,
67 * Shows the changes of a single revision.
69 * @throws NotFoundException
71 public function changes(string $bookSlug, string $pageSlug, int $revisionId)
73 $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
74 $revision = $page->revisions()->where('id', '=', $revisionId)->first();
75 if ($revision === null) {
76 throw new NotFoundException();
79 $prev = $revision->getPrevious();
80 $prevContent = $prev->html ?? '';
81 $diff = Diff::excecute($prevContent, $revision->html);
83 $page->fill($revision->toArray());
84 // TODO - Refactor PageContent so we don't need to juggle this
85 $page->html = $revision->html;
86 $page->html = (new PageContent($page))->render();
87 $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
89 return view('pages.revision', [
91 'book' => $page->book,
93 'revision' => $revision,
98 * Restores a page using the content of the specified revision.
100 * @throws NotFoundException
102 public function restore(string $bookSlug, string $pageSlug, int $revisionId)
104 $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
105 $this->checkOwnablePermission('page-update', $page);
107 $page = $this->pageRepo->restoreRevision($page, $revisionId);
109 return redirect($page->getUrl());
113 * Deletes a revision using the id of the specified revision.
115 * @throws NotFoundException
117 public function destroy(string $bookSlug, string $pageSlug, int $revId)
119 $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
120 $this->checkOwnablePermission('page-delete', $page);
122 $revision = $page->revisions()->where('id', '=', $revId)->first();
123 if ($revision === null) {
124 throw new NotFoundException("Revision #{$revId} not found");
127 // Check if it's the latest revision, cannot delete the latest revision.
128 if (intval($page->currentRevision->id ?? null) === intval($revId)) {
129 $this->showErrorNotification(trans('entities.revision_cannot_delete_latest'));
131 return redirect($page->getUrl('/revisions'));
135 $this->showSuccessNotification(trans('entities.revision_delete_success'));
137 return redirect($page->getUrl('/revisions'));