Skip to content

Commit 4061cc0

Browse files
committed
Add drawingPassThroughEnabled to sheet
1 parent fd3252b commit 4061cc0

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,15 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
14841484
// Store drawing XML for pass-through if enabled
14851485
if ($this->enableDrawingPassThrough) {
14861486
$unparsedDrawings[$drawingRelId] = $xmlDrawing->asXML();
1487+
// Mark that pass-through is enabled for this sheet
1488+
$sheetCodeName = $docSheet->getCodeName();
1489+
if (!isset($unparsedLoadedData['sheets']) || !is_array($unparsedLoadedData['sheets'])) {
1490+
$unparsedLoadedData['sheets'] = [];
1491+
}
1492+
if (!isset($unparsedLoadedData['sheets'][$sheetCodeName]) || !is_array($unparsedLoadedData['sheets'][$sheetCodeName])) {
1493+
$unparsedLoadedData['sheets'][$sheetCodeName] = [];
1494+
}
1495+
$unparsedLoadedData['sheets'][$sheetCodeName]['drawingPassThroughEnabled'] = true;
14871496
}
14881497

14891498
if ($xmlDrawingChildren->oneCellAnchor) {
@@ -1714,6 +1723,11 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
17141723
}
17151724
}
17161725
}
1726+
// Legacy behavior: preserve empty drawings when pass-through is disabled
1727+
if (empty($relsDrawing) && $xmlDrawing->count() == 0) {
1728+
// Save Drawing without rels and children as unparsed
1729+
$unparsedDrawings[$drawingRelId] = $xmlDrawing->asXML();
1730+
}
17171731
}
17181732

17191733
// store original rId of drawing files

src/PhpSpreadsheet/Writer/Xlsx/Drawing.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ private static function writeAttributeIf(XMLWriter $objWriter, ?bool $condition,
603603
*
604604
* Returns the original drawing XML stored during load (when Reader pass-through was enabled).
605605
* This preserves unsupported drawing elements (shapes, textboxes) that PhpSpreadsheet cannot parse.
606+
*
607+
* @return ?string The pass-through XML, or null if not available or should not be used
606608
*/
607609
private function getPassThroughDrawingXml(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet): ?string
608610
{
@@ -612,11 +614,20 @@ private function getPassThroughDrawingXml(\PhpOffice\PhpSpreadsheet\Worksheet\Wo
612614
}
613615

614616
$codeName = $worksheet->getCodeName();
615-
if (!isset($unparsedLoadedData['sheets'][$codeName]) || !is_array($unparsedLoadedData['sheets'][$codeName])) {
617+
if (!isset($unparsedLoadedData['sheets'][$codeName])) {
616618
return null;
617619
}
618620

619621
$sheetData = $unparsedLoadedData['sheets'][$codeName];
622+
if (!is_array($sheetData)) {
623+
return null;
624+
}
625+
626+
// Only use pass-through XML if the Reader flag was explicitly enabled
627+
if (($sheetData['drawingPassThroughEnabled'] ?? false) !== true) {
628+
return null;
629+
}
630+
620631
if (!isset($sheetData['Drawings']) || !is_array($sheetData['Drawings'])) {
621632
return null;
622633
}

tests/PhpSpreadsheetTests/Writer/Xlsx/DrawingPassThroughTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,59 @@ public function testDrawingPassThroughGetterSetter(): void
385385
$reader->setEnableDrawingPassThrough(false);
386386
self::assertFalse($reader->getEnableDrawingPassThrough());
387387
}
388+
389+
/**
390+
* Test that the drawingPassThroughEnabled flag is correctly set in unparsedLoadedData.
391+
* This verifies the Reader sets the flag and the Writer's getPassThroughDrawingXml checks it.
392+
*/
393+
public function testDrawingPassThroughEnabledFlagIsSetCorrectly(): void
394+
{
395+
// Test 1: Load WITHOUT pass-through (default)
396+
$reader = new XlsxReader();
397+
self::assertFalse($reader->getEnableDrawingPassThrough(), 'Pass-through should be disabled by default');
398+
$spreadsheet = $reader->load(self::TEMPLATE);
399+
400+
$sheet = $spreadsheet->getActiveSheet();
401+
$unparsedData = $spreadsheet->getUnparsedLoadedData();
402+
$codeName = $sheet->getCodeName();
403+
404+
// Verify that drawingPassThroughEnabled flag is NOT set when pass-through is disabled
405+
self::assertArrayHasKey('sheets', $unparsedData);
406+
self::assertIsArray($unparsedData['sheets']);
407+
408+
// The sheet may exist in unparsedData (legacy empty drawings), but the flag should be absent or false
409+
if (isset($unparsedData['sheets'][$codeName])) {
410+
$sheetData = $unparsedData['sheets'][$codeName];
411+
self::assertIsArray($sheetData);
412+
$flag = $sheetData['drawingPassThroughEnabled'] ?? false;
413+
self::assertFalse($flag, 'drawingPassThroughEnabled should be false/absent when pass-through is disabled');
414+
}
415+
416+
$spreadsheet->disconnectWorksheets();
417+
418+
// Test 2: Load WITH pass-through enabled
419+
$reader2 = new XlsxReader();
420+
$reader2->setEnableDrawingPassThrough(true);
421+
self::assertTrue($reader2->getEnableDrawingPassThrough(), 'Pass-through should be enabled');
422+
$spreadsheet2 = $reader2->load(self::TEMPLATE);
423+
424+
$sheet2 = $spreadsheet2->getActiveSheet();
425+
$unparsedData2 = $spreadsheet2->getUnparsedLoadedData();
426+
$codeName2 = $sheet2->getCodeName();
427+
428+
// Verify that drawingPassThroughEnabled flag IS set when pass-through is enabled
429+
self::assertArrayHasKey('sheets', $unparsedData2);
430+
self::assertIsArray($unparsedData2['sheets']);
431+
self::assertArrayHasKey($codeName2, $unparsedData2['sheets']);
432+
self::assertIsArray($unparsedData2['sheets'][$codeName2]);
433+
self::assertArrayHasKey('drawingPassThroughEnabled', $unparsedData2['sheets'][$codeName2], 'drawingPassThroughEnabled flag should exist');
434+
self::assertTrue($unparsedData2['sheets'][$codeName2]['drawingPassThroughEnabled'], 'drawingPassThroughEnabled should be true when pass-through is enabled');
435+
436+
// Verify that the drawing XML is also stored
437+
self::assertArrayHasKey('Drawings', $unparsedData2['sheets'][$codeName2]);
438+
self::assertIsArray($unparsedData2['sheets'][$codeName2]['Drawings']);
439+
self::assertNotEmpty($unparsedData2['sheets'][$codeName2]['Drawings'], 'Drawing XML should be stored when pass-through is enabled');
440+
441+
$spreadsheet2->disconnectWorksheets();
442+
}
388443
}

0 commit comments

Comments
 (0)