2014-03-02 19:52:21 +04:00
|
|
|
<?php
|
2014-03-27 23:55:06 +07:00
|
|
|
/**
|
2014-05-05 13:06:53 +04:00
|
|
|
* 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.
|
2014-03-27 23:55:06 +07:00
|
|
|
*
|
2017-11-04 22:44:12 +01:00
|
|
|
* @see https://github.com/PHPOffice/PHPWord
|
|
|
|
|
* @copyright 2010-2017 PHPWord contributors
|
2014-05-04 21:03:28 +04:00
|
|
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
|
2014-03-27 23:55:06 +07:00
|
|
|
*/
|
|
|
|
|
|
2015-11-15 13:33:05 +04:00
|
|
|
namespace PhpOffice\PhpWord;
|
2014-03-02 19:52:21 +04:00
|
|
|
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* @covers \PhpOffice\PhpWord\TemplateProcessor
|
|
|
|
|
* @coversDefaultClass \PhpOffice\PhpWord\TemplateProcessor
|
2014-03-27 23:55:06 +07:00
|
|
|
* @runTestsInSeparateProcesses
|
2014-03-02 19:52:21 +04:00
|
|
|
*/
|
2014-08-16 15:21:58 +04:00
|
|
|
final class TemplateProcessorTest extends \PHPUnit_Framework_TestCase
|
2014-03-02 19:52:21 +04:00
|
|
|
{
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* Template can be saved in temporary location.
|
2014-03-28 13:50:53 +07:00
|
|
|
*
|
2014-03-12 20:09:10 +04:00
|
|
|
* @covers ::save
|
2014-03-02 19:52:21 +04:00
|
|
|
* @test
|
|
|
|
|
*/
|
2014-03-12 20:09:10 +04:00
|
|
|
final public function testTemplateCanBeSavedInTemporaryLocation()
|
2014-03-02 19:52:21 +04:00
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateFqfn = __DIR__ . '/_files/templates/with_table_macros.docx';
|
2014-03-02 14:40:58 -05:00
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor($templateFqfn);
|
2016-07-30 16:02:23 +04:00
|
|
|
$xslDomDocument = new \DOMDocument();
|
2017-11-04 22:44:12 +01:00
|
|
|
$xslDomDocument->load(__DIR__ . '/_files/xsl/remove_tables_by_needle.xsl');
|
2016-07-30 16:02:23 +04:00
|
|
|
foreach (array('${employee.', '${scoreboard.', '${reference.') as $needle) {
|
|
|
|
|
$templateProcessor->applyXslStyleSheet($xslDomDocument, array('needle' => $needle));
|
2014-03-12 20:09:10 +04:00
|
|
|
}
|
|
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$documentFqfn = $templateProcessor->save();
|
2014-03-12 20:09:10 +04:00
|
|
|
|
|
|
|
|
$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);
|
2016-07-30 16:02:23 +04:00
|
|
|
$templateHeaderXml = $templateZip->getFromName('word/header1.xml');
|
|
|
|
|
$templateMainPartXml = $templateZip->getFromName('word/document.xml');
|
|
|
|
|
$templateFooterXml = $templateZip->getFromName('word/footer1.xml');
|
2015-02-06 22:28:31 +04:00
|
|
|
if (false === $templateZip->close()) {
|
2014-03-12 20:09:10 +04:00
|
|
|
throw new \Exception("Could not close zip file \"{$templateZip}\".");
|
2014-03-07 17:47:23 +04:00
|
|
|
}
|
2014-03-02 14:40:58 -05:00
|
|
|
|
2014-03-12 20:09:10 +04:00
|
|
|
$documentZip = new \ZipArchive();
|
|
|
|
|
$documentZip->open($documentFqfn);
|
2016-07-30 16:02:23 +04:00
|
|
|
$documentHeaderXml = $documentZip->getFromName('word/header1.xml');
|
|
|
|
|
$documentMainPartXml = $documentZip->getFromName('word/document.xml');
|
|
|
|
|
$documentFooterXml = $documentZip->getFromName('word/footer1.xml');
|
2015-02-06 22:28:31 +04:00
|
|
|
if (false === $documentZip->close()) {
|
2014-03-12 20:09:10 +04:00
|
|
|
throw new \Exception("Could not close zip file \"{$documentZip}\".");
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-30 16:02:23 +04:00
|
|
|
$this->assertNotEquals($templateHeaderXml, $documentHeaderXml);
|
|
|
|
|
$this->assertNotEquals($templateMainPartXml, $documentMainPartXml);
|
|
|
|
|
$this->assertNotEquals($templateFooterXml, $documentFooterXml);
|
2014-03-12 20:09:10 +04:00
|
|
|
|
2014-03-12 20:40:29 +04:00
|
|
|
return $documentFqfn;
|
2014-03-12 20:09:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* XSL stylesheet can be applied.
|
2014-03-28 13:50:53 +07:00
|
|
|
*
|
2015-10-10 19:06:23 +04:00
|
|
|
* @test
|
2014-03-12 20:09:10 +04:00
|
|
|
* @covers ::applyXslStyleSheet
|
|
|
|
|
* @depends testTemplateCanBeSavedInTemporaryLocation
|
2015-10-10 19:06:23 +04:00
|
|
|
*
|
|
|
|
|
* @param string $actualDocumentFqfn
|
|
|
|
|
*
|
|
|
|
|
* @throws \Exception
|
2014-03-12 20:09:10 +04:00
|
|
|
*/
|
2014-03-12 20:40:29 +04:00
|
|
|
final public function testXslStyleSheetCanBeApplied($actualDocumentFqfn)
|
2014-03-12 20:09:10 +04:00
|
|
|
{
|
2015-02-06 22:28:31 +04:00
|
|
|
$expectedDocumentFqfn = __DIR__ . '/_files/documents/without_table_macros.docx';
|
2014-03-02 14:40:58 -05:00
|
|
|
|
2014-03-12 20:40:29 +04:00
|
|
|
$actualDocumentZip = new \ZipArchive();
|
|
|
|
|
$actualDocumentZip->open($actualDocumentFqfn);
|
2016-07-30 16:02:23 +04:00
|
|
|
$actualHeaderXml = $actualDocumentZip->getFromName('word/header1.xml');
|
|
|
|
|
$actualMainPartXml = $actualDocumentZip->getFromName('word/document.xml');
|
|
|
|
|
$actualFooterXml = $actualDocumentZip->getFromName('word/footer1.xml');
|
2015-02-06 22:28:31 +04:00
|
|
|
if (false === $actualDocumentZip->close()) {
|
2014-03-12 20:40:29 +04:00
|
|
|
throw new \Exception("Could not close zip file \"{$actualDocumentFqfn}\".");
|
2014-03-07 17:47:23 +04:00
|
|
|
}
|
2014-03-02 14:40:58 -05:00
|
|
|
|
2014-03-12 20:40:29 +04:00
|
|
|
$expectedDocumentZip = new \ZipArchive();
|
|
|
|
|
$expectedDocumentZip->open($expectedDocumentFqfn);
|
2016-07-30 16:02:23 +04:00
|
|
|
$expectedHeaderXml = $expectedDocumentZip->getFromName('word/header1.xml');
|
|
|
|
|
$expectedMainPartXml = $expectedDocumentZip->getFromName('word/document.xml');
|
|
|
|
|
$expectedFooterXml = $expectedDocumentZip->getFromName('word/footer1.xml');
|
2015-02-06 22:28:31 +04:00
|
|
|
if (false === $expectedDocumentZip->close()) {
|
2014-03-12 20:40:29 +04:00
|
|
|
throw new \Exception("Could not close zip file \"{$expectedDocumentFqfn}\".");
|
2014-03-07 17:47:23 +04:00
|
|
|
}
|
2014-03-02 14:40:58 -05:00
|
|
|
|
2016-07-30 16:02:23 +04:00
|
|
|
$this->assertXmlStringEqualsXmlString($expectedHeaderXml, $actualHeaderXml);
|
|
|
|
|
$this->assertXmlStringEqualsXmlString($expectedMainPartXml, $actualMainPartXml);
|
|
|
|
|
$this->assertXmlStringEqualsXmlString($expectedFooterXml, $actualFooterXml);
|
2014-03-02 19:52:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* XSL stylesheet cannot be applied on failure in setting parameter value.
|
2014-03-28 13:50:53 +07:00
|
|
|
*
|
2014-03-02 19:52:21 +04:00
|
|
|
* @covers ::applyXslStyleSheet
|
2014-03-31 01:13:02 +07:00
|
|
|
* @expectedException \PhpOffice\PhpWord\Exception\Exception
|
2014-03-02 19:52:21 +04:00
|
|
|
* @expectedExceptionMessage Could not set values for the given XSL style sheet parameters.
|
|
|
|
|
* @test
|
|
|
|
|
*/
|
2014-03-03 17:03:09 +04:00
|
|
|
final public function testXslStyleSheetCanNotBeAppliedOnFailureOfSettingParameterValue()
|
2014-03-02 19:52:21 +04:00
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
|
2014-03-02 19:52:21 +04:00
|
|
|
|
2016-07-30 16:02:23 +04:00
|
|
|
$xslDomDocument = new \DOMDocument();
|
|
|
|
|
$xslDomDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
|
2014-03-02 19:52:21 +04:00
|
|
|
|
2014-03-04 14:36:39 +04:00
|
|
|
/*
|
2014-03-23 10:32:08 +04:00
|
|
|
* We have to use error control below, because \XSLTProcessor::setParameter omits warning on failure.
|
2014-03-04 14:36:39 +04:00
|
|
|
* This warning fails the test.
|
|
|
|
|
*/
|
2016-07-30 16:02:23 +04:00
|
|
|
@$templateProcessor->applyXslStyleSheet($xslDomDocument, array(1 => 'somevalue'));
|
2014-03-02 19:52:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* XSL stylesheet can be applied on failure of loading XML from template.
|
2014-03-28 13:50:53 +07:00
|
|
|
*
|
2014-03-02 19:52:21 +04:00
|
|
|
* @covers ::applyXslStyleSheet
|
2014-03-31 01:13:02 +07:00
|
|
|
* @expectedException \PhpOffice\PhpWord\Exception\Exception
|
2016-07-30 16:02:23 +04:00
|
|
|
* @expectedExceptionMessage Could not load the given XML document.
|
2014-03-02 19:52:21 +04:00
|
|
|
* @test
|
|
|
|
|
*/
|
2014-03-03 16:53:00 +04:00
|
|
|
final public function testXslStyleSheetCanNotBeAppliedOnFailureOfLoadingXmlFromTemplate()
|
2014-03-02 19:52:21 +04:00
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/corrupted_main_document_part.docx');
|
2014-03-02 19:52:21 +04:00
|
|
|
|
2016-07-30 16:02:23 +04:00
|
|
|
$xslDomDocument = new \DOMDocument();
|
|
|
|
|
$xslDomDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
|
2014-03-02 19:52:21 +04:00
|
|
|
|
2014-03-04 14:36:39 +04:00
|
|
|
/*
|
2014-03-23 10:32:08 +04:00
|
|
|
* We have to use error control below, because \DOMDocument::loadXML omits warning on failure.
|
2014-03-04 14:36:39 +04:00
|
|
|
* This warning fails the test.
|
|
|
|
|
*/
|
2016-07-30 16:02:23 +04:00
|
|
|
@$templateProcessor->applyXslStyleSheet($xslDomDocument);
|
2014-03-02 19:52:21 +04:00
|
|
|
}
|
2014-03-15 13:25:42 +07:00
|
|
|
|
|
|
|
|
/**
|
2016-01-23 21:35:04 +04:00
|
|
|
* @covers ::setValue
|
2014-08-16 15:21:58 +04:00
|
|
|
* @covers ::cloneRow
|
|
|
|
|
* @covers ::saveAs
|
|
|
|
|
* @test
|
2014-03-15 13:25:42 +07:00
|
|
|
*/
|
|
|
|
|
public function testCloneRow()
|
|
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx');
|
2014-03-15 13:25:42 +07:00
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$this->assertEquals(
|
|
|
|
|
array('tableHeader', 'userId', 'userName', 'userLocation'),
|
|
|
|
|
$templateProcessor->getVariables()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$docName = 'clone-test-result.docx';
|
2016-06-04 20:06:37 +04:00
|
|
|
$templateProcessor->setValue('tableHeader', utf8_decode('ééé'));
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor->cloneRow('userId', 1);
|
2016-06-04 20:06:37 +04:00
|
|
|
$templateProcessor->setValue('userId#1', 'Test');
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor->saveAs($docName);
|
2014-03-24 20:59:42 +07:00
|
|
|
$docFound = file_exists($docName);
|
2014-03-15 13:25:42 +07:00
|
|
|
unlink($docName);
|
|
|
|
|
$this->assertTrue($docFound);
|
|
|
|
|
}
|
2014-04-01 13:25:05 +01:00
|
|
|
|
2014-04-02 18:57:34 +07:00
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* @covers ::setValue
|
|
|
|
|
* @covers ::saveAs
|
|
|
|
|
* @test
|
2014-04-02 18:57:34 +07:00
|
|
|
*/
|
2015-08-30 18:03:31 +04:00
|
|
|
public function testMacrosCanBeReplacedInHeaderAndFooter()
|
2014-04-01 13:25:05 +01:00
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx');
|
|
|
|
|
|
2016-04-23 19:49:10 +04:00
|
|
|
$this->assertEquals(array('documentContent', 'headerValue', 'footerValue'), $templateProcessor->getVariables());
|
|
|
|
|
|
|
|
|
|
$macroNames = array('headerValue', 'documentContent', 'footerValue');
|
2016-06-04 20:06:37 +04:00
|
|
|
$macroValues = array('Header Value', 'Document text.', 'Footer Value');
|
2016-04-23 19:49:10 +04:00
|
|
|
$templateProcessor->setValue($macroNames, $macroValues);
|
2014-04-01 13:25:05 +01:00
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$docName = 'header-footer-test-result.docx';
|
|
|
|
|
$templateProcessor->saveAs($docName);
|
2014-04-01 13:25:05 +01:00
|
|
|
$docFound = file_exists($docName);
|
|
|
|
|
unlink($docName);
|
|
|
|
|
$this->assertTrue($docFound);
|
|
|
|
|
}
|
2014-04-05 22:53:39 +07:00
|
|
|
|
|
|
|
|
/**
|
2014-08-16 15:21:58 +04:00
|
|
|
* @covers ::cloneBlock
|
|
|
|
|
* @covers ::deleteBlock
|
|
|
|
|
* @covers ::saveAs
|
|
|
|
|
* @test
|
2014-04-05 22:53:39 +07:00
|
|
|
*/
|
|
|
|
|
public function testCloneDeleteBlock()
|
|
|
|
|
{
|
2014-08-16 15:21:58 +04:00
|
|
|
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-delete-block.docx');
|
2014-04-05 22:53:39 +07:00
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$this->assertEquals(
|
|
|
|
|
array('DELETEME', '/DELETEME', 'CLONEME', '/CLONEME'),
|
|
|
|
|
$templateProcessor->getVariables()
|
|
|
|
|
);
|
2014-04-05 22:53:39 +07:00
|
|
|
|
2014-08-16 15:21:58 +04:00
|
|
|
$docName = 'clone-delete-block-result.docx';
|
|
|
|
|
$templateProcessor->cloneBlock('CLONEME', 3);
|
|
|
|
|
$templateProcessor->deleteBlock('DELETEME');
|
|
|
|
|
$templateProcessor->saveAs($docName);
|
2014-04-05 22:53:39 +07:00
|
|
|
$docFound = file_exists($docName);
|
|
|
|
|
unlink($docName);
|
|
|
|
|
$this->assertTrue($docFound);
|
2014-03-15 13:25:42 +07:00
|
|
|
}
|
2014-03-11 21:44:54 +07:00
|
|
|
}
|