improve `cloneBlock` regex
it wrongly matched `<w:pPr` when looking for `<w:p` in that case the cloned block would not be valid XML, and so the generated docx document could not be opened by Word adding the `\b` word boundary to the regex fixes this. the accompanying unit test failed with this message when trying to load the generated file: ``` ErrorException: DOMDocument::loadXML(): Opening and ending tag mismatch: p line 2 and body in Entity, line: 2 ``` This might solve issues such as #681 and #664.
This commit is contained in:
parent
9a91d54e10
commit
4105a9aad1
|
|
@ -322,7 +322,7 @@ class TemplateProcessor
|
||||||
{
|
{
|
||||||
$xmlBlock = null;
|
$xmlBlock = null;
|
||||||
preg_match(
|
preg_match(
|
||||||
'/(<\?xml.*)(<w:p.*>\${' . $blockname . '}<\/w:.*?p>)(.*)(<w:p.*\${\/' . $blockname . '}<\/w:.*?p>)/is',
|
'/(<\?xml.*)(<w:p\b.*>\${' . $blockname . '}<\/w:.*?p>)(.*)(<w:p\b.*\${\/' . $blockname . '}<\/w:.*?p>)/is',
|
||||||
$this->tempDocumentMainPart,
|
$this->tempDocumentMainPart,
|
||||||
$matches
|
$matches
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -223,4 +223,56 @@ final class TemplateProcessorTest extends \PHPUnit\Framework\TestCase
|
||||||
unlink($docName);
|
unlink($docName);
|
||||||
$this->assertTrue($docFound);
|
$this->assertTrue($docFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::cloneBlock
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function cloneBlockCanCloneABlockTwice()
|
||||||
|
{
|
||||||
|
// create template with placeholders and block
|
||||||
|
$phpWord = new PhpWord();
|
||||||
|
$section = $phpWord->addSection();
|
||||||
|
$documentElements = array(
|
||||||
|
'Title: ${title}',
|
||||||
|
'${subreport}',
|
||||||
|
'${subreport.id}: ${subreport.text}. ',
|
||||||
|
'${/subreport}',
|
||||||
|
);
|
||||||
|
foreach ($documentElements as $documentElement) {
|
||||||
|
$section->addText($documentElement);
|
||||||
|
}
|
||||||
|
$objWriter = IOFactory::createWriter($phpWord);
|
||||||
|
$templatePath = 'test.docx';
|
||||||
|
$objWriter->save($templatePath);
|
||||||
|
|
||||||
|
// replace placeholders and save the file
|
||||||
|
$templateProcessor = new TemplateProcessor($templatePath);
|
||||||
|
$templateProcessor->setValue('title', 'Some title');
|
||||||
|
$templateProcessor->cloneBlock('subreport', 2);
|
||||||
|
$templateProcessor->setValue('subreport.id', '123', 1);
|
||||||
|
$templateProcessor->setValue('subreport.text', 'Some text', 1);
|
||||||
|
$templateProcessor->setValue('subreport.id', '456', 1);
|
||||||
|
$templateProcessor->setValue('subreport.text', 'Some other text', 1);
|
||||||
|
$templateProcessor->saveAs($templatePath);
|
||||||
|
|
||||||
|
// assert the block has been cloned twice
|
||||||
|
// and the placeholders have been replaced correctly
|
||||||
|
$phpWord = IOFactory::load($templatePath);
|
||||||
|
$sections = $phpWord->getSections();
|
||||||
|
$actualElements = $sections[0]->getElements();
|
||||||
|
unlink($templatePath);
|
||||||
|
$expectedElements = array(
|
||||||
|
'Title: Some title',
|
||||||
|
'123: Some text. ',
|
||||||
|
'456: Some other text. ',
|
||||||
|
);
|
||||||
|
$this->assertCount(count($expectedElements), $actualElements);
|
||||||
|
foreach ($expectedElements as $i => $expectedElement) {
|
||||||
|
$this->assertEquals(
|
||||||
|
$expectedElement,
|
||||||
|
$actualElements[$i]->getText()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue