Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/App/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions app/Config/setting-defaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' => [
Expand All @@ -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,
],

Expand Down
3 changes: 3 additions & 0 deletions app/Entities/Controllers/ChapterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -105,6 +107,7 @@ public function show(string $bookSlug, string $chapterSlug)
'next' => $nextPreviousLocator->getNext(),
'previous' => $nextPreviousLocator->getPrevious(),
'referenceCount' => $this->referenceFetcher->getReferenceCountToEntity($chapter),
'view' => $view,
]);
}

Expand Down
6 changes: 6 additions & 0 deletions app/Entities/Controllers/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 2 additions & 0 deletions app/Entities/Models/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
9 changes: 9 additions & 0 deletions app/Entities/Models/EntityContainerData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions app/Entities/Models/EntityPageData.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ class EntityPageData extends Model
'html',
'text',
'markdown',
'image_id'
];
}
36 changes: 32 additions & 4 deletions app/Entities/Models/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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',
];

Expand Down Expand Up @@ -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<EntityPageData, $this>
*/
Expand Down
48 changes: 34 additions & 14 deletions app/Entities/Queries/PageQueries.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
];

/**
Expand Down Expand Up @@ -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',
]
));
}

/**
Expand All @@ -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
Expand All @@ -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');
}
}
8 changes: 8 additions & 0 deletions app/Entities/Repos/PageRepo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions app/Entities/Tools/BookContents.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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();
Expand Down
3 changes: 1 addition & 2 deletions app/Entities/Tools/Cloner.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -127,8 +128,6 @@ protected function createBookClone(Book $original, string $newName): Book
}
}

$this->referenceChangeContext->add($original, $copyBook);

return $copyBook;
}

Expand Down
4 changes: 3 additions & 1 deletion app/Entities/Tools/EntityCover.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

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;

class EntityCover
{
public function __construct(
protected Book|Bookshelf $entity,
protected Book|Bookshelf|Page $entity,
) {
}

Expand All @@ -33,6 +34,7 @@ public function exists(): bool
*/
public function getImage(): Image|null
{

if ($this->entity->image_id === null) {
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion app/Entities/Tools/EntityHtmlDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 ?? '';
Expand Down
6 changes: 3 additions & 3 deletions app/Permissions/PermissionApplicator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
}
Expand Down
Loading