Skip to content

Commit ed1d5b8

Browse files
committed
TemplateProcessor Persist File After Destruct
Fix #2539. Inadvertent break in TemplateProcessor behavior with #2475. Deleted temp file on destruct. It will now persist, restoring prior behavior, unless user specifies otherwise in constructor.
1 parent 11a7aaa commit ed1d5b8

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

src/PhpWord/TemplateProcessor.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,22 @@ class TemplateProcessor
9999

100100
protected static $macroClosingChars = '}';
101101

102+
/**
103+
* Delete temp file at destruct?
104+
*
105+
* @var bool
106+
*/
107+
protected $deleteAtDestruct = false;
108+
102109
/**
103110
* @since 0.12.0 Throws CreateTemporaryFileException and CopyFileException instead of Exception
104111
*
105112
* @param string $documentTemplate The fully qualified template filename
113+
* @param bool $deleteAtDestruct Delete temp file at destruct
106114
*/
107-
public function __construct($documentTemplate)
115+
public function __construct($documentTemplate, $deleteAtDestruct = false)
108116
{
117+
$this->deleteAtDestruct = $deleteAtDestruct;
109118
// Temporary document filename initialization
110119
$this->tempDocumentFilename = tempnam(Settings::getTempDir(), 'PhpWord');
111120
if (false === $this->tempDocumentFilename) {
@@ -147,7 +156,7 @@ public function __destruct()
147156
}
148157
}
149158
// Temporary file
150-
if ($this->tempDocumentFilename && file_exists($this->tempDocumentFilename)) {
159+
if ($this->deleteAtDestruct && $this->tempDocumentFilename && file_exists($this->tempDocumentFilename)) {
151160
unlink($this->tempDocumentFilename);
152161
}
153162
}

