mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-09-09 06:29:32 +03:00
Imports: Fixed drawing IDs not being updated in content
Would leave imported content with inaccessible images in many cases (or wrong references) although the drawing was still being uploaded & related to the page. Added test to cover. For #5761
This commit is contained in:
@@ -29,7 +29,10 @@ class ZipImportReferences
|
||||
/** @var Image[] */
|
||||
protected array $images = [];
|
||||
|
||||
/** @var array<string, Model> */
|
||||
/**
|
||||
* Mapping keyed by "type:old-reference-id" with values being the new imported equivalent model.
|
||||
* @var array<string, Model>
|
||||
*/
|
||||
protected array $referenceMap = [];
|
||||
|
||||
/** @var array<int, ZipExportPage> */
|
||||
@@ -108,6 +111,22 @@ class ZipImportReferences
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function replaceDrawingIdReferences(string $content): string
|
||||
{
|
||||
$referenceRegex = '/\sdrawio-diagram=[\'"](\d+)[\'"]/';
|
||||
|
||||
$result = preg_replace_callback($referenceRegex, function ($matches) {
|
||||
$key = 'image:' . $matches[1];
|
||||
$model = $this->referenceMap[$key] ?? null;
|
||||
if ($model instanceof Image && $model->type === 'drawio') {
|
||||
return ' drawio-diagram="' . $model->id . '"';
|
||||
}
|
||||
return $matches[0];
|
||||
}, $content);
|
||||
|
||||
return $result ?: $content;
|
||||
}
|
||||
|
||||
public function replaceReferences(): void
|
||||
{
|
||||
foreach ($this->books as $book) {
|
||||
@@ -134,7 +153,9 @@ class ZipImportReferences
|
||||
$exportPage = $this->zipExportPageMap[$page->id];
|
||||
$contentType = $exportPage->markdown ? 'markdown' : 'html';
|
||||
$content = $exportPage->markdown ?: ($exportPage->html ?: '');
|
||||
|
||||
$parsed = $this->parser->parseReferences($content, $this->handleReference(...));
|
||||
$parsed = $this->replaceDrawingIdReferences($parsed);
|
||||
|
||||
$this->pageRepo->setContentFromInput($page, [
|
||||
$contentType => $parsed,
|
||||
|
@@ -393,4 +393,42 @@ class ZipImportRunnerTest extends TestCase
|
||||
|
||||
ZipTestHelper::deleteZipForImport($import);
|
||||
}
|
||||
|
||||
public function test_drawing_references_are_updated_within_content()
|
||||
{
|
||||
$testImagePath = $this->files->testFilePath('test-image.png');
|
||||
$parent = $this->entities->chapter();
|
||||
|
||||
$import = ZipTestHelper::importFromData([], [
|
||||
'page' => [
|
||||
'name' => 'Page A',
|
||||
'html' => '<div drawio-diagram="1125"><img src="[[bsexport:image:1125]]"></div>',
|
||||
'images' => [
|
||||
[
|
||||
'id' => 1125,
|
||||
'name' => 'Cat',
|
||||
'type' => 'drawio',
|
||||
'file' => 'my_drawing'
|
||||
]
|
||||
],
|
||||
],
|
||||
], [
|
||||
'my_drawing' => $testImagePath,
|
||||
]);
|
||||
|
||||
$this->asAdmin();
|
||||
/** @var Page $page */
|
||||
$page = $this->runner->run($import, $parent);
|
||||
|
||||
$pageImages = Image::where('uploaded_to', '=', $page->id)->whereIn('type', ['gallery', 'drawio'])->get();
|
||||
$this->assertCount(1, $pageImages);
|
||||
$this->assertEquals('drawio', $pageImages[0]->type);
|
||||
|
||||
$drawingId = $pageImages[0]->id;
|
||||
$this->assertStringContainsString("drawio-diagram=\"{$drawingId}\"", $page->html);
|
||||
$this->assertStringNotContainsString('[[bsexport:image:1125]]', $page->html);
|
||||
$this->assertStringNotContainsString('drawio-diagram="1125"', $page->html);
|
||||
|
||||
ZipTestHelper::deleteZipForImport($import);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user