From 4019ca181cb2430cd1ce8ae968c792141df22b1c Mon Sep 17 00:00:00 2001 From: "e.kremnev" Date: Wed, 17 Aug 2022 13:43:48 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BC=D1=83=D1=81=D0=BE=D1=80=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=82=D0=B5=D0=B3=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D0=B1?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D1=88=D0=B8=D1=85=20=D1=88=D0=B0=D0=B1=D0=BB?= =?UTF-8?q?=D0=BE=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .phpunit.result.cache | 2 +- src/PhpDocxTemplate.php | 39 +++++++++-- tests/PhpDocxTemplateTest.php | 120 +++++++++++++++++----------------- tests/documents/.gitignore | 3 + 4 files changed, 97 insertions(+), 67 deletions(-) create mode 100644 tests/documents/.gitignore diff --git a/.phpunit.result.cache b/.phpunit.result.cache index 366e0d6..086d622 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":1,"defects":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":4,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":3},"times":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":0.008,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testXmlToString":0.005,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetDocx":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetXml":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testPatchXml":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRenderXml":0.014,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRender":0.007,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testLineBreak":0.003,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testCyrillic":0.002,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testForLoop":0.006,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":0.788,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":0.009}} \ No newline at end of file +{"version":1,"defects":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":4,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTemplate":4,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRenderXml":3,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testPatchXml":4},"times":{"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTable":0.057,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testXmlToString":0.029,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetDocx":0.02,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testGetXml":0.025,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testPatchXml":0.021,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRenderXml":0.083,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testRender":0.065,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testLineBreak":0.056,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testCyrillic":0.074,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testForLoop":0.057,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testImages":0.124,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testSections":0.09,"Doctrine\\Tests\\DBAL\\Query\\PhpDocxTemplateTest::testTemplate":0.111}} \ No newline at end of file diff --git a/src/PhpDocxTemplate.php b/src/PhpDocxTemplate.php index 6d72a38..c87bb82 100644 --- a/src/PhpDocxTemplate.php +++ b/src/PhpDocxTemplate.php @@ -3,7 +3,6 @@ namespace PhpDocxTemplate; use DOMDocument; -use DOMElement; use Twig\Loader\ArrayLoader; use Twig\Environment; use PhpDocxTemplate\Twig\Impl\{ @@ -99,16 +98,44 @@ private function updateXml(DOMDocument $xml): void $this->docx->updateDOMDocument($xml); } + public function patchXml(string $xml): string + { + $matches = []; + + preg_match('/^.*?()/s', $xml, $matches); + + $beforeXml = $matches[0]; + + preg_match('/(<\/w:body>).*?$/s', $xml, $matches); + + $afterXml = $matches[0]; + + $dom = new DOMDocument(); + $dom->loadXML($xml); + + $elBody = $dom->getElementsByTagName('body')->item(0); + + $chunkXml = ''; + + for ($itemIdx = 0; $itemIdx < $elBody->childNodes->count(); $itemIdx++) { + $el = $elBody->childNodes->item($itemIdx); + + $chunkXml .= $this->patchXmlChunk($el->ownerDocument->saveXML($el)); + } + + return sprintf('%s%s%s', $beforeXml, $chunkXml, $afterXml); + } + /** * Patch initial xml * * @param string $xml - initial xml */ - public function patchXml(string $xml): string + public function patchXmlChunk(string $xml): string { - $xml = preg_replace('/(?<={)(<[^>]*>)+(?=[\{%])|(?<=[%\}])(<[^>]*>)+(?=\})/mu', '', $xml); + $xml = preg_replace('/(?<={)(<[^>]*>)+(?=[\{%\#])|(?<=[%\}\#])(<[^>]*>)+(?=\})/mu', '', $xml); $xml = preg_replace_callback( - '/{%(?:(?!%}).)*|{{(?:(?!}}).)*/mu', + '/{%(?:(?!%}).)*|{#(?:(?!#}).)*|{{(?:(?!}}).)*/mu', array(get_class($this), 'stripTags'), $xml ); @@ -262,7 +289,7 @@ private function resolveText(string $paragraphProperties, string $runProperties, * * @return string */ - private function stripTags(array $matches): string + private static function stripTags(array $matches): string { return preg_replace('/<\/w:t>.*?(|]*>)/mu', '', $matches[0]); } @@ -274,7 +301,7 @@ private function stripTags(array $matches): string * * @return string */ - private function colspan(array $matches): string + private static function colspan(array $matches): string { $cellXml = $matches[1] . $matches[3]; $cellXml = preg_replace('/](?:(?!]).)*<\/w:t>.*?<\/w:r>/mu', '', $cellXml); diff --git a/tests/PhpDocxTemplateTest.php b/tests/PhpDocxTemplateTest.php index 066de7e..0cdd9fc 100644 --- a/tests/PhpDocxTemplateTest.php +++ b/tests/PhpDocxTemplateTest.php @@ -23,7 +23,7 @@ class PhpDocxTemplateTest extends TestCase public function testXmlToString(): void { $xml = new DOMDocument('1.0'); - $root = $xml->createElement('book'); + $root = $xml->createElement('w:body'); $root = $xml->appendChild($root); $title = $xml->createElement('title'); $title = $root->appendChild($title); @@ -33,7 +33,7 @@ public function testXmlToString(): void $this->assertEquals( $reporter->xmlToString($xml), - "\nTitle\n" + "\nTitle\n" ); $reporter->close(); } @@ -99,17 +99,17 @@ public function testPatchXml(): void //test stripTags $xml = "{%Hello\nworld%}\n{{Hi\nthere}}\n"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), "{%Hello\nworld%}\n{{Hi\nthere}}\n" ); //test colspan $xml = "TAnAaqg_a}sePvK.OO#Q=B-]cBDFM8UL]8m@i" . - "Ct{% colspan val%}TkuSd" . - "?Nl`z:^kY@FXeJ@P{8WhCt0__/,8woI2." . - "8#[r_Cqig!5Qt{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe"; + "Ct{% colspan val%}TkuSd" . + "?Nl`z:^kY@FXeJ@P{8WhCt0__/,8woI2." . + "8#[r_Cqig!5Qt{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), 'TAnAaqg_a}sePvK.OO#Q=B-]cBDFM8UL]8m@iCtTkuSd' . '?Nl`z:^kY@FXeJ@P{8WhCt0__/,8woI2.8#[r_Cqig!5Qt' . '{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe' @@ -117,11 +117,11 @@ public function testPatchXml(): void //test cellbg $xml = "TAnAaqg_a}sePvK.OO#Q=B-]cBDFM8UL]8m@i" . - "Ct{% cellbg val%}TkuSd" . - "?Nl`z:^kY@FXeJ@P{8WhCt0__/,8woI2." . - "8#[r_Cqig!5Qt{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe"; + "Ct{% cellbg val%}TkuSd" . + "?Nl`z:^kY@FXeJ@P{8WhCt0__/,8woI2." . + "8#[r_Cqig!5Qt{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), 'TAnAaqg_a}sePvK.OO#Q=B-]cBDFM8UL]8m@iCtTkuSd' . '?Nl`z:^kY@FXeJ@P{8WhCt0__/,' . '8woI2.8#[r_Cqig!5Qt{8gl5ls<9Ci|^QN2IK#L[cB9@:XclVQQIxe' @@ -129,16 +129,16 @@ public function testPatchXml(): void $xml = "{%r _Rom{X=aC3/s#W#~o<#d:tH^>DTAz;s<}O0RJ#V!wW:]%kR@wzLf*\iu^zAGrr!3]vkA.:*1?,0%}"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), '{%r _Rom{X=aC3/s#W#~o<#d:tH^>DTAz;s<}O0RJ#V!wW:]%kR' . '@wzLf*\iu^zAGrr!3]vkA.:*1?,0%}' ); // test vMerge $xml = "t/H-Q.X)jC_sI6(J7w-;QI&JpDG}:>f02Zls<8(7&SEyc>" . - "`@P/{% vm %}"; + "`@P/{% vm %}"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), 't/H-Q.X)jC_sI6(J7w-;QI&JpDG}:>f02Zls<8(7&SEyc>`' . '@P/{% if loop.first %}{% endif %}' @@ -146,9 +146,9 @@ public function testPatchXml(): void // test hMerge $xml = "t/H-Q.X)jC_sI6(J7w-;QI&JpDG}:>f02Zls<8(7&SEyc>" . - "`@P/{% hm %}"; + "`@P/{% hm %}"; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), '{% if loop.first %}t/H-Q.X)' . 'jC_sI6(J7w-;QI&JpDG}:>f02Zls<8(7&SEyc>`@P/{% endif %}' ); @@ -156,7 +156,7 @@ public function testPatchXml(): void // test cleanTags $xml = '{%‘<>“”‘’%}'; $this->assertEquals( - $reporter->patchXml($xml), + $reporter->patchXmlChunk($xml), "{%'<>\"\"''%}" ); $reporter->close(); @@ -754,48 +754,48 @@ public function testImages(): void public function testSections(): void { $reporter = new PhpDocxTemplate(self::TEMPLATE9); - /* $this->assertEquals( - $reporter->buildXml(["object" => "world"]), - "\n" . - "" . - "Hello world!" . - "" . - "" . - "" . - "\n" - );*/ + /* $this->assertEquals( + $reporter->buildXml(["object" => "world"]), + "\n" . + "" . + "Hello world!" . + "" . + "" . + "" . + "\n" + );*/ $docName = './doc9.docx'; $reporter->render(["object" => "test", "section" => [["id" => "test section"]]]); $reporter->save($docName); @@ -805,7 +805,7 @@ public function testSections(): void $expectedDocumentZip->open($docName); $header = $expectedDocumentZip->getFromName('word/header2.xml'); $this->assertEquals('' . PHP_EOL . -'