mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-07 01:30:06 +00:00
Zip Exports: Added attachment/image link resolving & JSON null handling
This commit is contained in:
parent
7c39dd5cba
commit
06ffd8ee72
9 changed files with 79 additions and 10 deletions
app
|
@ -5,7 +5,7 @@ namespace BookStack\Exports\ZipExportModels;
|
||||||
use BookStack\Exports\ZipExportFiles;
|
use BookStack\Exports\ZipExportFiles;
|
||||||
use BookStack\Uploads\Attachment;
|
use BookStack\Uploads\Attachment;
|
||||||
|
|
||||||
class ZipExportAttachment implements ZipExportModel
|
class ZipExportAttachment extends ZipExportModel
|
||||||
{
|
{
|
||||||
public ?int $id = null;
|
public ?int $id = null;
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace BookStack\Exports\ZipExportModels;
|
||||||
|
|
||||||
use BookStack\Activity\Models\Tag;
|
use BookStack\Activity\Models\Tag;
|
||||||
|
|
||||||
class ZipExportImage implements ZipExportModel
|
class ZipExportImage extends ZipExportModel
|
||||||
{
|
{
|
||||||
public string $name;
|
public string $name;
|
||||||
public string $file;
|
public string $file;
|
||||||
|
|
|
@ -2,10 +2,19 @@
|
||||||
|
|
||||||
namespace BookStack\Exports\ZipExportModels;
|
namespace BookStack\Exports\ZipExportModels;
|
||||||
|
|
||||||
use BookStack\App\Model;
|
use JsonSerializable;
|
||||||
use BookStack\Exports\ZipExportFiles;
|
|
||||||
|
|
||||||
interface ZipExportModel
|
abstract class ZipExportModel implements JsonSerializable
|
||||||
{
|
{
|
||||||
// public static function fromModel(Model $model, ZipExportFiles $files): self;
|
/**
|
||||||
|
* Handle the serialization to JSON.
|
||||||
|
* For these exports, we filter out optional (represented as nullable) fields
|
||||||
|
* just to clean things up and prevent confusion to avoid null states in the
|
||||||
|
* resulting export format itself.
|
||||||
|
*/
|
||||||
|
public function jsonSerialize(): array
|
||||||
|
{
|
||||||
|
$publicProps = get_object_vars(...)->__invoke($this);
|
||||||
|
return array_filter($publicProps, fn ($value) => $value !== null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use BookStack\Entities\Models\Page;
|
||||||
use BookStack\Entities\Tools\PageContent;
|
use BookStack\Entities\Tools\PageContent;
|
||||||
use BookStack\Exports\ZipExportFiles;
|
use BookStack\Exports\ZipExportFiles;
|
||||||
|
|
||||||
class ZipExportPage implements ZipExportModel
|
class ZipExportPage extends ZipExportModel
|
||||||
{
|
{
|
||||||
public ?int $id = null;
|
public ?int $id = null;
|
||||||
public string $name;
|
public string $name;
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace BookStack\Exports\ZipExportModels;
|
||||||
|
|
||||||
use BookStack\Activity\Models\Tag;
|
use BookStack\Activity\Models\Tag;
|
||||||
|
|
||||||
class ZipExportTag implements ZipExportModel
|
class ZipExportTag extends ZipExportModel
|
||||||
{
|
{
|
||||||
public string $name;
|
public string $name;
|
||||||
public ?string $value = null;
|
public ?string $value = null;
|
||||||
|
|
|
@ -44,11 +44,14 @@ class ZipExportReferences
|
||||||
// TODO - Handle found link to $model
|
// TODO - Handle found link to $model
|
||||||
// - Validate we can see/access $model, or/and that it's
|
// - Validate we can see/access $model, or/and that it's
|
||||||
// part of the export in progress.
|
// part of the export in progress.
|
||||||
|
|
||||||
|
// TODO - Add images after the above to files
|
||||||
return '[CAT]';
|
return '[CAT]';
|
||||||
});
|
});
|
||||||
// TODO - markdown
|
// TODO - markdown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dd('end');
|
||||||
// TODO - Parse chapter desc html
|
// TODO - Parse chapter desc html
|
||||||
// TODO - Parse book desc html
|
// TODO - Parse book desc html
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@ namespace BookStack\Exports;
|
||||||
|
|
||||||
use BookStack\App\Model;
|
use BookStack\App\Model;
|
||||||
use BookStack\Entities\Queries\EntityQueries;
|
use BookStack\Entities\Queries\EntityQueries;
|
||||||
|
use BookStack\References\ModelResolvers\AttachmentModelResolver;
|
||||||
use BookStack\References\ModelResolvers\BookLinkModelResolver;
|
use BookStack\References\ModelResolvers\BookLinkModelResolver;
|
||||||
use BookStack\References\ModelResolvers\ChapterLinkModelResolver;
|
use BookStack\References\ModelResolvers\ChapterLinkModelResolver;
|
||||||
use BookStack\References\ModelResolvers\CrossLinkModelResolver;
|
use BookStack\References\ModelResolvers\CrossLinkModelResolver;
|
||||||
|
use BookStack\References\ModelResolvers\ImageModelResolver;
|
||||||
use BookStack\References\ModelResolvers\PageLinkModelResolver;
|
use BookStack\References\ModelResolvers\PageLinkModelResolver;
|
||||||
use BookStack\References\ModelResolvers\PagePermalinkModelResolver;
|
use BookStack\References\ModelResolvers\PagePermalinkModelResolver;
|
||||||
|
|
||||||
|
@ -24,8 +26,8 @@ class ZipReferenceParser
|
||||||
new PageLinkModelResolver($queries->pages),
|
new PageLinkModelResolver($queries->pages),
|
||||||
new ChapterLinkModelResolver($queries->chapters),
|
new ChapterLinkModelResolver($queries->chapters),
|
||||||
new BookLinkModelResolver($queries->books),
|
new BookLinkModelResolver($queries->books),
|
||||||
// TODO - Image
|
new ImageModelResolver(),
|
||||||
// TODO - Attachment
|
new AttachmentModelResolver(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
app/References/ModelResolvers/AttachmentModelResolver.php
Normal file
22
app/References/ModelResolvers/AttachmentModelResolver.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\References\ModelResolvers;
|
||||||
|
|
||||||
|
use BookStack\Uploads\Attachment;
|
||||||
|
|
||||||
|
class AttachmentModelResolver implements CrossLinkModelResolver
|
||||||
|
{
|
||||||
|
public function resolve(string $link): ?Attachment
|
||||||
|
{
|
||||||
|
$pattern = '/^' . preg_quote(url('/attachments'), '/') . '\/(\d+)/';
|
||||||
|
$matches = [];
|
||||||
|
$match = preg_match($pattern, $link, $matches);
|
||||||
|
if (!$match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = intval($matches[1]);
|
||||||
|
|
||||||
|
return Attachment::query()->find($id);
|
||||||
|
}
|
||||||
|
}
|
33
app/References/ModelResolvers/ImageModelResolver.php
Normal file
33
app/References/ModelResolvers/ImageModelResolver.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\References\ModelResolvers;
|
||||||
|
|
||||||
|
use BookStack\Uploads\Image;
|
||||||
|
|
||||||
|
class ImageModelResolver implements CrossLinkModelResolver
|
||||||
|
{
|
||||||
|
public function resolve(string $link): ?Image
|
||||||
|
{
|
||||||
|
$pattern = '/^' . preg_quote(url('/uploads/images'), '/') . '\/(.+)/';
|
||||||
|
$matches = [];
|
||||||
|
$match = preg_match($pattern, $link, $matches);
|
||||||
|
if (!$match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $matches[1];
|
||||||
|
|
||||||
|
// Strip thumbnail element from path if existing
|
||||||
|
$originalPathSplit = array_filter(explode('/', $path), function (string $part) {
|
||||||
|
$resizedDir = (str_starts_with($part, 'thumbs-') || str_starts_with($part, 'scaled-'));
|
||||||
|
$missingExtension = !str_contains($part, '.');
|
||||||
|
|
||||||
|
return !($resizedDir && $missingExtension);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Build a database-format image path and search for the image entry
|
||||||
|
$fullPath = '/uploads/images/' . ltrim(implode('/', $originalPathSplit), '/');
|
||||||
|
|
||||||
|
return Image::query()->where('path', '=', $fullPath)->first();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue