+ public function getParentFromSlugs(string $bookSlug, string $chapterSlug = null): Entity
+ {
+ if ($chapterSlug !== null) {
+ return $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail();
+ }
+
+ return Book::visible()->where('slug', '=', $bookSlug)->firstOrFail();
+ }
+
+ /**
+ * Get the draft copy of the given page for the current user.
+ */
+ public function getUserDraft(Page $page): ?PageRevision
+ {
+ $revision = $this->getUserDraftQuery($page)->first();
+ return $revision;
+ }
+
+ /**
+ * Get a new draft page belonging to the given parent entity.
+ */
+ public function getNewDraftPage(Entity $parent)
+ {
+ $page = (new Page())->forceFill([
+ 'name' => trans('entities.pages_initial_name'),
+ 'created_by' => user()->id,
+ 'updated_by' => user()->id,
+ 'draft' => true,
+ ]);
+
+ if ($parent instanceof Chapter) {
+ $page->chapter_id = $parent->id;
+ $page->book_id = $parent->book_id;
+ } else {
+ $page->book_id = $parent->id;
+ }
+
+ $page->save();
+ $page->refresh()->rebuildPermissions();
+ return $page;
+ }
+
+ /**
+ * Publish a draft page to make it a live, non-draft page.
+ */
+ public function publishDraft(Page $draft, array $input): Page
+ {
+ $this->baseRepo->update($draft, $input);
+ if (isset($input['template']) && userCan('templates-manage')) {
+ $draft->template = ($input['template'] === 'true');
+ }
+
+ $pageContent = new PageContent($draft);
+ $pageContent->setNewHTML($input['html']);
+ $draft->draft = false;
+ $draft->revision_count = 1;
+ $draft->priority = $this->getNewPriority($draft);
+ $draft->refreshSlug();
+ $draft->save();
+
+ $this->savePageRevision($draft, trans('entities.pages_initial_revision'));
+ $draft->indexForSearch();
+ return $draft->refresh();
+ }
+
+ /**
+ * Update a page in the system.
+ */
+ public function update(Page $page, array $input): Page