]> BookStack Code Mirror - bookstack/blob - app/Entities/Tools/PageEditorData.php
Permissions: Cleanup after review of enum implementation PR
[bookstack] / app / Entities / Tools / PageEditorData.php
1 <?php
2
3 namespace BookStack\Entities\Tools;
4
5 use BookStack\Activity\Tools\CommentTree;
6 use BookStack\Entities\Models\Page;
7 use BookStack\Entities\Queries\EntityQueries;
8 use BookStack\Entities\Tools\Markdown\HtmlToMarkdown;
9 use BookStack\Entities\Tools\Markdown\MarkdownToHtml;
10 use BookStack\Permissions\Permission;
11
12 class PageEditorData
13 {
14     protected array $viewData;
15     protected array $warnings;
16
17     public function __construct(
18         protected Page $page,
19         protected EntityQueries $queries,
20         protected string $requestedEditor
21     ) {
22         $this->viewData = $this->build();
23     }
24
25     public function getViewData(): array
26     {
27         return $this->viewData;
28     }
29
30     public function getWarnings(): array
31     {
32         return $this->warnings;
33     }
34
35     protected function build(): array
36     {
37         $page = clone $this->page;
38         $isDraft = boolval($this->page->draft);
39         $templates = $this->queries->pages->visibleTemplates()
40             ->orderBy('name', 'asc')
41             ->take(10)
42             ->paginate()
43             ->withPath('/templates');
44
45         $draftsEnabled = auth()->check();
46
47         $isDraftRevision = false;
48         $this->warnings = [];
49         $editActivity = new PageEditActivity($page);
50
51         if ($editActivity->hasActiveEditing()) {
52             $this->warnings[] = $editActivity->activeEditingMessage();
53         }
54
55         // Check for a current draft version for this user
56         $userDraft = $this->queries->revisions->findLatestCurrentUserDraftsForPageId($page->id);
57         if (!is_null($userDraft)) {
58             $page->forceFill($userDraft->only(['name', 'html', 'markdown']));
59             $isDraftRevision = true;
60             $this->warnings[] = $editActivity->getEditingActiveDraftMessage($userDraft);
61         }
62
63         $editorType = $this->getEditorType($page);
64         $this->updateContentForEditor($page, $editorType);
65
66         return [
67             'page'            => $page,
68             'book'            => $page->book,
69             'isDraft'         => $isDraft,
70             'isDraftRevision' => $isDraftRevision,
71             'draftsEnabled'   => $draftsEnabled,
72             'templates'       => $templates,
73             'editor'          => $editorType,
74             'comments'        => new CommentTree($page),
75         ];
76     }
77
78     protected function updateContentForEditor(Page $page, PageEditorType $editorType): void
79     {
80         $isHtml = !empty($page->html) && empty($page->markdown);
81
82         // HTML to markdown-clean conversion
83         if ($editorType === PageEditorType::Markdown && $isHtml && $this->requestedEditor === 'markdown-clean') {
84             $page->markdown = (new HtmlToMarkdown($page->html))->convert();
85         }
86
87         // Markdown to HTML conversion if we don't have HTML
88         if ($editorType->isHtmlBased() && !$isHtml) {
89             $page->html = (new MarkdownToHtml($page->markdown))->convert();
90         }
91     }
92
93     /**
94      * Get the type of editor to show for editing the given page.
95      * Defaults based upon the current content of the page otherwise will fall back
96      * to system default but will take a requested type (if provided) if permissions allow.
97      */
98     protected function getEditorType(Page $page): PageEditorType
99     {
100         $editorType = PageEditorType::forPage($page) ?: PageEditorType::getSystemDefault();
101
102         // Use the requested editor if valid and if we have permission
103         $requestedType = PageEditorType::fromRequestValue($this->requestedEditor);
104         if ($requestedType && userCan(Permission::EditorChange)) {
105             $editorType = $requestedType;
106         }
107
108         return $editorType;
109     }
110 }