Skip to content

Commit

Permalink
[BUGFIX] Ensure nested w:sdt -> w:sdtContent node parsing for Document
Browse files Browse the repository at this point in the history
Nodes can be nested or directly provided for the document structure.
Until now, the `sdt->sdtContent` wrapping have not been respected.

This change moves the node parsing for a document to a dedicated
method and make it recursivly callable to unnest the wrapped node.
  • Loading branch information
sbuerk committed Apr 2, 2024
1 parent 8b891bb commit bf40294
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/PhpWord/Reader/Word2007/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Reader\Word2007;

use DOMElement;
use DOMNode;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Shared\XMLReader;
Expand Down Expand Up @@ -46,15 +47,33 @@ public function read(PhpWord $phpWord): void
$this->phpWord = $phpWord;
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($this->docFile, $this->xmlFile);
$readMethods = ['w:p' => 'readWPNode', 'w:tbl' => 'readTable', 'w:sectPr' => 'readWSectPrNode'];

$nodes = $xmlReader->getElements('w:body/*');
if ($nodes->length > 0) {
$section = $this->phpWord->addSection();
foreach ($nodes as $node) {
if (isset($readMethods[$node->nodeName])) {
$readMethod = $readMethods[$node->nodeName];
$this->$readMethod($xmlReader, $node, $section);
$this->readNode($phpWord, $xmlReader, $node, $section);
}
}
}

private function readNode(PhpWord $phpWord, XMLReader $xmlReader, DOMNode $node, Section $section): void
{
$readMethods = ['w:p' => 'readWPNode', 'w:tbl' => 'readTable', 'w:sectPr' => 'readWSectPrNode'];
if (isset($readMethods[$node->nodeName])) {
$readMethod = $readMethods[$node->nodeName];
$this->$readMethod($xmlReader, $node, $section);
} elseif ($node->nodeName === 'w:sdt' && $node instanceof DOMElement) {
$nodes = $xmlReader->getElements('w:sdtContent/*', $node);
if ($nodes->length > 0) {
foreach ($nodes as $subNode) {
$this->readNode($phpWord, $xmlReader, $subNode, $section);
}
}
} elseif ($node->nodeName === 'w:sdtContent' && $node instanceof DOMElement) {
$nodes = $xmlReader->getElements('*', $node);
if ($nodes->length > 0) {
foreach ($nodes as $subNode) {
$this->readNode($phpWord, $xmlReader, $subNode, $section);
}
}
}
Expand Down

0 comments on commit bf40294

Please sign in to comment.