From a209906f3d64d4327afbf09b49c6466c209e13db Mon Sep 17 00:00:00 2001 From: milkyway Date: Tue, 7 Nov 2023 07:11:06 +0100 Subject: [PATCH] Added field 'FILENAME' --- docs/changes/1.x/1.2.0.md | 1 + docs/usage/elements/field.md | 3 +- samples/Sample_27_Field.php | 3 + src/PhpWord/Element/Field.php | 6 ++ src/PhpWord/Writer/ODText/Element/Field.php | 15 ++++- src/PhpWord/Writer/RTF/Element/Field.php | 19 +++++- src/PhpWord/Writer/Word2007/Element/Field.php | 22 ++++--- .../Writer/ODText/Element/FieldTest.php | 64 +++++++++++++++++++ tests/PhpWordTests/Writer/RTF/ElementTest.php | 18 ++++++ .../Writer/Word2007/ElementTest.php | 38 +++++++++++ 10 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 tests/PhpWordTests/Writer/ODText/Element/FieldTest.php diff --git a/docs/changes/1.x/1.2.0.md b/docs/changes/1.x/1.2.0.md index d52fa01e7e..c7ad030b3e 100644 --- a/docs/changes/1.x/1.2.0.md +++ b/docs/changes/1.x/1.2.0.md @@ -30,6 +30,7 @@ - PDF Writer : Added callback for modifying the HTML - Added Support for Language, both for document overall and individual text elements - Template : Set a checkbox by [@nxtpge](https://github.com/nxtpge) in [#2509](https://github.com/PHPOffice/PHPWord/pull/2509) +- ODText / RTF / Word2007 Writer : Add field FILENAME by [@milkyway-git](https://github.com/milkyway-git) in [#2510](https://github.com/PHPOffice/PHPWord/pull/2510) ### Bug fixes diff --git a/docs/usage/elements/field.md b/docs/usage/elements/field.md index 10492cc742..fe8e9756fc 100644 --- a/docs/usage/elements/field.md +++ b/docs/usage/elements/field.md @@ -7,6 +7,7 @@ Currently the following fields are supported: - DATE - XE - INDEX +- FILENAME ``` php addField('XE', array(), array(), $fieldText); //this actually adds the index $section->addField('INDEX', array(), array('\\e " " \\h "A" \\c "3"'), 'right click to update index'); -``` \ No newline at end of file +``` diff --git a/samples/Sample_27_Field.php b/samples/Sample_27_Field.php index d250946169..fd441ba022 100644 --- a/samples/Sample_27_Field.php +++ b/samples/Sample_27_Field.php @@ -26,6 +26,9 @@ $section->addText('Number of pages field:'); $section->addField('NUMPAGES', ['numformat' => '0,00', 'format' => 'Arabic'], ['PreserveFormat']); + +$section->addText('Filename field:'); +$section->addField('FILENAME', ['format' => 'Upper'], ['Path', 'PreserveFormat']); $section->addTextBreak(); $textrun = $section->addTextRun(); diff --git a/src/PhpWord/Element/Field.php b/src/PhpWord/Element/Field.php index 68a5296d7a..b371bb80d7 100644 --- a/src/PhpWord/Element/Field.php +++ b/src/PhpWord/Element/Field.php @@ -85,6 +85,12 @@ class Field extends AbstractElement 'properties' => ['StyleIdentifier' => ''], 'options' => ['PreserveFormat'], ], + 'FILENAME' => [ + 'properties' => [ + 'format' => ['Upper', 'Lower', 'FirstCap', 'Caps'], + ], + 'options' => ['Path', 'PreserveFormat'], + ], ]; /** diff --git a/src/PhpWord/Writer/ODText/Element/Field.php b/src/PhpWord/Writer/ODText/Element/Field.php index 1bfdbc9301..46f62b0f02 100644 --- a/src/PhpWord/Writer/ODText/Element/Field.php +++ b/src/PhpWord/Writer/ODText/Element/Field.php @@ -15,7 +15,7 @@ * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ // Not fully implemented -// - supports only PAGE and NUMPAGES +// - supports only PAGE, NUMPAGES, DATE and FILENAME // - supports only default formats and options // - supports style only if specified by name // - spaces before and after field may be dropped @@ -44,6 +44,7 @@ public function write(): void case 'date': case 'page': case 'numpages': + case 'filename': $this->writeDefault($element, $type); break; @@ -78,6 +79,18 @@ private function writeDefault(\PhpOffice\PhpWord\Element\Field $element, $type): $xmlWriter->startElement('text:page-count'); $xmlWriter->endElement(); + break; + case 'filename': + $xmlWriter->startElement('text:file-name'); + $xmlWriter->writeAttribute('text:fixed', 'false'); + $options = $element->getOptions(); + if ($options != null && in_array('Path', $options)) { + $xmlWriter->writeAttribute('text:display', 'full'); + } else { + $xmlWriter->writeAttribute('text:display', 'name'); + } + $xmlWriter->endElement(); + break; } $xmlWriter->endElement(); // text:span diff --git a/src/PhpWord/Writer/RTF/Element/Field.php b/src/PhpWord/Writer/RTF/Element/Field.php index 37f203aca8..34024f5e51 100644 --- a/src/PhpWord/Writer/RTF/Element/Field.php +++ b/src/PhpWord/Writer/RTF/Element/Field.php @@ -17,10 +17,12 @@ namespace PhpOffice\PhpWord\Writer\RTF\Element; +use PhpOffice\PhpWord\Element\Field as ElementField; + /** * Field element writer. * - * Note: for now, only date, page and numpages fields are implemented for RTF. + * Note: for now, only date, page, numpages and filename fields are implemented for RTF. */ class Field extends Text { @@ -30,7 +32,7 @@ class Field extends Text public function write() { $element = $this->element; - if (!$element instanceof \PhpOffice\PhpWord\Element\Field) { + if (!$element instanceof ElementField) { return; } @@ -66,7 +68,18 @@ protected function writeNumpages() return 'NUMPAGES'; } - protected function writeDate(\PhpOffice\PhpWord\Element\Field $element) + protected function writeFilename(ElementField $element): string + { + $content = 'FILENAME'; + $options = $element->getOptions(); + if ($options != null && in_array('Path', $options)) { + $content .= ' \\\\p'; + } + + return $content; + } + + protected function writeDate(ElementField $element) { $content = ''; $content .= 'DATE'; diff --git a/src/PhpWord/Writer/Word2007/Element/Field.php b/src/PhpWord/Writer/Word2007/Element/Field.php index 6fdb48b0f4..4d7c2a0b46 100644 --- a/src/PhpWord/Writer/Word2007/Element/Field.php +++ b/src/PhpWord/Writer/Word2007/Element/Field.php @@ -166,15 +166,15 @@ private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $ele foreach ($properties as $propkey => $propval) { switch ($propkey) { case 'format': - $propertiesAndOptions .= '\* ' . $propval . ' '; + $propertiesAndOptions .= '\\* ' . $propval . ' '; break; case 'numformat': - $propertiesAndOptions .= '\# ' . $propval . ' '; + $propertiesAndOptions .= '\\# ' . $propval . ' '; break; case 'dateformat': - $propertiesAndOptions .= '\@ "' . $propval . '" '; + $propertiesAndOptions .= '\\@ "' . $propval . '" '; break; case 'macroname': @@ -192,27 +192,31 @@ private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $ele foreach ($options as $option) { switch ($option) { case 'PreserveFormat': - $propertiesAndOptions .= '\* MERGEFORMAT '; + $propertiesAndOptions .= '\\* MERGEFORMAT '; break; case 'LunarCalendar': - $propertiesAndOptions .= '\h '; + $propertiesAndOptions .= '\\h '; break; case 'SakaEraCalendar': - $propertiesAndOptions .= '\s '; + $propertiesAndOptions .= '\\s '; break; case 'LastUsedFormat': - $propertiesAndOptions .= '\l '; + $propertiesAndOptions .= '\\l '; break; case 'Bold': - $propertiesAndOptions .= '\b '; + $propertiesAndOptions .= '\\b '; break; case 'Italic': - $propertiesAndOptions .= '\i '; + $propertiesAndOptions .= '\\i '; + + break; + case 'Path': + $propertiesAndOptions .= '\\p '; break; default: diff --git a/tests/PhpWordTests/Writer/ODText/Element/FieldTest.php b/tests/PhpWordTests/Writer/ODText/Element/FieldTest.php new file mode 100644 index 0000000000..2d9bb7c87d --- /dev/null +++ b/tests/PhpWordTests/Writer/ODText/Element/FieldTest.php @@ -0,0 +1,64 @@ +addSection(); + $section->addField('FILENAME'); + + $doc = TestHelperDOCX::getDocument($phpWord, 'ODText'); + + self::assertTrue($doc->elementExists('/office:document-content/office:body/office:text/text:section/text:span/text:file-name')); + self::assertEquals('false', $doc->getElementAttribute('/office:document-content/office:body/office:text/text:section/text:span/text:file-name', 'text:fixed')); + self::assertEquals('name', $doc->getElementAttribute('/office:document-content/office:body/office:text/text:section/text:span/text:file-name', 'text:display')); + } + + public function testFieldFilenameOptionPath(): void + { + $phpWord = new PhpWord(); + + $section = $phpWord->addSection(); + $section->addField('FILENAME', [], ['Path']); + + $doc = TestHelperDOCX::getDocument($phpWord, 'ODText'); + + self::assertTrue($doc->elementExists('/office:document-content/office:body/office:text/text:section/text:span/text:file-name')); + self::assertEquals('false', $doc->getElementAttribute('/office:document-content/office:body/office:text/text:section/text:span/text:file-name', 'text:fixed')); + self::assertEquals('full', $doc->getElementAttribute('/office:document-content/office:body/office:text/text:section/text:span/text:file-name', 'text:display')); + } +} diff --git a/tests/PhpWordTests/Writer/RTF/ElementTest.php b/tests/PhpWordTests/Writer/RTF/ElementTest.php index 7c1549371d..fd0842cd6c 100644 --- a/tests/PhpWordTests/Writer/RTF/ElementTest.php +++ b/tests/PhpWordTests/Writer/RTF/ElementTest.php @@ -45,6 +45,24 @@ public function testUnmatchedElements(): void } } + public function testFilenameField(): void + { + $parentWriter = new RTF(); + $element = new \PhpOffice\PhpWord\Element\Field('FILENAME'); + $field = new \PhpOffice\PhpWord\Writer\RTF\Element\Field($parentWriter, $element); + + self::assertEquals("{\\field{\\*\\fldinst FILENAME}{\\fldrslt}}\\par\n", $this->removeCr($field)); + } + + public function testFilenameFieldOptionsPath(): void + { + $parentWriter = new RTF(); + $element = new \PhpOffice\PhpWord\Element\Field('FILENAME', [], ['Path']); + $field = new \PhpOffice\PhpWord\Writer\RTF\Element\Field($parentWriter, $element); + + self::assertEquals("{\\field{\\*\\fldinst FILENAME \\\\p}{\\fldrslt}}\\par\n", $this->removeCr($field)); + } + public function testPageField(): void { $parentWriter = new RTF(); diff --git a/tests/PhpWordTests/Writer/Word2007/ElementTest.php b/tests/PhpWordTests/Writer/Word2007/ElementTest.php index 3bcd842fbd..3ed3e7a91b 100644 --- a/tests/PhpWordTests/Writer/Word2007/ElementTest.php +++ b/tests/PhpWordTests/Writer/Word2007/ElementTest.php @@ -306,6 +306,44 @@ public function testStyledFieldElement(): void self::assertEquals($stnam, $doc->getElementAttribute($sty . '/w:rStyle', 'w:val')); } + public function testFieldElementFilename(): void + { + $phpWord = new PhpWord(); + $stnam = 'h1'; + $phpWord->addFontStyle($stnam, ['name' => 'Courier New', 'size' => 8]); + $section = $phpWord->addSection(); + + $fld = $section->addField('FILENAME'); + $fld->setFontStyle($stnam); + $doc = TestHelperDOCX::getDocument($phpWord); + + $element = '/w:document/w:body/w:p/w:r[2]/w:instrText'; + self::assertTrue($doc->elementExists($element)); + self::assertEquals(' FILENAME ', $doc->getElement($element)->textContent); + $sty = '/w:document/w:body/w:p/w:r[2]/w:rPr'; + self::assertTrue($doc->elementExists($sty)); + self::assertEquals($stnam, $doc->getElementAttribute($sty . '/w:rStyle', 'w:val')); + } + + public function testFieldElementFilenameOptionsPath(): void + { + $phpWord = new PhpWord(); + $stnam = 'h1'; + $phpWord->addFontStyle($stnam, ['name' => 'Courier New', 'size' => 8]); + $section = $phpWord->addSection(); + + $fld = $section->addField('FILENAME', [], ['Path']); + $fld->setFontStyle($stnam); + $doc = TestHelperDOCX::getDocument($phpWord); + + $element = '/w:document/w:body/w:p/w:r[2]/w:instrText'; + self::assertTrue($doc->elementExists($element)); + self::assertEquals(' FILENAME \p ', $doc->getElement($element)->textContent); + $sty = '/w:document/w:body/w:p/w:r[2]/w:rPr'; + self::assertTrue($doc->elementExists($sty)); + self::assertEquals($stnam, $doc->getElementAttribute($sty . '/w:rStyle', 'w:val')); + } + public function testFieldElementWithComplexText(): void { $phpWord = new PhpWord();