tests/PhpWordTests/TemplateProcessorTest.php

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,45 @@
3838
*/
3939
final class TemplateProcessorTest extends \PHPUnit\Framework\TestCase
4040
{
41+
private const DELETE_AT_DESTRUCT = true;
42+
4143
/**
4244
* Construct test.
4345
*
4446
* @covers ::__construct
47+
* @covers ::__destruct
4548
*/
4649
public function testTheConstruct(): void
4750
{
48-
$object = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
51+
$object = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx', self::DELETE_AT_DESTRUCT);
4952
self::assertInstanceOf('PhpOffice\\PhpWord\\TemplateProcessor', $object);
5053
self::assertEquals([], $object->getVariables());
54+
$filename1 = $object->save();
55+
self::assertFileExists($filename1);
56+
unset($object);
57+
gc_collect_cycles();
58+
if (method_exists(self::class, 'assertFileDoesNotExist')) {
59+
self::assertFileDoesNotExist($filename1);
60+
} else {
61+
self::assertFileNotExists($filename1);
62+
}
63+
}
64+
65+
/**
66+
* Do not delete tempfile test.
67+
*
68+
* @covers ::__construct
69+
* @covers ::__destruct
70+
*/
71+
public function testDoNotDeleteTempfile(): void
72+
{
73+
$object = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
74+
$filename1 = $object->save();
75+
self::assertFileExists($filename1);
76+
unset($object);
77+
gc_collect_cycles();
78+
self::assertFileExists($filename1);
79+
@unlink($filename1);
5180
}
5281

5382
/**
@@ -106,7 +135,7 @@ public function xtestTemplateCanBeSavedInTemporaryLocation(string $templateFqfn,
106135
public function testXslStyleSheetCanBeApplied(): void
107136
{
108137
$templateFqfn = __DIR__ . '/_files/templates/with_table_macros.docx';
109-
$templateProcessor = new TemplateProcessor($templateFqfn);
138+
$templateProcessor = new TemplateProcessor($templateFqfn, self::DELETE_AT_DESTRUCT);
110139

111140
$actualDocumentFqfn = $this->xtestTemplateCanBeSavedInTemporaryLocation($templateFqfn, $templateProcessor);
112141
$expectedDocumentFqfn = __DIR__ . '/_files/documents/without_table_macros.docx';
@@ -150,7 +179,7 @@ public function testXslStyleSheetCanNotBeAppliedOnFailureOfSettingParameterValue
150179
$this->expectExceptionMessage('Could not set values for the given XSL style sheet parameters.');
151180
}
152181

153-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
182+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx', self::DELETE_AT_DESTRUCT);
154183

155184
$xslDomDocument = new DOMDocument();
156185
$xslDomDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
@@ -171,7 +200,7 @@ public function testXslStyleSheetCanNotBeAppliedOnFailureOfLoadingXmlFromTemplat
171200
{
172201
$this->expectException(\PhpOffice\PhpWord\Exception\Exception::class);
173202
$this->expectExceptionMessage('Could not load the given XML document.');
174-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/corrupted_main_document_part.docx');
203+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/corrupted_main_document_part.docx', self::DELETE_AT_DESTRUCT);
175204

176205
$xslDomDocument = new DOMDocument();
177206
$xslDomDocument->load(__DIR__ . '/_files/xsl/passthrough.xsl');
@@ -190,7 +219,7 @@ public function testXslStyleSheetCanNotBeAppliedOnFailureOfLoadingXmlFromTemplat
190219
*/
191220
public function testDeleteRow(): void
192221
{
193-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/delete-row.docx');
222+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/delete-row.docx', self::DELETE_AT_DESTRUCT);
194223

195224
self::assertEquals(
196225
['deleteMe', 'deleteMeToo'],
@@ -216,7 +245,7 @@ public function testDeleteRow(): void
216245
*/
217246
public function testCloneRow(): void
218247
{
219-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx');
248+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx', self::DELETE_AT_DESTRUCT);
220249

221250
self::assertEquals(
222251
['tableHeader', 'userId', 'userName', 'userLocation'],
@@ -240,7 +269,7 @@ public function testCloneRow(): void
240269
*/
241270
public function testCloneRowWithCustomMacro(): void
242271
{
243-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge-with-custom-macro.docx');
272+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge-with-custom-macro.docx', self::DELETE_AT_DESTRUCT);
244273

245274
$templateProcessor->setMacroOpeningChars('{#');
246275
$templateProcessor->setMacroClosingChars('#}');
@@ -397,7 +426,7 @@ public function testCloneRowAndSetValuesWithCustomMacro(): void
397426
*/
398427
public function testMacrosCanBeReplacedInHeaderAndFooter(): void
399428
{
400-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx');
429+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx', self::DELETE_AT_DESTRUCT);
401430

402431
self::assertEquals(['documentContent', 'headerValue:100:100', 'footerValue'], $templateProcessor->getVariables());
403432

@@ -418,7 +447,7 @@ public function testMacrosCanBeReplacedInHeaderAndFooter(): void
418447
*/
419448
public function testCustomMacrosCanBeReplacedInHeaderAndFooter(): void
420449
{
421-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer-with-custom-macro.docx');
450+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer-with-custom-macro.docx', self::DELETE_AT_DESTRUCT);
422451
$templateProcessor->setMacroOpeningChars('{{');
423452
$templateProcessor->setMacroClosingChars('}}');
424453

@@ -440,7 +469,7 @@ public function testCustomMacrosCanBeReplacedInHeaderAndFooter(): void
440469
*/
441470
public function testSetValue(): void
442471
{
443-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx');
472+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge.docx', self::DELETE_AT_DESTRUCT);
444473
Settings::setOutputEscapingEnabled(true);
445474
$helloworld = "hello\nworld";
446475
$templateProcessor->setValue('userName', $helloworld);
@@ -455,7 +484,7 @@ public function testSetValue(): void
455484
*/
456485
public function testSetValueWithCustomMacro(): void
457486
{
458-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge-with-custom-macro.docx');
487+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-merge-with-custom-macro.docx', self::DELETE_AT_DESTRUCT);
459488
$templateProcessor->setMacroChars('{#', '#}');
460489
Settings::setOutputEscapingEnabled(true);
461490
$helloworld = "hello\nworld";
@@ -615,7 +644,7 @@ public function testSetValuesWithCustomMacro(): void
615644
*/
616645
public function testSetImageValue(): void
617646
{
618-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx');
647+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/header-footer.docx', self::DELETE_AT_DESTRUCT);
619648
$imagePath = __DIR__ . '/_files/images/earth.jpg';
620649

621650
$variablesReplace = [
@@ -695,7 +724,7 @@ public function testSetImageValue(): void
695724
*/
696725
public function testCloneDeleteBlock(): void
697726
{
698-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-delete-block.docx');
727+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/clone-delete-block.docx', self::DELETE_AT_DESTRUCT);
699728

700729
self::assertEquals(
701730
['DELETEME', '/DELETEME', 'CLONEME', 'blockVariable', '/CLONEME'],
@@ -735,7 +764,7 @@ public function testGetVariableCountCountsHowManyTimesEachPlaceholderIsPresent()
735764
$templatePath = 'test.docx';
736765
$objWriter->save($templatePath);
737766

738-
$templateProcessor = new TemplateProcessor($templatePath);
767+
$templateProcessor = new TemplateProcessor($templatePath, self::DELETE_AT_DESTRUCT);
739768
$variableCount = $templateProcessor->getVariableCount();
740769
unlink($templatePath);
741770

@@ -772,7 +801,7 @@ public function testGetVariableCountCountsHowManyTimesEachPlaceholderIsPresentWi
772801
$templatePath = 'test.docx';
773802
$objWriter->save($templatePath);
774803

775-
$templateProcessor = new TemplateProcessor($templatePath);
804+
$templateProcessor = new TemplateProcessor($templatePath, self::DELETE_AT_DESTRUCT);
776805
$templateProcessor->setMacroChars('{{', '}}');
777806
$variableCount = $templateProcessor->getVariableCount();
778807
unlink($templatePath);
@@ -810,7 +839,7 @@ public function testCloneBlockCanCloneABlockTwice(): void
810839
$objWriter->save($templatePath);
811840

812841
// replace placeholders and save the file
813-
$templateProcessor = new TemplateProcessor($templatePath);
842+
$templateProcessor = new TemplateProcessor($templatePath, self::DELETE_AT_DESTRUCT);
814843
$templateProcessor->setValue('title', 'Some title');
815844
$templateProcessor->cloneBlock('subreport', 2);
816845
$templateProcessor->setValue('subreport.id', '123', 1);
@@ -863,7 +892,7 @@ public function testCloneBlockCanCloneABlockTwiceWithCustomMacro(): void
863892
$objWriter->save($templatePath);
864893

865894
// replace placeholders and save the file
866-
$templateProcessor = new TemplateProcessor($templatePath);
895+
$templateProcessor = new TemplateProcessor($templatePath, self::DELETE_AT_DESTRUCT);
867896
$templateProcessor->setMacroChars('{{', '}}');
868897
$templateProcessor->setValue('title', 'Some title');
869898
$templateProcessor->cloneBlock('subreport', 2);
@@ -1152,7 +1181,7 @@ public function testFixBrokenMacrosWithCustomMacro(): void
11521181
*/
11531182
public function testMainPartNameDetection(): void
11541183
{
1155-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/document22-xml.docx');
1184+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/document22-xml.docx', self::DELETE_AT_DESTRUCT);
11561185

11571186
$variables = ['test'];
11581187

@@ -1164,7 +1193,7 @@ public function testMainPartNameDetection(): void
11641193
*/
11651194
public function testMainPartNameDetectionWithCustomMacro(): void
11661195
{
1167-
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/document22-with-custom-macro-xml.docx');
1196+
$templateProcessor = new TemplateProcessor(__DIR__ . '/_files/templates/document22-with-custom-macro-xml.docx', self::DELETE_AT_DESTRUCT);
11681197
$templateProcessor->setMacroOpeningChars('{#');
11691198
$templateProcessor->setMacroClosingChars('#}');
11701199
$variables = ['test'];
@@ -1431,7 +1460,7 @@ public function testUnserialize(): void
14311460
{
14321461
$this->expectException(WordException::class);
14331462
$this->expectExceptionMessage('unserialize not permitted');
1434-
$object = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx');
1463+
$object = new TemplateProcessor(__DIR__ . '/_files/templates/blank.docx', self::DELETE_AT_DESTRUCT);
14351464
$serialized = serialize($object);
14361465
$object2 = unserialize($serialized);
14371466
}

0 commit comments

Comments
 (0)