diff --git a/docs/changes/1.x/1.3.0.md b/docs/changes/1.x/1.3.0.md
index 4e38e38f91..2496313bf3 100644
--- a/docs/changes/1.x/1.3.0.md
+++ b/docs/changes/1.x/1.3.0.md
@@ -27,8 +27,6 @@
- Template Processor : Fixed bad naming of variables fixing [#2586](https://github.com/PHPOffice/PHPWord/issues/2586) by [@Progi1984](https://github.com/Progi1984) in [#2655](https://github.com/PHPOffice/PHPWord/pull/2655)
- Word2007 Writer : Fix first footnote appearing as separator [#2634](https://github.com/PHPOffice/PHPWord/issues/2634) by [@jacksleight](https://github.com/jacksleight) in [#2635](https://github.com/PHPOffice/PHPWord/pull/2635)
- Template Processor : Fixed images with transparent backgrounds displaying a white background by [@ElwynVdb](https://github.com/ElwynVdb) in [#2638](https://github.com/PHPOffice/PHPWord/pull/2638)
-- HTML Writer : Fixed rowspan for tables by [@andomiell](https://github.com/andomiell) in [#2659](https://github.com/PHPOffice/PHPWord/pull/2659)
-- Word2007 Writer : Fixed StrikeThrough property by [@noec764](https://github.com/noec764) fixing [#1722](https://github.com/PHPOffice/PHPWord/issues/1722) & [#1693](https://github.com/PHPOffice/PHPWord/issues/1693) in [#2661](https://github.com/PHPOffice/PHPWord/pull/2661)
### Miscellaneous
@@ -45,5 +43,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/2640)
### BC Breaks
diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php
index f6fe1d8887..5fd790674b 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, int $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT): void
{
foreach ($values as $macro => $replace) {
- $this->setValue($macro, $replace);
+ $this->setValue($macro, $replace, $limit);
}
}
@@ -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 = self::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
+ );
+ }
}
}
diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php
index b8ad970ced..a88c8cf7a0 100644
--- a/tests/PhpWordTests/TemplateProcessorTest.php
+++ b/tests/PhpWordTests/TemplateProcessorTest.php
@@ -614,12 +614,53 @@ public function testSetValues(): void
Hello ${firstname} ${lastname}
- ';
+
+
+
+ Hello ${firstname} ${lastname}
+
+
+
+
+ Hello ${firstname} ${lastname}
+
+
+ ';
$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);
+ $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']);
}
/**