Forum


Replies: 0   Views: 1471
Multi search and replace function...
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 criptos  · 29-05-2017 - 19:26

I needed to create a funciton to replace multiple texts. 

I used the search and replace function as base (actually I added  4 lines...) and created a funcion called 

multiSearchAndReplace, the function recives an array in the form 

array("text to replace"=>"replacement"); 

If is useful to anybody.

File DocxUtilitines.inc

 

  /**
     * This is the method that does all the needed manipulation to search
     * and replace multiples text in a Word document
     * @access public
     * @param string $document path to the document
     * @param string $finalDocument path to the resulting document
     * @param array  $searchAndReplace associative array where the key is the text to search and the value is the text to replace
     * @param array $options
     * Values: document (boolean), endnotes (boolean), footnotes (boolean), comments (boolean)
     * headerAndFooters (boolean)
     * @return void
     */
    public function multiSearchAndReplace($document, $finalDocument, $searchAndReplace,  $options = array('document' => true))
    {

        $this->_docx = new ZipArchive();
        $this->_documentXML = '';
        $this->_footnotesXML = '';
        $this->_endnotesXML = '';
        $this->_commentsXML = '';
        $this->_commentsDOM = new DOMDocument();
        $this->_documentDOM = new DOMDocument();
        $this->_endnotesDOM = new DOMDocument();
        $this->_footnotesDOM = new DOMDocument();
        $this->_relsDOM = new DOMDocument();
        //if search and replace isn't an array, we do nothing...
        if(sizeof($rawSearchAndReplace)==0)
        return; 

        //we make a copy of the the document into its final destination so we do not overwrite it
        copy($document, $finalDocument);
        //we extract (some) of the relevant files of the copy of the first document for manipulation
        $this->_docx->open($finalDocument);

        if (isset($options['document']) && $options['document'] == true) {
            $this->_documentXML = $this->_docx->getFromName('word/document.xml');
            $optionEntityLoader = libxml_disable_entity_loader(true);
            $this->_documentDOM->loadXML($this->_documentXML);
            libxml_disable_entity_loader($optionEntityLoader);
            //We prepare the document for XPath
            $this->_documentXPath = new DOMXPath($this->_documentDOM);
            $this->_documentXPath->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
            $this->searchToReplace($this->_documentXPath, $searchTerm, $replaceTerm);
            $newDocumentXML = $this->_documentDOM->saveXML();
            $this->_docx->addFromString('word/document.xml', $newDocumentXML);
        }
        if (isset($options['footnotes']) && $options['footnotes'] == true) {
            $this->_footnotesXML = $this->_docx->getFromName('word/footnotes.xml');
            if ($this->_footnotesXML !== false) {
                $optionEntityLoader = libxml_disable_entity_loader(true);
                $this->_footnotesDOM->loadXML($this->_footnotesXML);
                libxml_disable_entity_loader($optionEntityLoader);
                //We prepare the document for XPath
                $this->_footnotesXPath = new DOMXPath($this->_footnotesDOM);
                $this->_footnotesXPath->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
                $this->searchToReplace($this->_footnotesXPath, $searchTerm, $replaceTerm);
                $newFootnotesXML = $this->_footnotesDOM->saveXML();
                $this->_docx->addFromString('word/footnotes.xml', $newFootnotesXML);
            }
        }
        if (isset($options['endnotes']) && $options['endnotes'] == true) {
            $this->_endnotesXML = $this->_docx->getFromName('word/endnotes.xml');
            if ($this->_endnotesXML !== false) {
                $optionEntityLoader = libxml_disable_entity_loader(true);
                $this->_endnotesDOM->loadXML($this->_endnotesXML);
                libxml_disable_entity_loader($optionEntityLoader);
                //We prepare the document for XPath
                $this->_endnotesXPath = new DOMXPath($this->_endnotesDOM);
                $this->_endnotesXPath->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
                $this->searchToReplace($this->_endnotesXPath, $searchTerm, $replaceTerm);
                $newEndnotesXML = $this->_endnotesDOM->saveXML();
                $this->_docx->addFromString('word/endnotes.xml', $newEndnotesXML);
            }
        }
        if (isset($options['comments']) && $options['comments'] == true) {
            $this->_commentsXML = $this->_docx->getFromName('word/comments.xml');
            if ($this->_commentsXML !== false) {
                $optionEntityLoader = libxml_disable_entity_loader(true);
                $this->_commentsDOM->loadXML($this->_commentsXML);
                libxml_disable_entity_loader($optionEntityLoader);
                //We prepare the document for XPath
                $this->_commentsXPath = new DOMXPath($this->_commentsDOM);
                $this->_commentsXPath->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
                $this->searchToReplace($this->_commentsXPath, $searchTerm, $replaceTerm);
                $newCommentsXML = $this->_commentsDOM->saveXML();
                $this->_docx->addFromString('word/comments.xml', $newCommentsXML);
            }
        }
        if (isset($options['headersAndFooters']) && $options['headersAndFooters'] == true) {
            $this->_relsXML = $this->_docx->getFromName('word/_rels/document.xml.rels');
            $this->_relsDOM->preserveWhiteSpace = false;
            $optionEntityLoader = libxml_disable_entity_loader(true);
            $this->_relsDOM->loadXML($this->_relsXML);
            libxml_disable_entity_loader($optionEntityLoader);
            $relsNodes = $this->_relsDOM->documentElement->childNodes;
            $headersAndFooters = array();
            foreach ($relsNodes as $node) {
                if ($node->getAttribute('Type') == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer' ||
                        $node->getAttribute('Type') == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/header') {
                    $headersAndFooters[] = $node->getAttribute('Target');
                }
            }
            $this->_headersAndFootersXML = array();
            $this->_headersAndFootersDOM = array();
            $this->_headersAndFootersXPath = array();
            for ($k = 0; $k < count($headersAndFooters); $k++) {
                $this->_headersAndFootersXML[$k] = $this->_docx->getFromName('word/' . $headersAndFooters[$k]);
                $this->_headersAndFootersDOM[$k] = new DOMDocument();
                $optionEntityLoader = libxml_disable_entity_loader(true);
                $this->_headersAndFootersDOM[$k]->loadXML($this->_headersAndFootersXML[$k]);
                libxml_disable_entity_loader($optionEntityLoader);
                //We prepare the document for XPath
                $this->_headersAndFootersXPath[$k] = new DOMXPath($this->_headersAndFootersDOM[$k]);
                $this->_headersAndFootersXPath[$k]->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
                foreach($sarchAndReplace as $st => $rt)
                $this->searchToReplace($this->_headersAndFootersXPath[$k], $st, $rt);
                $newXML = $this->_headersAndFootersDOM[$k]->saveXML();
                $this->_docx->addFromString('word/' . $headersAndFooters[$k], $newXML);
            }
        }


        //we finally close the zip file
        $this->_docx->close();
    }