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. * * @param string $actualDocumentFqfn * @throws \Exception * @covers ::applyXslStyleSheet * @depends testTemplateCanBeSavedInTemporaryLocation * @test */ 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 => htmlspecialchars('somevalue', ENT_COMPAT, 'UTF-8'))); } /** * 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); } /** * @civers ::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(htmlspecialchars('ééé', ENT_COMPAT, 'UTF-8'))); $templateProcessor->cloneRow('userId', 1); $templateProcessor->setValue('userId#1', htmlspecialchars('Test', ENT_COMPAT, 'UTF-8')); $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() ); $docName = 'header-footer-test-result.docx'; $templateProcessor->setValue('headerValue', htmlspecialchars('Header Value', ENT_COMPAT, 'UTF-8')); $templateProcessor->setValue('documentContent', htmlspecialchars('Document text.', ENT_COMPAT, 'UTF-8')); $templateProcessor->setValue('footerValue', htmlspecialchars('Footer Value', ENT_COMPAT, 'UTF-8')); $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); } }