2024-10-21 02:56:56 +08:00
|
|
|
<?php
|
|
|
|
|
2024-10-23 17:48:26 +08:00
|
|
|
namespace BookStack\Exports\ZipExports;
|
2024-10-21 02:56:56 +08:00
|
|
|
|
|
|
|
use BookStack\App\Model;
|
2024-10-23 22:59:58 +08:00
|
|
|
use BookStack\Entities\Models\Book;
|
|
|
|
use BookStack\Entities\Models\Chapter;
|
|
|
|
use BookStack\Entities\Models\Page;
|
2024-10-23 17:48:26 +08:00
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportAttachment;
|
2024-10-23 18:30:32 +08:00
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportBook;
|
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportChapter;
|
2024-10-23 17:48:26 +08:00
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportImage;
|
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportModel;
|
|
|
|
use BookStack\Exports\ZipExports\Models\ZipExportPage;
|
2024-10-21 20:59:15 +08:00
|
|
|
use BookStack\Uploads\Attachment;
|
|
|
|
use BookStack\Uploads\Image;
|
2024-10-21 02:56:56 +08:00
|
|
|
|
|
|
|
class ZipExportReferences
|
|
|
|
{
|
|
|
|
/** @var ZipExportPage[] */
|
|
|
|
protected array $pages = [];
|
2024-10-23 18:30:32 +08:00
|
|
|
/** @var ZipExportChapter[] */
|
2024-10-21 02:56:56 +08:00
|
|
|
protected array $chapters = [];
|
2024-10-23 18:30:32 +08:00
|
|
|
/** @var ZipExportBook[] */
|
|
|
|
protected array $books = [];
|
2024-10-21 02:56:56 +08:00
|
|
|
|
|
|
|
/** @var ZipExportAttachment[] */
|
|
|
|
protected array $attachments = [];
|
|
|
|
|
2024-10-21 20:59:15 +08:00
|
|
|
/** @var ZipExportImage[] */
|
|
|
|
protected array $images = [];
|
|
|
|
|
2024-10-21 02:56:56 +08:00
|
|
|
public function __construct(
|
|
|
|
protected ZipReferenceParser $parser,
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public function addPage(ZipExportPage $page): void
|
|
|
|
{
|
|
|
|
if ($page->id) {
|
|
|
|
$this->pages[$page->id] = $page;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($page->attachments as $attachment) {
|
|
|
|
if ($attachment->id) {
|
|
|
|
$this->attachments[$attachment->id] = $attachment;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-23 18:30:32 +08:00
|
|
|
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) {
|
2024-10-27 22:33:43 +08:00
|
|
|
$this->books[$book->id] = $book;
|
2024-10-23 18:30:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($book->pages as $page) {
|
|
|
|
$this->addPage($page);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($book->chapters as $chapter) {
|
|
|
|
$this->addChapter($chapter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-21 20:59:15 +08:00
|
|
|
public function buildReferences(ZipExportFiles $files): void
|
2024-10-21 02:56:56 +08:00
|
|
|
{
|
2024-10-23 18:30:32 +08:00
|
|
|
$createHandler = function (ZipExportModel $zipModel) use ($files) {
|
|
|
|
return function (Model $model) use ($files, $zipModel) {
|
|
|
|
return $this->handleModelReference($model, $zipModel, $files);
|
2024-10-23 17:48:26 +08:00
|
|
|
};
|
2024-10-23 18:30:32 +08:00
|
|
|
};
|
2024-10-23 17:48:26 +08:00
|
|
|
|
2024-10-23 18:30:32 +08:00
|
|
|
// Parse page content first
|
|
|
|
foreach ($this->pages as $page) {
|
|
|
|
$handler = $createHandler($page);
|
2024-11-11 00:03:50 +08:00
|
|
|
$page->html = $this->parser->parseLinks($page->html ?? '', $handler);
|
2024-10-23 17:48:26 +08:00
|
|
|
if ($page->markdown) {
|
2024-11-11 00:03:50 +08:00
|
|
|
$page->markdown = $this->parser->parseLinks($page->markdown, $handler);
|
2024-10-23 17:48:26 +08:00
|
|
|
}
|
2024-10-21 02:56:56 +08:00
|
|
|
}
|
|
|
|
|
2024-10-23 18:30:32 +08:00
|
|
|
// Parse chapter description HTML
|
|
|
|
foreach ($this->chapters as $chapter) {
|
|
|
|
if ($chapter->description_html) {
|
|
|
|
$handler = $createHandler($chapter);
|
2024-11-11 00:03:50 +08:00
|
|
|
$chapter->description_html = $this->parser->parseLinks($chapter->description_html, $handler);
|
2024-10-23 18:30:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse book description HTML
|
|
|
|
foreach ($this->books as $book) {
|
|
|
|
if ($book->description_html) {
|
|
|
|
$handler = $createHandler($book);
|
2024-11-11 00:03:50 +08:00
|
|
|
$book->description_html = $this->parser->parseLinks($book->description_html, $handler);
|
2024-10-23 18:30:32 +08:00
|
|
|
}
|
|
|
|
}
|
2024-10-21 02:56:56 +08:00
|
|
|
}
|
2024-10-21 20:59:15 +08:00
|
|
|
|
|
|
|
protected function handleModelReference(Model $model, ZipExportModel $exportModel, ZipExportFiles $files): ?string
|
|
|
|
{
|
|
|
|
// Handle attachment references
|
|
|
|
// No permission check needed here since they would only already exist in this
|
|
|
|
// reference context if already allowed via their entity access.
|
|
|
|
if ($model instanceof Attachment) {
|
|
|
|
if (isset($this->attachments[$model->id])) {
|
|
|
|
return "[[bsexport:attachment:{$model->id}]]";
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle image references
|
|
|
|
if ($model instanceof Image) {
|
|
|
|
// Only handle gallery and drawio images
|
|
|
|
if ($model->type !== 'gallery' && $model->type !== 'drawio') {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2024-11-25 23:54:15 +08:00
|
|
|
// Handle simple links outside of page content
|
|
|
|
if (!($exportModel instanceof ZipExportPage) && isset($this->images[$model->id])) {
|
|
|
|
return "[[bsexport:image:{$model->id}]]";
|
2024-10-21 20:59:15 +08:00
|
|
|
}
|
|
|
|
|
2024-11-25 23:54:15 +08:00
|
|
|
// Find and include images if in visibility
|
2024-10-21 20:59:15 +08:00
|
|
|
$page = $model->getPage();
|
|
|
|
if ($page && userCan('view', $page)) {
|
|
|
|
if (!isset($this->images[$model->id])) {
|
|
|
|
$exportImage = ZipExportImage::fromModel($model, $files);
|
|
|
|
$this->images[$model->id] = $exportImage;
|
|
|
|
$exportModel->images[] = $exportImage;
|
|
|
|
}
|
|
|
|
return "[[bsexport:image:{$model->id}]]";
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2024-10-23 22:59:58 +08:00
|
|
|
// Handle entity references
|
|
|
|
if ($model instanceof Book && isset($this->books[$model->id])) {
|
|
|
|
return "[[bsexport:book:{$model->id}]]";
|
|
|
|
} else if ($model instanceof Chapter && isset($this->chapters[$model->id])) {
|
|
|
|
return "[[bsexport:chapter:{$model->id}]]";
|
|
|
|
} else if ($model instanceof Page && isset($this->pages[$model->id])) {
|
|
|
|
return "[[bsexport:page:{$model->id}]]";
|
|
|
|
}
|
|
|
|
|
2024-10-21 20:59:15 +08:00
|
|
|
return null;
|
|
|
|
}
|
2024-10-21 02:56:56 +08:00
|
|
|
}
|