diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md
index 2ee54698cc..a8c3cd596e 100644
--- a/docs/changes/2.x/2.0.0.md
+++ b/docs/changes/2.x/2.0.0.md
@@ -8,6 +8,8 @@
- MsDoc Reader : Correct Font Size Calculation by [@oleibman](https://github.com/oleibman) fixing [#2526](https://github.com/PHPOffice/PHPWord/issues/2526) in [#2531](https://github.com/PHPOffice/PHPWord/pull/2531)
+- bug: TemplateProcessor fix multiline values [@gimler](https://github.com/gimler) fixing [#268](https://github.com/PHPOffice/PHPWord/issues/268), [#2323](https://github.com/PHPOffice/PHPWord/issues/2323) and [#2486](https://github.com/PHPOffice/PHPWord/issues/2486) in [#2522](https://github.com/PHPOffice/PHPWord/pull/2522)
+
### Miscellaneous
- Bump dompdf/dompdf from 2.0.3 to 2.0.4 by [@dependabot](https://github.com/dependabot) in [#2530](https://github.com/PHPOffice/PHPWord/pull/2530)
diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php
index 1ad901d480..27577499e5 100644
--- a/src/PhpWord/TemplateProcessor.php
+++ b/src/PhpWord/TemplateProcessor.php
@@ -357,6 +357,15 @@ public function setValue($search, $replace, $limit = self::MAXIMUM_REPLACEMENTS_
$replace = $xmlEscaper->escape($replace);
}
+ // convert carriage returns
+ if (is_array($replace)) {
+ foreach ($replace as &$item) {
+ $item = $this->replaceCarriageReturns($item);
+ }
+ } else {
+ $replace = $this->replaceCarriageReturns($replace);
+ }
+
$this->tempDocumentHeaders = $this->setValueForPart($search, $replace, $this->tempDocumentHeaders, $limit);
$this->tempDocumentMainPart = $this->setValueForPart($search, $replace, $this->tempDocumentMainPart, $limit);
$this->tempDocumentFooters = $this->setValueForPart($search, $replace, $this->tempDocumentFooters, $limit);
@@ -1305,6 +1314,14 @@ protected function indexClonedVariables($count, $xmlBlock)
return $results;
}
+ /**
+ * Replace carriage returns with xml.
+ */
+ public function replaceCarriageReturns(string $string): string
+ {
+ return str_replace(["\r\n", "\r", "\n"], '', $string);
+ }
+
/**
* Replaces variables with values from array, array keys are the variable names.
*
diff --git a/tests/PhpWordTests/TemplateProcessorTest.php b/tests/PhpWordTests/TemplateProcessorTest.php
index f2d2cfbf13..65d5cfe9d8 100644
--- a/tests/PhpWordTests/TemplateProcessorTest.php
+++ b/tests/PhpWordTests/TemplateProcessorTest.php
@@ -591,6 +591,24 @@ public function testSetValues(): void
self::assertStringContainsString('Hello John Doe', $templateProcessor->getMainPart());
}
+ /**
+ * @covers ::setValues
+ */
+ public function testSetValuesMultiLine(): void
+ {
+ $mainPart = '
+
+
+ Address: ${address}
+
+ ';
+
+ $templateProcessor = new TestableTemplateProcesor($mainPart);
+ $templateProcessor->setValues(['address' => "Peter Pan\nNeverland"]);
+
+ self::assertStringContainsString('Address: Peter PanNeverland', $templateProcessor->getMainPart());
+ }
+
/**
* @covers ::setValues
*/