Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clone block issue #1855

Closed
5b6santhosh opened this issue Apr 24, 2020 · 6 comments
Closed

Clone block issue #1855

5b6santhosh opened this issue Apr 24, 2020 · 6 comments

Comments

@5b6santhosh
Copy link

clone block not working when adding more content after the clone block please help
${test}
${v1}
${/test}
after adding text its not working
its depending on character

@cedrictailly
Copy link

Hi, you should take a look at my ticket because I have the same problem : #1836

I've just posted a rewrite of the function which bypasses the issue for my cases.

@5b6santhosh
Copy link
Author

5b6santhosh commented May 8, 2020

phpword when character length add more clone block not working after this loop adding content its not worked any one solved this please help

@5b6santhosh
Copy link
Author

Hi, you should take a look at my ticket because I have the same problem : #1836
I've just posted a rewrite of the function which bypasses the issue for my cases.

hi got issue resolved

please replace below code
in template preprocessor
/**
* Clone a block.
*
* @param string $blockname
* @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, $variableReplacements = null)
{
$xmlBlock = null;

    $matches = array();
    list($matches[1],$matches[2],$matches[3]) = $this->getBlocks($blockname);
    if (isset($matches[2])&&$matches[2]) {
        
        $xmlBlock = $matches[2];
        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++) {
                $cloned[] = $xmlBlock;
            }
        }

        if ($replace) {
            $this->tempDocumentMainPart = str_replace(
                $matches[1] . $matches[2] . $matches[3],
                implode('', $cloned),
                $this->tempDocumentMainPart
            );
        }
    }

    return $xmlBlock;
}
/**
* Get part of block for cloneBlock
*
* @param string $blockName Block name to clone
*
* @return array
*/
private function getBlocks($blockName){
    $dataXML = $this->tempDocumentMainPart;
    if(stripos($dataXML,'{'.$blockName.'}') && stripos($dataXML,'{/'.$blockName.'}')){
        $startBlock1 = strrpos(substr($dataXML,0,stripos($dataXML,'{'.$blockName.'}')), '<w:p ');
        $lengthBlock1 = (stripos(substr($dataXML,$startBlock1),'p>')+2);
        $block1 = substr($dataXML,$startBlock1,$lengthBlock1);
        $startBlock3 = strrpos(substr($dataXML,0,stripos($dataXML,'{/'.$blockName.'}')), '<w:p ');
        $lengthBlock3 = (stripos(substr($dataXML,$startBlock3),'p>')+2);
        $block3 = substr($dataXML,$startBlock3,$lengthBlock3);
        $block2 = substr($dataXML,$startBlock1+$lengthBlock1,$startBlock3-($startBlock1+$lengthBlock1));
        return array($block1, $block2, $block3);
    }
    return array(0,0,0);
}

@silver247
Copy link

Hi, you should take a look at my ticket because I have the same problem : #1836
I've just posted a rewrite of the function which bypasses the issue for my cases.

hi got issue resolved

please replace below code
in template preprocessor
/**

  • Clone a block.
  • @param string $blockname
  • @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 Implement RTF Writer #1, Implement ODT Writer #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, $variableReplacements = null)
    {
    $xmlBlock = null;
    $matches = array();
    list($matches[1],$matches[2],$matches[3]) = $this->getBlocks($blockname);
    if (isset($matches[2])&&$matches[2]) {
        
        $xmlBlock = $matches[2];
        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++) {
                $cloned[] = $xmlBlock;
            }
        }

        if ($replace) {
            $this->tempDocumentMainPart = str_replace(
                $matches[1] . $matches[2] . $matches[3],
                implode('', $cloned),
                $this->tempDocumentMainPart
            );
        }
    }

    return $xmlBlock;
}
/**
* Get part of block for cloneBlock
*
* @param string $blockName Block name to clone
*
* @return array
*/
private function getBlocks($blockName){
    $dataXML = $this->tempDocumentMainPart;
    if(stripos($dataXML,'{'.$blockName.'}') && stripos($dataXML,'{/'.$blockName.'}')){
        $startBlock1 = strrpos(substr($dataXML,0,stripos($dataXML,'{'.$blockName.'}')), '<w:p ');
        $lengthBlock1 = (stripos(substr($dataXML,$startBlock1),'p>')+2);
        $block1 = substr($dataXML,$startBlock1,$lengthBlock1);
        $startBlock3 = strrpos(substr($dataXML,0,stripos($dataXML,'{/'.$blockName.'}')), '<w:p ');
        $lengthBlock3 = (stripos(substr($dataXML,$startBlock3),'p>')+2);
        $block3 = substr($dataXML,$startBlock3,$lengthBlock3);
        $block2 = substr($dataXML,$startBlock1+$lengthBlock1,$startBlock3-($startBlock1+$lengthBlock1));
        return array($block1, $block2, $block3);
    }
    return array(0,0,0);
}

In case you guys don't want to modify the original file, just write an extension

`use PhpOffice\PhpWord\TemplateProcessor;
class TemplateProcesserExtension extends TemplateProcessor {

//put your code here

public function __construct($documentTemplate) {
    parent::__construct($documentTemplate);
}
public function cloneBlockNew($blockname, $clones = 1, $replace = true, $indexVariables = false, $variableReplacements = null) {
    $xmlBlock = null;
    $matches = array();
    list($matches[1], $matches[2], $matches[3]) = $this->getBlocks($blockname);
    if (isset($matches[2]) && $matches[2]) {

        $xmlBlock = $matches[2];
        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++) {
                $cloned[] = $xmlBlock;
            }
        }

        if ($replace) {
            $this->tempDocumentMainPart = str_replace(
                    $matches[1] . $matches[2] . $matches[3],
                    implode('', $cloned),
                    $this->tempDocumentMainPart
            );
        }
    }

    return $xmlBlock;
}

/**
 * Get part of block for cloneBlock
 *
 * @param string $blockName Block name to clone
 *
 * @return array
 */
private function getBlocks($blockName) {
    $dataXML = $this->tempDocumentMainPart;
    if (stripos($dataXML, '{' . $blockName . '}') && stripos($dataXML, '{/' . $blockName . '}')) {
        $startBlock1 = strrpos(substr($dataXML, 0, stripos($dataXML, '{' . $blockName . '}')), '<w:p ');
        $lengthBlock1 = (stripos(substr($dataXML, $startBlock1), 'p>') + 2);
        $block1 = substr($dataXML, $startBlock1, $lengthBlock1);
        $startBlock3 = strrpos(substr($dataXML, 0, stripos($dataXML, '{/' . $blockName . '}')), '<w:p ');
        $lengthBlock3 = (stripos(substr($dataXML, $startBlock3), 'p>') + 2);
        $block3 = substr($dataXML, $startBlock3, $lengthBlock3);
        $block2 = substr($dataXML, $startBlock1 + $lengthBlock1, $startBlock3 - ($startBlock1 + $lengthBlock1));
        return array($block1, $block2, $block3);
    }
    return array(0, 0, 0);
}

}`

And use by

`
use TemplateProcesserExtension;
public function generateDocumentFromTemplate($document) {
$templateProcessor = new TemplateProcesserExtension('path to template');

        $templateProcessor->setValue('variable name', 'some value'); //Original PHPWord Method
        
        $block_replacements = $replacement_data;
        $templateProcessor->cloneBlockNew('block_name', 0, true, false, $block_replacements); //Extension Method

}`

@5b6santhosh
Copy link
Author

5b6santhosh commented Jun 17, 2020 via email

@ghost
Copy link

ghost commented Aug 15, 2023

But it's not complete. It's 2023 and this is still an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants