Forum


Replies: 1   Views: 4909
Variable2text improvement
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by lharkleroad  · 17-03-2016 - 21:29

If your document template contains variables in form elements, replacing those variables replaces the text entered into the field, but it does not replace the default value. This can cause problems if the document needs to be edited after it is created because the copied and pasted field will show the default value instead of the text that was entered into it. To preserve the text, we need to replace the default value, too.

To fix this, variable2Text can be modified as follows:

1. Change the xpath query to include form field default values.

$query = '//w:default[@w:val[contains(.,"' . $search . '")]]|//w:t[text()[contains(., "' . $search . '")]]';

2. Set the defalut value if the attribute exists in your matching node. Otherwise, replace the node's text value as usual.

if (!empty($node->attributes('w', TRUE)->val)) {
        $node->attributes('w', TRUE)->val = $val;
} else {
        $strNode = str_replace($search, $val, $strNode);
        $node[0] = $strNode;
}

Here is the complete method with the above modifications.

    private function variable2Text($variables, $loadContent, $options)
    {
        if (isset($options['firstMatch'])) {
            $firstMatch = $options['firstMatch'];
        } else {
            $firstMatch = false;
        }
        if (!self::$_preprocessed) {
            $loadContent = $this->repairVariables($variables, $loadContent);
        }
        $dom = simplexml_load_string($loadContent);
        $dom->registerXPathNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
        foreach ($variables as $var => $val) {
            $search = self::$_templateSymbol . $var . self::$_templateSymbol;
            $query = '//w:default[@w:val[contains(.,"' . $search . '")]]|//w:t[text()[contains(., "' . $search . '")]]';
            if ($firstMatch) {
                $query = '(' . $query . ')[1]';
            }
            $foundNodes = $dom->xpath($query);
            foreach ($foundNodes as $node) {
                $strNode = (string) $node;
                if (isset($options['parseLineBreaks']) && $options['parseLineBreaks']) {
                    $domNode = dom_import_simplexml($node);
                    //parse $val for \n\r, \r\n, \n or \r
                    $val = str_replace(array('\n\r', '\r\n', '\n', '\r'), '<linebreak/>', $val);
                    $strNode = str_replace($search, $val, $strNode);
                    $runs = explode('<linebreak/>', $strNode);
                    $preserveWS = false;
                    $preserveWhiteSpace = $domNode->getAttribute('xml:space');
                    if ($preserveWhiteSpace == 'preserve') {
                        $preserveWS = true;
                    }
                    //TODO: check and finish
                    $numberOfRuns = count($runs);
                    $counter = 0;
                    foreach ($runs as $run) {
                        $counter++;
                        $newT = $domNode->ownerDocument->createElementNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 't', htmlspecialchars($run));
                        if ($preserveWS) {
                            $newT->setAttribute('xml:space', 'preserve');
                        }
                        $domNode->parentNode->insertBefore($newT, $domNode);
                        if ($counter < $numberOfRuns) {
                            $br = $domNode->ownerDocument->createElementNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'br');
                            $domNode->parentNode->insertBefore($br, $domNode);
                        }
                    }
                    $domNode->parentNode->removeChild($domNode);
                } else {
                    if (!empty($node->attributes('w', TRUE)->val)) {
                        $node->attributes('w', TRUE)->val = $val;
                    } else {
                        $strNode = str_replace($search, $val, $strNode);
                        $node[0] = $strNode;
                    }
                }
            }
        }

        return $dom;
    }