From 7790b6a6b0f964131c025703b81da5e4c350b60c Mon Sep 17 00:00:00 2001 From: troosan Date: Thu, 27 Dec 2018 22:13:48 +0100 Subject: [PATCH] Pass values to replace macros with in cloneBlock --- CHANGELOG.md | 1 + docs/templates-processing.rst | 23 +++++++++++++++++ src/PhpWord/TemplateProcessor.php | 27 +++++++++++++++++++- tests/PhpWord/TemplateProcessorTest.php | 33 +++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d440989c..af226cf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ v0.16.0 (xx dec 2018) - Add support for setting images in TemplateProcessor @SailorMax #1170 - Add "Plain Text" type to SDT (Structured Document Tags) @morrisdj #1541 - Added possibility to index variables inside cloned block in TemplateProcessor @JPBetley #817 +- Added possibility to replace variables inside cloned block with values in TemplateProcessor @DIDoS #1392 ### Fixed - Fix regex in `cloneBlock` function @nicoder #1269 diff --git a/docs/templates-processing.rst b/docs/templates-processing.rst index 6513cb24..095093b2 100644 --- a/docs/templates-processing.rst +++ b/docs/templates-processing.rst @@ -79,11 +79,34 @@ The result will be Customer: ${customer_name#1} Address: ${customer_address#1} + Customer: ${customer_name#2} Address: ${customer_address#2} + Customer: ${customer_name#3} Address: ${customer_address#3} +It is also possible to pass an array with the values to replace the marcros with. +If an array with replacements is passed, the ``count`` argument is ignored, it is the size of the array that counts. + +.. code-block:: php + + $replacements = array( + array('customer_name' => 'Batman', 'customer_address' => 'Gotham City'), + array('customer_name' => 'Superman', 'customer_address' => 'Metropolis'), + ); + $templateProcessor->cloneBlock('block_name', 0, true, false, $replacements); + +The result will then be + +.. code-block:: clean + + Customer: Batman + Address: Gotham City + + Customer: Superman + Address: Metropolis + replaceBlock """""""""""" Given a template containing diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 727dd74c..704352d4 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -632,10 +632,11 @@ class TemplateProcessor * @param int $clones How many time the block should be cloned * @param bool $replace * @param bool $indexVariables If true, any variables inside the block will be indexed (postfixed with #1, #2, ...) + * @param array $variableReplacements Array containing replacements for macros found inside the block to clone * * @return string|null */ - public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false) + public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null) { $xmlBlock = null; preg_match( @@ -648,6 +649,8 @@ class TemplateProcessor $xmlBlock = $matches[3]; if ($indexVariables) { $cloned = $this->indexClonedVariables($clones, $xmlBlock); + } elseif ($variableReplacements !== null && is_array($variableReplacements)) { + $cloned = $this->replaceClonedVariables($variableReplacements, $xmlBlock); } else { $cloned = array(); for ($i = 1; $i <= $clones; $i++) { @@ -960,4 +963,26 @@ class TemplateProcessor return $results; } + + /** + * Raplaces variables with values from array, array keys are the variable names + * + * @param array $variableReplacements + * @param string $xmlBlock + * + * @return string[] + */ + protected function replaceClonedVariables($variableReplacements, $xmlBlock) + { + $results = array(); + foreach ($variableReplacements as $replacementArray) { + $localXmlBlock = $xmlBlock; + foreach ($replacementArray as $search => $replacement) { + $localXmlBlock = $this->setValueForPart(self::ensureMacroCompleted($search), $replacement, $localXmlBlock, self::MAXIMUM_REPLACEMENTS_DEFAULT); + } + $results[] = $localXmlBlock; + } + + return $results; + } } diff --git a/tests/PhpWord/TemplateProcessorTest.php b/tests/PhpWord/TemplateProcessorTest.php index 2c388299..2bca64ef 100644 --- a/tests/PhpWord/TemplateProcessorTest.php +++ b/tests/PhpWord/TemplateProcessorTest.php @@ -456,6 +456,39 @@ final class TemplateProcessorTest extends \PHPUnit\Framework\TestCase $this->assertContains('Address ${address#3}, Street ${street#3}', $templateProcessor->getMainPart()); } + public function testCloneBlockWithVariableReplacements() + { + $mainPart = ' + + + + ${CLONEME} + + + + + City: ${city}, Street: ${street} + + + + + ${/CLONEME} + + '; + + $replacements = array( + array('city' => 'London', 'street' => 'Baker Street'), + array('city' => 'New York', 'street' => '5th Avenue'), + array('city' => 'Rome', 'street' => 'Via della Conciliazione'), + ); + $templateProcessor = new TestableTemplateProcesor($mainPart); + $templateProcessor->cloneBlock('CLONEME', 0, true, false, $replacements); + + $this->assertContains('City: London, Street: Baker Street', $templateProcessor->getMainPart()); + $this->assertContains('City: New York, Street: 5th Avenue', $templateProcessor->getMainPart()); + $this->assertContains('City: Rome, Street: Via della Conciliazione', $templateProcessor->getMainPart()); + } + /** * Template macros can be fixed. *