diff --git a/app/App/HomeController.php b/app/App/HomeController.php index 00e2db3df43..ac3bd765661 100644 --- a/app/App/HomeController.php +++ b/app/App/HomeController.php @@ -45,7 +45,7 @@ public function index( : $this->queries->books->visibleForList()->orderBy('created_at', 'desc')->take(12 * $recentFactor)->get(); $favourites = $topFavourites->run(6); $recentlyUpdatedPages = $this->queries->pages->visibleForList() - ->where('draft', false) + ->where('entity_page_data.draft', false) ->orderBy('updated_at', 'desc') ->take($favourites->count() > 0 ? 5 : 10) ->get(); @@ -102,7 +102,9 @@ public function index( $homepageSetting = setting('app-homepage', '0:'); $id = intval(explode(':', $homepageSetting)[0]); /** @var Page $customHomepage */ - $customHomepage = $this->queries->pages->start()->where('draft', '=', false)->findOrFail($id); + $customHomepage = $this->queries->pages->start() + ->where('entity_page_data.draft', '=', false) + ->findOrFail($id); $pageContent = new PageContent($customHomepage); $customHomepage->html = $pageContent->render(false); diff --git a/app/Config/setting-defaults.php b/app/Config/setting-defaults.php index 2f270b283a2..827cdb1addd 100644 --- a/app/Config/setting-defaults.php +++ b/app/Config/setting-defaults.php @@ -32,6 +32,7 @@ 'page-draft-color-dark' => '#a66ce8', 'app-custom-head' => false, 'registration-enabled' => false, + 'default_page_cover_image' => ENV('DEFAULT_PAGE_COVER_IMAGE', 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='), // User-level default settings 'user' => [ @@ -41,6 +42,7 @@ 'bookshelves_view_type' => env('APP_VIEWS_BOOKSHELVES', 'grid'), 'bookshelf_view_type' => env('APP_VIEWS_BOOKSHELF', 'grid'), 'books_view_type' => env('APP_VIEWS_BOOKS', 'grid'), + 'pages_view_type' => env('APP_VIEWS_BOOKS', 'grid'), 'notifications#comment-mentions' => true, ], diff --git a/app/Entities/Controllers/ChapterController.php b/app/Entities/Controllers/ChapterController.php index db2391599ab..b8f06e61437 100644 --- a/app/Entities/Controllers/ChapterController.php +++ b/app/Entities/Controllers/ChapterController.php @@ -77,8 +77,10 @@ public function store(Request $request, string $bookSlug) */ public function show(string $bookSlug, string $chapterSlug) { + $view = setting()->getForCurrentUser(key: 'pages_view_type'); try { $chapter = $this->queries->findVisibleBySlugsOrFail($bookSlug, $chapterSlug); + $this->checkOwnablePermission('chapter-view', $chapter); } catch (NotFoundException $exception) { $chapter = $this->entityQueries->findVisibleByOldSlugs('chapter', $chapterSlug, $bookSlug); if (is_null($chapter)) { @@ -105,6 +107,7 @@ public function show(string $bookSlug, string $chapterSlug) 'next' => $nextPreviousLocator->getNext(), 'previous' => $nextPreviousLocator->getPrevious(), 'referenceCount' => $this->referenceFetcher->getReferenceCountToEntity($chapter), + 'view' => $view, ]); } diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index 82edfbc2763..7d507d98ec8 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -226,6 +226,12 @@ public function update(Request $request, string $bookSlug, string $pageSlug) $page = $this->queries->findVisibleBySlugsOrFail($bookSlug, $pageSlug); $this->checkOwnablePermission(Permission::PageUpdate, $page); + if ($request->has('image_reset')) { + $request['image'] = null; + } elseif (array_key_exists('image', $request->all()) && is_null($request['image'])) { + unset($request['image']); + } + $this->pageRepo->update($page, $request->all()); return redirect($page->getUrl()); diff --git a/app/Entities/Models/Entity.php b/app/Entities/Models/Entity.php index 27cfccaa836..dc609f81414 100644 --- a/app/Entities/Models/Entity.php +++ b/app/Entities/Models/Entity.php @@ -47,6 +47,8 @@ * @property int|null $updated_by * @property int|null $owned_by * @property Collection $tags + * @property string $description + * @property string $description_html * * @method static Entity|Builder visible() * @method static Builder withLastView() diff --git a/app/Entities/Models/EntityContainerData.php b/app/Entities/Models/EntityContainerData.php index 21bace7513f..6b4c54f7f17 100644 --- a/app/Entities/Models/EntityContainerData.php +++ b/app/Entities/Models/EntityContainerData.php @@ -19,6 +19,15 @@ class EntityContainerData extends Model public $timestamps = false; protected $primaryKey = 'entity_id'; public $incrementing = false; + protected $fillable = [ + 'entity_id', + 'entity_type', + 'description', + 'description_html', + 'default_template_id', + 'image_id', + 'sort_rule_id', + ]; public static array $fields = [ 'description', diff --git a/app/Entities/Models/EntityPageData.php b/app/Entities/Models/EntityPageData.php index a98b1a9823c..0d3c62f79ce 100644 --- a/app/Entities/Models/EntityPageData.php +++ b/app/Entities/Models/EntityPageData.php @@ -21,5 +21,6 @@ class EntityPageData extends Model 'html', 'text', 'markdown', + 'image_id' ]; } diff --git a/app/Entities/Models/Page.php b/app/Entities/Models/Page.php index d3a392da6fa..d4d6d32df7e 100644 --- a/app/Entities/Models/Page.php +++ b/app/Entities/Models/Page.php @@ -2,9 +2,14 @@ namespace BookStack\Entities\Models; +use BookStack\Entities\Tools\EntityCover; +use BookStack\Entities\Tools\EntityDefaultTemplate; +use BookStack\Entities\Tools\EntityHtmlDescription; +use BookStack\Uploads\Image; use BookStack\Entities\Tools\PageContent; use BookStack\Permissions\PermissionApplicator; use BookStack\Uploads\Attachment; +use Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -23,22 +28,25 @@ * @property bool $draft * @property int $revision_count * @property string $editor - * @property Chapter|null $chapter + * @property Image|null $cover + * @property Chapter $chapter * @property Collection $attachments * @property Collection $revisions * @property PageRevision $currentRevision */ -class Page extends BookChild +class Page extends BookChild implements HasDescriptionInterface, HasCoverInterface { use HasFactory; + // use ContainerTrait; + public string $textField = 'text'; public string $htmlField = 'html'; - protected $hidden = ['html', 'markdown', 'text', 'pivot', 'deleted_at', 'entity_id', 'entity_type']; + protected $hidden = ['html', 'markdown', 'text', 'pivot', 'deleted_at', 'entity_id', 'entity_type']; protected $fillable = ['name', 'priority']; protected $casts = [ - 'draft' => 'boolean', + 'draft' => 'boolean', 'template' => 'boolean', ]; @@ -145,6 +153,26 @@ public function forJsonDisplay(): self return $refreshed; } + + public function descriptionInfo(): EntityHtmlDescription + { + return new EntityHtmlDescription($this); + } + + public function cover(): BelongsTo + { + return $this->belongsTo(Image::class, 'image_id'); + } + + public function coverInfo(): EntityCover + { + return new EntityCover($this); + } + + public function coverImageTypeKey(): string + { + return 'cover_page'; + } /** * @return HasOne */ diff --git a/app/Entities/Queries/PageQueries.php b/app/Entities/Queries/PageQueries.php index f4ecee2dc08..7acc1b4e668 100644 --- a/app/Entities/Queries/PageQueries.php +++ b/app/Entities/Queries/PageQueries.php @@ -12,13 +12,18 @@ class PageQueries implements ProvidesEntityQueries { protected static array $contentAttributes = [ - 'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', - 'template', 'html', 'markdown', 'text', 'created_at', 'updated_at', 'priority', - 'created_by', 'updated_by', 'owned_by', + 'entities.name as name', 'entities.id as id', 'entities.slug as slug', 'entities.book_id as book_id', + 'entities.chapter_id as chapter_id', 'entity_page_data.draft as draft', + 'entity_page_data.template as template', 'entity_page_data.html as html', 'entity_page_data.markdown as markdown', + 'entity_page_data.text as text', 'entities.created_at as created_at', 'entities.updated_at as updated_at', + 'entities.priority as priority', 'entities.created_by as created_by', 'entities.updated_by as updated_by', + 'entities.owned_by as owned_by', ]; protected static array $listAttributes = [ - 'name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', - 'template', 'text', 'created_at', 'updated_at', 'priority', 'owned_by', + 'entities.name as name', 'entities.id as id', 'entities.slug as slug', 'entities.book_id as book_id', + 'entities.chapter_id as chapter_id', 'entity_page_data.draft as draft', + 'entity_page_data.template as template', 'entity_page_data.text as text', 'entities.created_at as created_at', + 'entities.updated_at as updated_at', 'entities.priority as priority', 'entities.owned_by as owned_by', ]; /** @@ -79,7 +84,12 @@ public function visibleForList(): Builder { return $this->start() ->scopes('visible') - ->select($this->mergeBookSlugForSelect(static::$listAttributes)); + ->select(array_merge( + $this->mergeBookSlugForSelect(static::$listAttributes), + [ + 'entity_page_data.image_id', + ] + )); } /** @@ -92,30 +102,35 @@ public function visibleForContent(): Builder public function visibleForChapterList(int $chapterId): Builder { - return $this->visibleForList() - ->where('chapter_id', '=', $chapterId) - ->orderBy('draft', 'desc') - ->orderBy('priority', 'asc'); + return $this->visibleForListWithCover() + ->where('entities.chapter_id', '=', $chapterId) + ->orderBy('entity_page_data.draft', 'desc') + ->orderBy('entities.priority', 'asc'); } public function visibleWithContents(): Builder { return $this->start() ->scopes('visible') - ->select($this->mergeBookSlugForSelect(static::$contentAttributes)); + ->select(array_merge( + $this->mergeBookSlugForSelect(static::$contentAttributes), + [ + 'entity_page_data.image_id', + ] + )); } public function currentUserDraftsForList(): Builder { return $this->visibleForList() - ->where('draft', '=', true) - ->where('created_by', '=', user()->id); + ->where('entity_page_data.draft', '=', true) + ->where('entities.created_by', '=', user()->id); } public function visibleTemplates(bool $includeContents = false): Builder { $base = $includeContents ? $this->visibleWithContents() : $this->visibleForList(); - return $base->where('template', '=', true); + return $base->where('entity_page_data.template', '=', true); } protected function mergeBookSlugForSelect(array $columns): array @@ -127,4 +142,9 @@ protected function mergeBookSlugForSelect(array $columns): array ->whereColumn('books.id', '=', 'entities.book_id'); }]); } + + public function visibleForListWithCover(): Builder + { + return $this->visibleForList()->with('cover'); + } } diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 375bf1d2bc1..eb826847a0a 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -88,6 +88,10 @@ public function publishDraft(Page $draft, array $input): Page $draft->priority = $this->getNewPriority($draft); $this->updateTemplateStatusAndContentFromInput($draft, $input); + if (array_key_exists('image', $input)) { + $this->baseRepo->updateCoverImage($draft, $input['image'], $input['image'] === null); + } + $draft = $this->baseRepo->update($draft, $input); $draft->rebuildPermissions(); @@ -142,6 +146,10 @@ public function update(Page $page, array $input): Page $this->revisionRepo->storeNewForPage($page, $summary); } + if (array_key_exists('image', $input)) { + $this->baseRepo->updateCoverImage($page, $input['image'], $input['image'] === null); + } + Activity::add(ActivityType::PAGE_UPDATE, $page); $this->baseRepo->sortParent($page); diff --git a/app/Entities/Tools/BookContents.php b/app/Entities/Tools/BookContents.php index 4bbab626520..c71e9e069a2 100644 --- a/app/Entities/Tools/BookContents.php +++ b/app/Entities/Tools/BookContents.php @@ -25,7 +25,7 @@ public function __construct( public function getLastPriority(): int { $maxPage = $this->book->pages() - ->where('draft', '=', false) + ->where('entity_page_data.draft', '=', false) ->whereDoesntHave('chapter') ->max('priority'); @@ -97,7 +97,7 @@ protected function getPages(bool $showDrafts = false, bool $getPageContent = fal } if (!$showDrafts) { - $query->where('draft', '=', false); + $query->where('entity_page_data.draft', '=', false); } return $query->where('book_id', '=', $this->book->id)->get(); diff --git a/app/Entities/Tools/Cloner.php b/app/Entities/Tools/Cloner.php index 64c48c351ae..468eaa1da3c 100644 --- a/app/Entities/Tools/Cloner.php +++ b/app/Entities/Tools/Cloner.php @@ -106,6 +106,7 @@ protected function createBookClone(Book $original, string $newName): Book // Clone book $copyBook = $this->bookRepo->create($bookDetails); + $this->referenceChangeContext->add($original, $copyBook); // Clone contents $directChildren = $original->getDirectVisibleChildren(); @@ -127,8 +128,6 @@ protected function createBookClone(Book $original, string $newName): Book } } - $this->referenceChangeContext->add($original, $copyBook); - return $copyBook; } diff --git a/app/Entities/Tools/EntityCover.php b/app/Entities/Tools/EntityCover.php index 1e8fce201dd..878c673ac74 100644 --- a/app/Entities/Tools/EntityCover.php +++ b/app/Entities/Tools/EntityCover.php @@ -4,6 +4,7 @@ use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; +use BookStack\Entities\Models\Page; use BookStack\Uploads\Image; use Exception; use Illuminate\Database\Eloquent\Builder; @@ -11,7 +12,7 @@ class EntityCover { public function __construct( - protected Book|Bookshelf $entity, + protected Book|Bookshelf|Page $entity, ) { } @@ -33,6 +34,7 @@ public function exists(): bool */ public function getImage(): Image|null { + if ($this->entity->image_id === null) { return null; } diff --git a/app/Entities/Tools/EntityHtmlDescription.php b/app/Entities/Tools/EntityHtmlDescription.php index 052088c04d6..14b7d7ab411 100644 --- a/app/Entities/Tools/EntityHtmlDescription.php +++ b/app/Entities/Tools/EntityHtmlDescription.php @@ -5,6 +5,7 @@ use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Chapter; +use BookStack\Entities\Models\Page; use BookStack\Util\HtmlContentFilter; use BookStack\Util\HtmlContentFilterConfig; @@ -14,7 +15,7 @@ class EntityHtmlDescription protected string $plain = ''; public function __construct( - protected Book|Chapter|Bookshelf $entity, + protected Book|Chapter|Bookshelf|Page $entity, ) { $this->html = $this->entity->description_html ?? ''; $this->plain = $this->entity->description ?? ''; diff --git a/app/Permissions/PermissionApplicator.php b/app/Permissions/PermissionApplicator.php index c44a18a4d53..a2a258902f0 100644 --- a/app/Permissions/PermissionApplicator.php +++ b/app/Permissions/PermissionApplicator.php @@ -117,10 +117,10 @@ public function restrictEntityQuery(Builder $query): Builder public function restrictDraftsOnPageQuery(Builder $query): Builder { return $query->where(function (Builder $query) { - $query->where('draft', '=', false) + $query->where('entity_page_data.draft', '=', false) ->orWhere(function (Builder $query) { - $query->where('draft', '=', true) - ->where('owned_by', '=', $this->currentUser()->id); + $query->where('entity_page_data.draft', '=', true) + ->where('entities.owned_by', '=', $this->currentUser()->id); }); }); } diff --git a/app/References/ReferenceChangeContext.php b/app/References/ReferenceChangeContext.php index 27de0e2d24c..21853eb94b1 100644 --- a/app/References/ReferenceChangeContext.php +++ b/app/References/ReferenceChangeContext.php @@ -12,9 +12,17 @@ class ReferenceChangeContext */ protected array $changes = []; + protected array $urlMap = []; + protected array $permalinkMap = []; + public function add(Entity $oldEntity, Entity $newEntity): void { $this->changes[] = [$oldEntity, $newEntity]; + $this->urlMap[$oldEntity->getUrl()] = $newEntity->getUrl(); + + if (method_exists($oldEntity, 'getPermalink') && method_exists($newEntity, 'getPermalink')) { + $this->permalinkMap[$oldEntity->getPermalink()] = $newEntity->getPermalink(); + } } /** @@ -42,4 +50,14 @@ public function getNewForOld(Entity $oldEntity): ?Entity } return null; } + + public function getUrlMap(): array + { + return $this->urlMap; + } + + public function getPermalinkMap(): array + { + return $this->permalinkMap; + } } diff --git a/app/References/ReferenceUpdater.php b/app/References/ReferenceUpdater.php index 42de72fde04..d19723ef095 100644 --- a/app/References/ReferenceUpdater.php +++ b/app/References/ReferenceUpdater.php @@ -3,9 +3,12 @@ namespace BookStack\References; use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Bookshelf; +use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\HasDescriptionInterface; use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; +use Illuminate\Support\Facades\DB; use BookStack\Entities\Repos\RevisionRepo; use BookStack\Util\HtmlDocument; @@ -67,6 +70,17 @@ public function changeReferencesUsingContext(ReferenceChangeContext $context): v $reference->to_type = $newToEntity->getMorphClass(); $reference->save(); } + + // Handle embedded HTML links within content fields + foreach ($context->getUrlMap() as $oldUrl => $newUrl) { + if ($new instanceof Page) { + $this->updateReferencesWithinPage($new, $oldUrl, $newUrl); + } + // Only for Chapter, Book, or Bookshelf - entities with descriptions + if (($new instanceof Chapter) || ($new instanceof Book) || ($new instanceof Bookshelf)) { + $this->updateReferencesWithinDescription($new, $oldUrl, $newUrl); + } + } } } @@ -104,7 +118,7 @@ protected function updateReferencesWithinEntity(Entity $entity, string $oldLink, $this->updateReferencesWithinPage($entity, $oldLink, $newLink); } - if ($entity instanceof HasDescriptionInterface) { + if (($entity instanceof Chapter) || ($entity instanceof Book) || ($entity instanceof Bookshelf)) { $this->updateReferencesWithinDescription($entity, $oldLink, $newLink); } } @@ -112,9 +126,35 @@ protected function updateReferencesWithinEntity(Entity $entity, string $oldLink, protected function updateReferencesWithinDescription(Entity&HasDescriptionInterface $entity, string $oldLink, string $newLink): void { $description = $entity->descriptionInfo(); - $html = $this->updateLinksInHtml($description->getHtml(true) ?: '', $oldLink, $newLink); + $originalHtml = $description->getHtml(true) ?: ''; + $html = $this->updateLinksInHtml($originalHtml, $oldLink, $newLink); $description->set($html); - $entity->save(); + + $plainText = $description->getPlain(); + $entity->description_html = $html; + $entity->description = $plainText; + + $existing = DB::table('entity_container_data') + ->where('entity_id', $entity->id) + ->where('entity_type', $entity->getMorphClass()) + ->first(); + + if ($existing) { + DB::table('entity_container_data') + ->where('entity_id', $entity->id) + ->where('entity_type', $entity->getMorphClass()) + ->update([ + 'description_html' => $html, + 'description' => $plainText, + ]); + } else { + DB::table('entity_container_data')->insert([ + 'entity_id' => $entity->id, + 'entity_type' => $entity->getMorphClass(), + 'description_html' => $html, + 'description' => $plainText, + ]); + } } protected function updateReferencesWithinPage(Page $page, string $oldLink, string $newLink): void @@ -159,10 +199,15 @@ protected function updateLinksInHtml(string $html, string $oldLink, string $newL /** @var \DOMElement $anchor */ foreach ($anchors as $anchor) { $link = $anchor->getAttribute('href'); - $updated = str_ireplace($oldLink, $newLink, $link); - $anchor->setAttribute('href', $updated); + $isExactMatch = strcasecmp($link, $oldLink) === 0; + $isPrefixMatch = strcasecmp(substr($link, 0, strlen($oldLink)), $oldLink) === 0 && strlen($link) > strlen($oldLink) && $link[strlen($oldLink)] === '/'; + if (!$isExactMatch && !$isPrefixMatch) { + continue; + } + $anchor->setAttribute('href', $newLink . ($isPrefixMatch ? substr($link, strlen($oldLink)) : '')); } - return $doc->getBodyInnerHtml(); + $result = $doc->getBodyInnerHtml(); + return $result; } } diff --git a/app/Search/SearchController.php b/app/Search/SearchController.php index 50a73910afe..35521677e42 100644 --- a/app/Search/SearchController.php +++ b/app/Search/SearchController.php @@ -101,7 +101,7 @@ public function templatesForSelector(Request $request) $entities = $this->searchRunner->searchEntities($searchOptions, 'page', 1, 20)['results']; } else { $entities = $this->pageQueries->visibleTemplates() - ->where('draft', '=', false) + ->where('entity_page_data.draft', '=', false) ->orderBy('updated_at', 'desc') ->take(20) ->get(); diff --git a/app/Settings/SettingService.php b/app/Settings/SettingService.php index e0b13618012..5b29ea8d1b1 100644 --- a/app/Settings/SettingService.php +++ b/app/Settings/SettingService.php @@ -291,4 +291,9 @@ public function flushCache(): void { $this->localCache = []; } + + public function getDefaultPageCoverImage() + { + return config('setting-defaults.default_page_cover_image'); + } } diff --git a/app/Users/Controllers/UserPreferencesController.php b/app/Users/Controllers/UserPreferencesController.php index f4a56b7bf0e..a7c77e1ddd0 100644 --- a/app/Users/Controllers/UserPreferencesController.php +++ b/app/Users/Controllers/UserPreferencesController.php @@ -18,7 +18,7 @@ public function __construct( */ public function changeView(Request $request, string $type) { - $valueViewTypes = ['books', 'bookshelves', 'bookshelf']; + $valueViewTypes = ['books', 'bookshelves', 'bookshelf','pages']; if (!in_array($type, $valueViewTypes)) { return $this->redirectToRequest($request); } diff --git a/app/Users/Queries/UserRecentlyCreatedContent.php b/app/Users/Queries/UserRecentlyCreatedContent.php index 23850e07201..55d0ce57ccb 100644 --- a/app/Users/Queries/UserRecentlyCreatedContent.php +++ b/app/Users/Queries/UserRecentlyCreatedContent.php @@ -30,7 +30,7 @@ public function run(User $user, int $count): array }; return [ - 'pages' => $query($this->queries->pages->visibleForList()->where('draft', '=', false)), + 'pages' => $query($this->queries->pages->visibleForList()->where('entity_page_data.draft', '=', false)), 'chapters' => $query($this->queries->chapters->visibleForList()), 'books' => $query($this->queries->books->visibleForList()), 'shelves' => $query($this->queries->shelves->visibleForList()), diff --git a/database/migrations/2024_10_24_074404_add_image_id_in_page_table.php b/database/migrations/2024_10_24_074404_add_image_id_in_page_table.php new file mode 100755 index 00000000000..8b252034ead --- /dev/null +++ b/database/migrations/2024_10_24_074404_add_image_id_in_page_table.php @@ -0,0 +1,28 @@ +integer('image_id')->after('priority')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('page', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2026_04_11_220254_add_image_id_to_entity_page_data.php b/database/migrations/2026_04_11_220254_add_image_id_to_entity_page_data.php new file mode 100755 index 00000000000..806f89ceed4 --- /dev/null +++ b/database/migrations/2026_04_11_220254_add_image_id_to_entity_page_data.php @@ -0,0 +1,30 @@ +unsignedInteger('image_id')->nullable(); + $table->foreign('image_id')->references('id')->on('images')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('entity_page_data', function (Blueprint $table) { + $table->dropForeign(['image_id']); + $table->dropColumn('image_id'); + }); + } +}; diff --git a/resources/sass/_colors.scss b/resources/sass/_colors.scss index bf7a7a0fc03..917a95e9ff1 100644 --- a/resources/sass/_colors.scss +++ b/resources/sass/_colors.scss @@ -105,3 +105,6 @@ .bg-bookshelf { background-color: var(--color-bookshelf); } +.bg-page { + background-color: var(--color-page); +} diff --git a/resources/views/chapters/parts/show-sidebar-section-actions.blade.php b/resources/views/chapters/parts/show-sidebar-section-actions.blade.php index 55df999a22c..06d52e113fe 100644 --- a/resources/views/chapters/parts/show-sidebar-section-actions.blade.php +++ b/resources/views/chapters/parts/show-sidebar-section-actions.blade.php @@ -2,6 +2,7 @@
{{ trans('common.actions') }}