From 9660d59ecbd19d51c8cac11eb4a91bb75de37aa4 Mon Sep 17 00:00:00 2001 From: moghwan Date: Fri, 12 Jul 2024 13:22:39 +0100 Subject: [PATCH 01/10] adding limit option to setValues for multiple values --- src/PhpWord/TemplateProcessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 8aee40c546..4948cadc81 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -362,10 +362,10 @@ public function setValue($search, $replace, $limit = self::MAXIMUM_REPLACEMENTS_ /** * Set values from a one-dimensional array of "variable => value"-pairs. */ - public function setValues(array $values): void + public function setValues(array $values, $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT): void { foreach ($values as $macro => $replace) { - $this->setValue($macro, $replace); + $this->setValue($macro, $replace, $limit); } } From 5fbf82cad85dd1da7a16934aa6ec0ef0fb483817 Mon Sep 17 00:00:00 2001 From: moghwan Date: Fri, 12 Jul 2024 15:37:10 +0100 Subject: [PATCH 02/10] add parameter type --- src/PhpWord/TemplateProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 4948cadc81..4474fbf2de 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -362,7 +362,7 @@ public function setValue($search, $replace, $limit = self::MAXIMUM_REPLACEMENTS_ /** * Set values from a one-dimensional array of "variable => value"-pairs. */ - public function setValues(array $values, $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT): void + public function setValues(array $values, int $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT): void { foreach ($values as $macro => $replace) { $this->setValue($macro, $replace, $limit); From 8ae73127a7ae074561a0566a2208f079d97bb377 Mon Sep 17 00:00:00 2001 From: moghwan Date: Fri, 12 Jul 2024 15:56:01 +0100 Subject: [PATCH 03/10] Update 2.0.0.md --- docs/changes/2.x/2.0.0.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md index c5fbaf4b52..6d8d7cf0d1 100644 --- a/docs/changes/2.x/2.0.0.md +++ b/docs/changes/2.x/2.0.0.md @@ -24,5 +24,6 @@ - Bump symfony/process from 5.4.28 to 5.4.34 by [@dependabot](https://github.com/dependabot) in [#2536](https://github.com/PHPOffice/PHPWord/pull/2536) - Allow rgb() when converting Html by [@oleibman](https://github.com/oleibman) fixing [#2508](https://github.com/PHPOffice/PHPWord/issues/2508) in [#2512](https://github.com/PHPOffice/PHPWord/pull/2512) - Improved Issue Template by [@Progi1984](https://github.com/Progi1984) in [#2609](https://github.com/PHPOffice/PHPWord/pull/2609) +- Adding the possibility to use iterate search and replace with setValues by [@moghwan](https://github.com/moghwan) in [#2632](https://github.com/PHPOffice/PHPWord/pull/2632) ### BC Breaks From 2bb2190d18361016abc884f6c2a403ddb7d2c350 Mon Sep 17 00:00:00 2001 From: moghwan Date: Sun, 4 Aug 2024 16:28:12 +0100 Subject: [PATCH 04/10] adding limit oprion to cloneblock --- src/PhpWord/TemplateProcessor.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 8aee40c546..5aace8b0ac 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -893,7 +893,7 @@ public function cloneRowAndSetValues($search, $values): void * * @return null|string */ - public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null) + public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null, int $limit = MAXIMUM_REPLACEMENTS_DEFAULT) { $xmlBlock = null; $matches = []; @@ -921,11 +921,21 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria } if ($replace) { - $this->tempDocumentMainPart = str_replace( - $matches[2] . $matches[3] . $matches[4], - implode('', $cloned), - $this->tempDocumentMainPart - ); + if(self::MAXIMUM_REPLACEMENTS_DEFAULT === $limit) { + $this->tempDocumentMainPart = str_replace( + $matches[2] . $matches[3] . $matches[4], + implode('', $cloned), + $this->tempDocumentMainPart + ); + } else { + $regExpEscaper = new RegExp(); + $this->tempDocumentMainPart = preg_replace( + $regExpEscaper->escape($matches[2] . $matches[3] . $matches[4]), + implode('', $cloned), + $this->tempDocumentMainPart, + $limit + ); + } } } From eb5f82b735f7179512167257ac801d13de4102d7 Mon Sep 17 00:00:00 2001 From: moghwan Date: Sun, 4 Aug 2024 16:44:53 +0100 Subject: [PATCH 05/10] phpcs improved --- src/PhpWord/TemplateProcessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 5aace8b0ac..6d3b8b8f78 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -893,7 +893,7 @@ public function cloneRowAndSetValues($search, $values): void * * @return null|string */ - public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null, int $limit = MAXIMUM_REPLACEMENTS_DEFAULT) + public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null, int $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT) { $xmlBlock = null; $matches = []; @@ -921,7 +921,7 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria } if ($replace) { - if(self::MAXIMUM_REPLACEMENTS_DEFAULT === $limit) { + if (self::MAXIMUM_REPLACEMENTS_DEFAULT === $limit) { $this->tempDocumentMainPart = str_replace( $matches[2] . $matches[3] . $matches[4], implode('', $cloned), From 88a2646f4ccde0d13c22b36ab3c6008f60abeffc Mon Sep 17 00:00:00 2001 From: moghwan Date: Tue, 27 Aug 2024 12:08:06 +0100 Subject: [PATCH 06/10] add more replacement for testSetValues --- tests/PhpWordTests/TemplateProcessorTest.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index b8ad970ced..11bd98d0c9 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -614,7 +614,18 @@ public function testSetValues(): void Hello ${firstname} ${lastname} - '; + + + + Hello ${firstname} ${lastname} + + + + + Hello ${firstname} ${lastname} + + + '; $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'John', 'lastname' => 'Doe']); From 16a6f23bce568dc59c38c88271cc5e0899ac486f Mon Sep 17 00:00:00 2001 From: moghwan Date: Tue, 27 Aug 2024 12:09:23 +0100 Subject: [PATCH 07/10] testSetValues with different limit values --- tests/PhpWordTests/TemplateProcessorTest.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index 11bd98d0c9..2eb6f2cc2f 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -629,8 +629,17 @@ public function testSetValues(): void $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'John', 'lastname' => 'Doe']); - self::assertStringContainsString('Hello John Doe', $templateProcessor->getMainPart()); + + // test with a specific limit that is lower than the number of replacements + $templateProcessor = new TestableTemplateProcesor($mainPart); + $templateProcessor->setValues(['firstname' => 'Jane', 'lastname' => 'Smith'], 2); + self::assertStringContainsString('Hello Jane Smith', $templateProcessor->getMainPart()); + + // test with a limit for only one replacement + $templateProcessor = new TestableTemplateProcesor($mainPart); + $templateProcessor->setValues(['firstname' => 'Alice', 'lastname' => 'Wonderland'], 1); + self::assertStringContainsString('Hello Alice Wonderland', $templateProcessor->getMainPart()); } /** From aa13b54fb473c2a3d5f34f06c9c7b13bdaa3e22d Mon Sep 17 00:00:00 2001 From: moghwan Date: Tue, 27 Aug 2024 12:23:58 +0100 Subject: [PATCH 08/10] testSetValues with a zero replacement --- tests/PhpWordTests/TemplateProcessorTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index 2eb6f2cc2f..178f8e92c4 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -630,16 +630,25 @@ public function testSetValues(): void $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'John', 'lastname' => 'Doe']); self::assertStringContainsString('Hello John Doe', $templateProcessor->getMainPart()); + self::assertStringNotContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); // test with a specific limit that is lower than the number of replacements $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'Jane', 'lastname' => 'Smith'], 2); self::assertStringContainsString('Hello Jane Smith', $templateProcessor->getMainPart()); + self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); // test with a limit for only one replacement $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'Alice', 'lastname' => 'Wonderland'], 1); self::assertStringContainsString('Hello Alice Wonderland', $templateProcessor->getMainPart()); + self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); + + // Test with a limit of 0 for a result with no replacements + $templateProcessor = new TestableTemplateProcesor($mainPart); + $templateProcessor->setValues(['firstname' => 'Test', 'lastname' => 'User'], 0); + self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); + self::assertStringNotContainsString('Hello Test User', $templateProcessor->getMainPart()); } /** From e58a5907bfd22acec78cf1fd301a04a8084068ca Mon Sep 17 00:00:00 2001 From: moghwan Date: Tue, 27 Aug 2024 13:03:23 +0100 Subject: [PATCH 09/10] Update 1.3.0.md --- docs/changes/1.x/1.3.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes/1.x/1.3.0.md b/docs/changes/1.x/1.3.0.md index 3acf9c7830..05f0c18597 100644 --- a/docs/changes/1.x/1.3.0.md +++ b/docs/changes/1.x/1.3.0.md @@ -45,6 +45,6 @@ - Bump mpdf/mpdf from 8.2.2 to 8.2.4 by [@dependabot](https://github.com/dependabot) in [#2647](https://github.com/PHPOffice/PHPWord/pull/2647) - Bump phenx/php-svg-lib from 0.5.1 to 0.5.4 by [@dependabot](https://github.com/dependabot) in [#2649](https://github.com/PHPOffice/PHPWord/pull/2649) - Bump phpstan/phpstan-phpunit from 1.3.15 to 1.4.0 by [@dependabot](https://github.com/dependabot) in [#2648](https://github.com/PHPOffice/PHPWord/pull/2648) -- Adding the possibility to use iterate search and replace with setValues by [@moghwan](https://github.com/moghwan) in [#2632](https://github.com/PHPOffice/PHPWord/pull/2632) +- Adding the possibility to use iterate search and replace with setValues by [@moghwan](https://github.com/moghwan) in [#2632](https://github.com/PHPOffice/PHPWord/pull/2640) ### BC Breaks From 32b796df185245d3b859fbf20432c81bfbc41e91 Mon Sep 17 00:00:00 2001 From: moghwan Date: Tue, 27 Aug 2024 14:44:04 +0100 Subject: [PATCH 10/10] improve tests with variables count check to ensure number of occurrences replaced --- tests/PhpWordTests/TemplateProcessorTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php index 178f8e92c4..a88c8cf7a0 100644 --- a/tests/PhpWordTests/TemplateProcessorTest.php +++ b/tests/PhpWordTests/TemplateProcessorTest.php @@ -635,20 +635,32 @@ public function testSetValues(): void // test with a specific limit that is lower than the number of replacements $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'Jane', 'lastname' => 'Smith'], 2); + $variablesCounts = $templateProcessor->getVariableCount(); + self::assertStringContainsString('Hello Jane Smith', $templateProcessor->getMainPart()); self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); + self::assertEquals(1, $variablesCounts['firstname']); + self::assertEquals(1, $variablesCounts['lastname']); // test with a limit for only one replacement $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'Alice', 'lastname' => 'Wonderland'], 1); + $variablesCounts = $templateProcessor->getVariableCount(); + self::assertStringContainsString('Hello Alice Wonderland', $templateProcessor->getMainPart()); self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); + self::assertEquals(2, $variablesCounts['firstname']); + self::assertEquals(2, $variablesCounts['lastname']); // Test with a limit of 0 for a result with no replacements $templateProcessor = new TestableTemplateProcesor($mainPart); $templateProcessor->setValues(['firstname' => 'Test', 'lastname' => 'User'], 0); + $variablesCounts = $templateProcessor->getVariableCount(); + self::assertStringContainsString('Hello ${firstname} ${lastname}', $templateProcessor->getMainPart()); self::assertStringNotContainsString('Hello Test User', $templateProcessor->getMainPart()); + self::assertEquals(3, $variablesCounts['firstname']); + self::assertEquals(3, $variablesCounts['lastname']); } /**