BookStack/app/Entities/Models/Book.php
Dan Brown c622b785a9
Input WYSIWYG: Added description_html field, added store logic
Rolled out HTML editor field and store logic across all target entity
types. Cleaned up WYSIWYG input logic and design.
Cleaned up some injected classes while there.
2023-12-17 15:02:15 +00:00

137 lines
3.8 KiB
PHP

<?php
namespace BookStack\Entities\Models;
use BookStack\Uploads\Image;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
/**
* Class Book.
*
* @property string $description
* @property int $image_id
* @property ?int $default_template_id
* @property Image|null $cover
* @property \Illuminate\Database\Eloquent\Collection $chapters
* @property \Illuminate\Database\Eloquent\Collection $pages
* @property \Illuminate\Database\Eloquent\Collection $directPages
* @property \Illuminate\Database\Eloquent\Collection $shelves
* @property ?Page $defaultTemplate
*/
class Book extends Entity implements HasCoverImage
{
use HasFactory;
use HasHtmlDescription;
public $searchFactor = 1.2;
protected $fillable = ['name'];
protected $hidden = ['pivot', 'image_id', 'deleted_at'];
/**
* Get the url for this book.
*/
public function getUrl(string $path = ''): string
{
return url('/books/' . implode('/', [urlencode($this->slug), trim($path, '/')]));
}
/**
* Returns book cover image, if book cover not exists return default cover image.
*/
public function getBookCover(int $width = 440, int $height = 250): string
{
$default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
if (!$this->image_id || !$this->cover) {
return $default;
}
try {
return $this->cover->getThumb($width, $height, false) ?? $default;
} catch (Exception $err) {
return $default;
}
}
/**
* Get the cover image of the book.
*/
public function cover(): BelongsTo
{
return $this->belongsTo(Image::class, 'image_id');
}
/**
* Get the type of the image model that is used when storing a cover image.
*/
public function coverImageTypeKey(): string
{
return 'cover_book';
}
/**
* Get the Page that is used as default template for newly created pages within this Book.
*/
public function defaultTemplate(): BelongsTo
{
return $this->belongsTo(Page::class, 'default_template_id');
}
/**
* Get all pages within this book.
*/
public function pages(): HasMany
{
return $this->hasMany(Page::class);
}
/**
* Get the direct child pages of this book.
*/
public function directPages(): HasMany
{
return $this->pages()->where('chapter_id', '=', '0');
}
/**
* Get all chapters within this book.
*/
public function chapters(): HasMany
{
return $this->hasMany(Chapter::class);
}
/**
* Get the shelves this book is contained within.
*/
public function shelves(): BelongsToMany
{
return $this->belongsToMany(Bookshelf::class, 'bookshelves_books', 'book_id', 'bookshelf_id');
}
/**
* Get the direct child items within this book.
*/
public function getDirectChildren(): Collection
{
$pages = $this->directPages()->scopes('visible')->get();
$chapters = $this->chapters()->scopes('visible')->get();
return $pages->concat($chapters)->sortBy('priority')->sortByDesc('draft');
}
/**
* Get a visible book by its slug.
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public static function getBySlug(string $slug): self
{
return static::visible()->where('slug', '=', $slug)->firstOrFail();
}
}