Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save mattimatti/9849d658237055878d4d92de0ea6da39 to your computer and use it in GitHub Desktop.

Select an option

Save mattimatti/9849d658237055878d4d92de0ea6da39 to your computer and use it in GitHub Desktop.
PHPOffice/PHPWord - Injecting AltChunks in word document using placeholders in template file
<?php namespace My\Namespace;
use DOMDocument;
use Parsedown;
use PhpOffice\PhpWord\TemplateProcessor as PhpWordTemplateProcessor;
class TemplateProcessor extends PhpWordTemplateProcessor
{
/**
* Injects a markdown snippet as HTML into the word document.
*
* @param string $search Template placeholder to replace
* @param string $markdown
* @return string
*/
public function replaceMarkdown($search, $markdown)
{
$parsedown = new Parsedown;
$contents = '<html><head /><body>' .
$parsedown->text($markdown)
. '</body></html>'
;
$this->registerAltChunk(
$search,
'word/' . $search . '.dat',
$contents
);
}
/**
* Registers an altChunk in the document.
*
* @param string $search Template placeholder
* @param string $target Base filename target added to archive
* @param string $contents HTML content to add to document
* @param string $type OOXML AltChunk Content Type
*/
private function registerAltChunk($search, $target, $contents, $type = 'text/html')
{
$id = 'alt_' . $search;
$this->zipClass->addFromString($target, $contents);
parent::setValue($search, '<w:altChunk r:id="' . $id . '" />');
$this
->registerContentTypeOverride($target, $type)
->registerRelationship(
$id,
$target,
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk'
)
;
// Close/Reopen ziparchive so subsequent reads will see these writes
// Probably a better way to do this.
$this->zipClass->close();
$this->zipClass->open($this->tempDocumentFilename);
}
/**
* Registers a content type override in the document in [Content_Types].xml
*
* @param string $target
* @param string $type
*/
private function registerContentTypeOverride($target, $type)
{
$contentTypes = new DOMDocument;
$contentTypes->loadXML( $this->zipClass->getFromName('[Content_Types].xml') );
$node = $contentTypes->createElement('Override');
$node->setAttribute('PartName', '/' . $target);
$node->setAttribute('ContentType', $type);
$root = $contentTypes->getElementsByTagName('Types')->item(0);
$root->appendChild($node);
$this->zipClass->addFromString('[Content_Types].xml', $contentTypes->saveXML());
return $this;
}
/**
* Registers a relationship to the main document part.
*
* @param string $id The main document ID attribute
* @param string $target Filename target inside of the archive
* @param string $type Type to register the relationship as
*/
private function registerRelationship($id, $target, $type)
{
$relationships = new DOMDocument;
$relationships->loadXML($this->zipClass->getFromName('word/_rels/document.xml.rels'));
$node = $relationships->createElement('Relationship');
$node->setAttribute('Id', $id);
$node->setAttribute('Type', $type);
$node->setAttribute('Target', '/' . $target);
$root = $relationships->getElementsByTagName('Relationships')->item(0);
$root->appendChild($node);
$this->zipClass->addFromString('word/_rels/document.xml.rels', $relationships->saveXML());
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment