PHPWord/tests/PhpWord/TemplateProcessorTest.php

215 lines
7.7 KiB
PHP

<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @link https://github.com/PHPOffice/PHPWord
* @copyright 2010-2015 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord;
/**
* @covers \PhpOffice\PhpWord\TemplateProcessor
* @coversDefaultClass \PhpOffice\PhpWord\TemplateProcessor
* @runTestsInSeparateProcesses
*/
final class TemplateProcessorTest extends \PHPUnit_Framework_TestCase
{
/**
* Template can be saved in temporary location.
*
* @covers ::save
* @test
*/
final public function testTemplateCanBeSavedInTemporaryLocation()
{
$templateFqfn = __DIR__ . '/_files/templates/with_table_macros.docx';
$templateProcessor = new TemplateProcessor($templateFqfn);
$xslDOMDocument = new \DOMDocument();
$xslDOMDocument->load(__DIR__ . "/_files/xsl/remove_tables_by_needle.xsl");
foreach (array('${employee.', '${scoreboard.') as $needle) {
$templateProcessor->applyXslStyleSheet($xslDOMDocument, array('needle' => $needle));
}
$documentFqfn = $templateProcessor->save();
$this->assertNotEmpty($documentFqfn, 'FQFN of the saved document is empty.');
$this->assertFileExists($documentFqfn, "The saved document \"{$documentFqfn}\" doesn't exist.");
$templateZip = new \ZipArchive();
$templateZip->open($templateFqfn);
$templateXml = $templateZip->getFromName('word/document.xml');
if (false === $templateZip->close()) {
throw new \Exception("Could not close zip file \"{$templateZip}\".");
}
$documentZip = new \ZipArchive();
$documentZip->open($documentFqfn);
$documentXml = $documentZip->getFromName('word/document.xml');
if (false === $documentZip->close()) {
throw new \Exception("Could not close zip file \"{$documentZip}\".");
}
$this->assertNotEquals($documentXml, $templateXml);
return $documentFqfn;
}
/**
* XSL stylesheet can be applied.
*
* @test
* @covers ::applyXslStyleSheet
* @depends testTemplateCanBeSavedInTemporaryLocation
*
* @param string $actualDocumentFqfn
*
* @throws \Exception
*/
final public function testXslStyleSheetCanBeApplied($actualDocumentFqfn)
{
$expectedDocumentFqfn = __DIR__ . '/_files/documents/without_table_macros.docx';
$actualDocumentZip = new \ZipArchive();
$actualDocumentZip->open($actualDocumentFqfn);
$actualDocumentXml = $actualDocumentZip->getFromName('word/document.xml');
if (false === $actualDocumentZip->close()) {
throw new \Exception("Could not close zip file \"{$actualDocumentFqfn}\".");
}
$expectedDocumentZip = new \ZipArchive();
$expectedDocumentZip->open($expectedDocumentFqfn);
$expectedDocumentXml = $expectedDocumentZip->getFromName('word/document.xml');
if (false === $expectedDocumentZip->close()) {
throw new \Exception("Could not close zip file \"{$expectedDocumentFqfn}\".");
}
$this->assertXmlStringEqualsXmlString($expectedDocumentXml, $actualDocumentXml);
}
/**
* XSL stylesheet cannot be applied on failure in setting parameter value.
*
* @covers ::applyXslStyleSheet
* @expectedException \PhpOffice\PhpWord\Exception\Exception
* @expectedExceptionMessage Could not set values for the given XSL style sheet parameters.
* @test
*/
final public function testXslStyleSheetCanNotBeAppliedOnFailureOfSettingParameterValue()
{
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
$xslDOMDocument = new \DOMDocument();
$xslDOMDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
/*
* We have to use error control below, because \XSLTProcessor::setParameter omits warning on failure.
* This warning fails the test.
*/
@$templateProcessor->applyXslStyleSheet($xslDOMDocument, array(1 => 'somevalue'));
}
/**
* XSL stylesheet can be applied on failure of loading XML from template.
*
* @covers ::applyXslStyleSheet
* @expectedException \PhpOffice\PhpWord\Exception\Exception
* @expectedExceptionMessage Could not load XML from the given template.
* @test
*/
final public function testXslStyleSheetCanNotBeAppliedOnFailureOfLoadingXmlFromTemplate()
{
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/corrupted_main_document_part.docx');
$xslDOMDocument = new \DOMDocument();
$xslDOMDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
/*
* We have to use error control below, because \DOMDocument::loadXML omits warning on failure.
* This warning fails the test.
*/
@$templateProcessor->applyXslStyleSheet($xslDOMDocument);
}
/**
* @covers ::setValue
* @covers ::cloneRow
* @covers ::saveAs
* @test
*/
public function testCloneRow()
{
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx');
$this->assertEquals(
array('tableHeader', 'userId', 'userName', 'userLocation'),
$templateProcessor->getVariables()
);
$docName = 'clone-test-result.docx';
$templateProcessor->setValue('tableHeader', utf8_decode('ééé'));
$templateProcessor->cloneRow('userId', 1);
$templateProcessor->setValue('userId#1', 'Test');
$templateProcessor->saveAs($docName);
$docFound = file_exists($docName);
unlink($docName);
$this->assertTrue($docFound);
}
/**
* @covers ::setValue
* @covers ::saveAs
* @test
*/
public function testMacrosCanBeReplacedInHeaderAndFooter()
{
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx');
$this->assertEquals(array('documentContent', 'headerValue', 'footerValue'), $templateProcessor->getVariables());
$macroNames = array('headerValue', 'documentContent', 'footerValue');
$macroValues = array('Header Value', 'Document text.', 'Footer Value');
$templateProcessor->setValue($macroNames, $macroValues);
$docName = 'header-footer-test-result.docx';
$templateProcessor->saveAs($docName);
$docFound = file_exists($docName);
unlink($docName);
$this->assertTrue($docFound);
}
/**
* @covers ::cloneBlock
* @covers ::deleteBlock
* @covers ::saveAs
* @test
*/
public function testCloneDeleteBlock()
{
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-delete-block.docx');
$this->assertEquals(
array('DELETEME', '/DELETEME', 'CLONEME', '/CLONEME'),
$templateProcessor->getVariables()
);
$docName = 'clone-delete-block-result.docx';
$templateProcessor->cloneBlock('CLONEME', 3);
$templateProcessor->deleteBlock('DELETEME');
$templateProcessor->saveAs($docName);
$docFound = file_exists($docName);
unlink($docName);
$this->assertTrue($docFound);
}
}