mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-29 23:22:34 +01:00
ZIP Exports: Added core logic for books/chapters
This commit is contained in:
parent
f732ef05d5
commit
42ada66fdd
@ -60,6 +60,7 @@ class Chapter extends BookChild
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the visible pages in this chapter.
|
* Get the visible pages in this chapter.
|
||||||
|
* @returns Collection<Page>
|
||||||
*/
|
*/
|
||||||
public function getVisiblePages(): Collection
|
public function getVisiblePages(): Collection
|
||||||
{
|
{
|
||||||
|
53
app/Exports/ZipExports/Models/ZipExportBook.php
Normal file
53
app/Exports/ZipExports/Models/ZipExportBook.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Exports\ZipExports\Models;
|
||||||
|
|
||||||
|
use BookStack\Entities\Models\Book;
|
||||||
|
use BookStack\Entities\Models\Chapter;
|
||||||
|
use BookStack\Entities\Models\Page;
|
||||||
|
use BookStack\Exports\ZipExports\ZipExportFiles;
|
||||||
|
|
||||||
|
class ZipExportBook extends ZipExportModel
|
||||||
|
{
|
||||||
|
public ?int $id = null;
|
||||||
|
public string $name;
|
||||||
|
public ?string $description_html = null;
|
||||||
|
public ?string $cover = null;
|
||||||
|
/** @var ZipExportChapter[] */
|
||||||
|
public array $chapters = [];
|
||||||
|
/** @var ZipExportPage[] */
|
||||||
|
public array $pages = [];
|
||||||
|
/** @var ZipExportTag[] */
|
||||||
|
public array $tags = [];
|
||||||
|
|
||||||
|
public static function fromModel(Book $model, ZipExportFiles $files): self
|
||||||
|
{
|
||||||
|
$instance = new self();
|
||||||
|
$instance->id = $model->id;
|
||||||
|
$instance->name = $model->name;
|
||||||
|
$instance->description_html = $model->descriptionHtml();
|
||||||
|
|
||||||
|
if ($model->cover) {
|
||||||
|
$instance->cover = $files->referenceForImage($model->cover);
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance->tags = ZipExportTag::fromModelArray($model->tags()->get()->all());
|
||||||
|
|
||||||
|
$chapters = [];
|
||||||
|
$pages = [];
|
||||||
|
|
||||||
|
$children = $model->getDirectVisibleChildren()->all();
|
||||||
|
foreach ($children as $child) {
|
||||||
|
if ($child instanceof Chapter) {
|
||||||
|
$chapters[] = $child;
|
||||||
|
} else if ($child instanceof Page) {
|
||||||
|
$pages[] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance->pages = ZipExportPage::fromModelArray($pages, $files);
|
||||||
|
$instance->chapters = ZipExportChapter::fromModelArray($chapters, $files);
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
}
|
45
app/Exports/ZipExports/Models/ZipExportChapter.php
Normal file
45
app/Exports/ZipExports/Models/ZipExportChapter.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Exports\ZipExports\Models;
|
||||||
|
|
||||||
|
use BookStack\Entities\Models\Chapter;
|
||||||
|
use BookStack\Entities\Models\Page;
|
||||||
|
use BookStack\Exports\ZipExports\ZipExportFiles;
|
||||||
|
|
||||||
|
class ZipExportChapter extends ZipExportModel
|
||||||
|
{
|
||||||
|
public ?int $id = null;
|
||||||
|
public string $name;
|
||||||
|
public ?string $description_html = null;
|
||||||
|
public ?int $priority = null;
|
||||||
|
/** @var ZipExportPage[] */
|
||||||
|
public array $pages = [];
|
||||||
|
/** @var ZipExportTag[] */
|
||||||
|
public array $tags = [];
|
||||||
|
|
||||||
|
public static function fromModel(Chapter $model, ZipExportFiles $files): self
|
||||||
|
{
|
||||||
|
$instance = new self();
|
||||||
|
$instance->id = $model->id;
|
||||||
|
$instance->name = $model->name;
|
||||||
|
$instance->description_html = $model->descriptionHtml();
|
||||||
|
$instance->priority = $model->priority;
|
||||||
|
$instance->tags = ZipExportTag::fromModelArray($model->tags()->get()->all());
|
||||||
|
|
||||||
|
$pages = $model->getVisiblePages()->filter(fn (Page $page) => !$page->draft)->all();
|
||||||
|
$instance->pages = ZipExportPage::fromModelArray($pages, $files);
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Chapter[] $chapterArray
|
||||||
|
* @return self[]
|
||||||
|
*/
|
||||||
|
public static function fromModelArray(array $chapterArray, ZipExportFiles $files): array
|
||||||
|
{
|
||||||
|
return array_values(array_map(function (Chapter $chapter) use ($files) {
|
||||||
|
return self::fromModel($chapter, $files);
|
||||||
|
}, $chapterArray));
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ class ZipExportPage extends ZipExportModel
|
|||||||
$instance->id = $model->id;
|
$instance->id = $model->id;
|
||||||
$instance->name = $model->name;
|
$instance->name = $model->name;
|
||||||
$instance->html = (new PageContent($model))->render();
|
$instance->html = (new PageContent($model))->render();
|
||||||
|
$instance->priority = $model->priority;
|
||||||
|
|
||||||
if (!empty($model->markdown)) {
|
if (!empty($model->markdown)) {
|
||||||
$instance->markdown = $model->markdown;
|
$instance->markdown = $model->markdown;
|
||||||
@ -36,4 +37,15 @@ class ZipExportPage extends ZipExportModel
|
|||||||
|
|
||||||
return $instance;
|
return $instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Page[] $pageArray
|
||||||
|
* @return self[]
|
||||||
|
*/
|
||||||
|
public static function fromModelArray(array $pageArray, ZipExportFiles $files): array
|
||||||
|
{
|
||||||
|
return array_values(array_map(function (Page $page) use ($files) {
|
||||||
|
return self::fromModel($page, $files);
|
||||||
|
}, $pageArray));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
namespace BookStack\Exports\ZipExports;
|
namespace BookStack\Exports\ZipExports;
|
||||||
|
|
||||||
|
use BookStack\Entities\Models\Book;
|
||||||
|
use BookStack\Entities\Models\Chapter;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use BookStack\Exceptions\ZipExportException;
|
use BookStack\Exceptions\ZipExportException;
|
||||||
|
use BookStack\Exports\ZipExports\Models\ZipExportBook;
|
||||||
|
use BookStack\Exports\ZipExports\Models\ZipExportChapter;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
||||||
use ZipArchive;
|
use ZipArchive;
|
||||||
|
|
||||||
@ -30,6 +34,32 @@ class ZipExportBuilder
|
|||||||
return $this->build();
|
return $this->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ZipExportException
|
||||||
|
*/
|
||||||
|
public function buildForChapter(Chapter $chapter): string
|
||||||
|
{
|
||||||
|
$exportChapter = ZipExportChapter::fromModel($chapter, $this->files);
|
||||||
|
$this->data['chapter'] = $exportChapter;
|
||||||
|
|
||||||
|
$this->references->addChapter($exportChapter);
|
||||||
|
|
||||||
|
return $this->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ZipExportException
|
||||||
|
*/
|
||||||
|
public function buildForBook(Book $book): string
|
||||||
|
{
|
||||||
|
$exportBook = ZipExportBook::fromModel($book, $this->files);
|
||||||
|
$this->data['book'] = $exportBook;
|
||||||
|
|
||||||
|
$this->references->addBook($exportBook);
|
||||||
|
|
||||||
|
return $this->build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws ZipExportException
|
* @throws ZipExportException
|
||||||
*/
|
*/
|
||||||
|
@ -4,6 +4,8 @@ namespace BookStack\Exports\ZipExports;
|
|||||||
|
|
||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportAttachment;
|
use BookStack\Exports\ZipExports\Models\ZipExportAttachment;
|
||||||
|
use BookStack\Exports\ZipExports\Models\ZipExportBook;
|
||||||
|
use BookStack\Exports\ZipExports\Models\ZipExportChapter;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportModel;
|
use BookStack\Exports\ZipExports\Models\ZipExportModel;
|
||||||
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
||||||
@ -14,8 +16,10 @@ class ZipExportReferences
|
|||||||
{
|
{
|
||||||
/** @var ZipExportPage[] */
|
/** @var ZipExportPage[] */
|
||||||
protected array $pages = [];
|
protected array $pages = [];
|
||||||
protected array $books = [];
|
/** @var ZipExportChapter[] */
|
||||||
protected array $chapters = [];
|
protected array $chapters = [];
|
||||||
|
/** @var ZipExportBook[] */
|
||||||
|
protected array $books = [];
|
||||||
|
|
||||||
/** @var ZipExportAttachment[] */
|
/** @var ZipExportAttachment[] */
|
||||||
protected array $attachments = [];
|
protected array $attachments = [];
|
||||||
@ -41,23 +45,64 @@ class ZipExportReferences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addChapter(ZipExportChapter $chapter): void
|
||||||
|
{
|
||||||
|
if ($chapter->id) {
|
||||||
|
$this->chapters[$chapter->id] = $chapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($chapter->pages as $page) {
|
||||||
|
$this->addPage($page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addBook(ZipExportBook $book): void
|
||||||
|
{
|
||||||
|
if ($book->id) {
|
||||||
|
$this->chapters[$book->id] = $book;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($book->pages as $page) {
|
||||||
|
$this->addPage($page);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($book->chapters as $chapter) {
|
||||||
|
$this->addChapter($chapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function buildReferences(ZipExportFiles $files): void
|
public function buildReferences(ZipExportFiles $files): void
|
||||||
{
|
{
|
||||||
|
$createHandler = function (ZipExportModel $zipModel) use ($files) {
|
||||||
|
return function (Model $model) use ($files, $zipModel) {
|
||||||
|
return $this->handleModelReference($model, $zipModel, $files);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// Parse page content first
|
// Parse page content first
|
||||||
foreach ($this->pages as $page) {
|
foreach ($this->pages as $page) {
|
||||||
$handler = function (Model $model) use ($files, $page) {
|
$handler = $createHandler($page);
|
||||||
return $this->handleModelReference($model, $page, $files);
|
|
||||||
};
|
|
||||||
|
|
||||||
$page->html = $this->parser->parse($page->html ?? '', $handler);
|
$page->html = $this->parser->parse($page->html ?? '', $handler);
|
||||||
if ($page->markdown) {
|
if ($page->markdown) {
|
||||||
$page->markdown = $this->parser->parse($page->markdown, $handler);
|
$page->markdown = $this->parser->parse($page->markdown, $handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dd('end');
|
// Parse chapter description HTML
|
||||||
// TODO - Parse chapter desc html
|
foreach ($this->chapters as $chapter) {
|
||||||
// TODO - Parse book desc html
|
if ($chapter->description_html) {
|
||||||
|
$handler = $createHandler($chapter);
|
||||||
|
$chapter->description_html = $this->parser->parse($chapter->description_html, $handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse book description HTML
|
||||||
|
foreach ($this->books as $book) {
|
||||||
|
if ($book->description_html) {
|
||||||
|
$handler = $createHandler($book);
|
||||||
|
$book->description_html = $this->parser->parse($book->description_html, $handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleModelReference(Model $model, ZipExportModel $exportModel, ZipExportFiles $files): ?string
|
protected function handleModelReference(Model $model, ZipExportModel $exportModel, ZipExportFiles $files): ?string
|
||||||
|
@ -87,7 +87,7 @@ The `id_ciphertext` is the ciphertext of encrypting the text `bookstack`. This i
|
|||||||
- `id` - Number, optional, original ID for the book from exported system.
|
- `id` - Number, optional, original ID for the book from exported system.
|
||||||
- `name` - String, required, name/title of the book.
|
- `name` - String, required, name/title of the book.
|
||||||
- `description_html` - String, optional, HTML description content.
|
- `description_html` - String, optional, HTML description content.
|
||||||
- `cover` - String reference, options, reference to book cover image.
|
- `cover` - String reference, optional, reference to book cover image.
|
||||||
- `chapters` - [Chapter](#chapter) array, optional, chapters within this book.
|
- `chapters` - [Chapter](#chapter) array, optional, chapters within this book.
|
||||||
- `pages` - [Page](#page) array, optional, direct child pages for this book.
|
- `pages` - [Page](#page) array, optional, direct child pages for this book.
|
||||||
- `tags` - [Tag](#tag) array, optional, tags assigned to this book.
|
- `tags` - [Tag](#tag) array, optional, tags assigned to this book.
|
||||||
|
Loading…
Reference in New Issue
Block a user