Add support for document headers and footers to Template class.
This commit is contained in:
parent
e405bf2b71
commit
763de347df
|
|
@ -32,6 +32,13 @@ class Template
|
|||
*/
|
||||
private $_tempFileName;
|
||||
|
||||
/**
|
||||
* Document header XML
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $_headerXMLs = array();
|
||||
|
||||
/**
|
||||
* Document XML
|
||||
*
|
||||
|
|
@ -39,6 +46,12 @@ class Template
|
|||
*/
|
||||
private $_documentXML;
|
||||
|
||||
/**
|
||||
* Document footer XML
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $_footerXMLs = array();
|
||||
|
||||
/**
|
||||
* Create a new Template Object
|
||||
|
|
@ -62,9 +75,41 @@ class Template
|
|||
$this->_objZip = new $zipClass();
|
||||
$this->_objZip->open($this->_tempFileName);
|
||||
|
||||
// Find and load up to three headers and footers
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$headerName = $this->getHeaderName($i);
|
||||
$footerName = $this->getFooterName($i);
|
||||
if ($this->_objZip->locateName($headerName) !== false) {
|
||||
$this->_headerXMLs[$i] = $this->_objZip->getFromName($headerName);
|
||||
}
|
||||
if ($this->_objZip->locateName($footerName) !== false) {
|
||||
$this->_footerXMLs[$i] = $this->_objZip->getFromName($footerName);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_documentXML = $this->_objZip->getFromName('word/document.xml');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the footer file for $index
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
private function getFooterName($index)
|
||||
{
|
||||
return sprintf('word/footer%d.xml', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the header file for $index
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
private function getHeaderName($index)
|
||||
{
|
||||
return sprintf('word/header%d.xml', $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies XSL style sheet to template's parts
|
||||
*
|
||||
|
|
@ -97,20 +142,22 @@ class Template
|
|||
}
|
||||
|
||||
/**
|
||||
* Set a Template value
|
||||
* Find and replace placeholders in the given XML section.
|
||||
*
|
||||
* @param mixed $search
|
||||
* @param string $documentPartXML
|
||||
* @param string $search
|
||||
* @param mixed $replace
|
||||
* @param integer $limit
|
||||
* @return string
|
||||
*/
|
||||
public function setValue($search, $replace, $limit = -1)
|
||||
protected function setValueForPart($documentPartXML, $search, $replace, $limit)
|
||||
{
|
||||
$pattern = '|\$\{([^\}]+)\}|U';
|
||||
preg_match_all($pattern, $this->_documentXML, $matches);
|
||||
preg_match_all($pattern, $documentPartXML, $matches);
|
||||
foreach ($matches[0] as $value) {
|
||||
$valueCleaned = preg_replace('/<[^>]+>/', '', $value);
|
||||
$valueCleaned = preg_replace('/<\/[^>]+>/', '', $valueCleaned);
|
||||
$this->_documentXML = str_replace($value, $valueCleaned, $this->_documentXML);
|
||||
$documentPartXML = str_replace($value, $valueCleaned, $documentPartXML);
|
||||
}
|
||||
|
||||
if (substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
|
||||
|
|
@ -130,16 +177,58 @@ class Template
|
|||
|
||||
$regExpDelim = '/';
|
||||
$escapedSearch = preg_quote($search, $regExpDelim);
|
||||
$this->_documentXML = preg_replace("{$regExpDelim}{$escapedSearch}{$regExpDelim}u", $replace, $this->_documentXML, $limit);
|
||||
return preg_replace("{$regExpDelim}{$escapedSearch}{$regExpDelim}u", $replace, $documentPartXML, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Template value
|
||||
*
|
||||
* @param mixed $search
|
||||
* @param mixed $replace
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function setValue($search, $replace, $limit = -1)
|
||||
{
|
||||
foreach ($this->_headerXMLs as $index => $headerXML) {
|
||||
$this->_headerXMLs[$index] = $this->setValueForPart($this->_headerXMLs[$index], $search, $replace, $limit);
|
||||
}
|
||||
|
||||
$this->_documentXML = $this->setValueForPart($this->_documentXML, $search, $replace, $limit);
|
||||
|
||||
foreach ($this->_footerXMLs as $index => $headerXML) {
|
||||
$this->_footerXMLs[$index] = $this->setValueForPart($this->_footerXMLs[$index], $search, $replace, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all variables in $documentPartXML
|
||||
* @param string $documentPartXML
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getVariablesForPart($documentPartXML)
|
||||
{
|
||||
preg_match_all('/\$\{(.*?)}/i', $documentPartXML, $matches);
|
||||
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of all variables in template
|
||||
* @return string[]
|
||||
*/
|
||||
public function getVariables()
|
||||
{
|
||||
preg_match_all('/\$\{(.*?)}/i', $this->_documentXML, $matches);
|
||||
return $matches[1];
|
||||
$variables = $this->getVariablesForPart($this->_documentXML);
|
||||
|
||||
foreach ($this->_headerXMLs as $headerXML) {
|
||||
$variables = array_merge($variables, $this->getVariablesForPart($headerXML));
|
||||
}
|
||||
|
||||
foreach ($this->_footerXMLs as $footerXML) {
|
||||
$variables = array_merge($variables, $this->getVariablesForPart($footerXML));
|
||||
}
|
||||
|
||||
return array_unique($variables);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -251,8 +340,16 @@ class Template
|
|||
*/
|
||||
public function save()
|
||||
{
|
||||
foreach ($this->_headerXMLs as $index => $headerXML) {
|
||||
$this->_objZip->addFromString($this->getHeaderName($index), $this->_headerXMLs[$index]);
|
||||
}
|
||||
|
||||
$this->_objZip->addFromString('word/document.xml', $this->_documentXML);
|
||||
|
||||
foreach ($this->_footerXMLs as $index => $headerXML) {
|
||||
$this->_objZip->addFromString($this->getFooterName($index), $this->_footerXMLs[$index]);
|
||||
}
|
||||
|
||||
// Close zip file
|
||||
if ($this->_objZip->close() === false) {
|
||||
throw new Exception('Could not close zip file.');
|
||||
|
|
|
|||
|
|
@ -156,4 +156,24 @@ final class TemplateTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertEquals($expectedVar, $actualVar);
|
||||
$this->assertTrue($docFound);
|
||||
}
|
||||
|
||||
public function testVariablesCanBeReplacedInHeaderAndFooter()
|
||||
{
|
||||
$template = __DIR__ . "/_files/templates/header-footer.docx";
|
||||
$expectedVar = array('documentContent', 'headerValue', 'footerValue');
|
||||
$docName = 'header-footer-test-result.docx';
|
||||
|
||||
$document = new Template($template);
|
||||
$actualVar = $document->getVariables();
|
||||
$document->setValue('headerValue', 'Header Value');
|
||||
$document->setValue('documentContent', 'Document text.');
|
||||
$document->setValue('footerValue', 'Footer Value');
|
||||
$document->saveAs($docName);
|
||||
$docFound = file_exists($docName);
|
||||
unlink($docName);
|
||||
|
||||
$this->assertEquals($expectedVar, $actualVar);
|
||||
$this->assertTrue($docFound);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue