Skip to content

Commit

Permalink
Merge 195a326 into 8b891bb
Browse files Browse the repository at this point in the history
  • Loading branch information
crystoline committed May 14, 2024
2 parents 8b891bb + 195a326 commit 1cb0092
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/usage/elements/field.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Currently the following fields are supported:
- XE
- INDEX
- FILENAME
- REF

``` php
<?php
Expand Down Expand Up @@ -37,4 +38,12 @@ $section->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');

//Adding reference to a bookmark
$fieldText->addField('REF', [
'name' => 'bookmark'
], [
'InsertParagraphNumberRelativeContext',
'CreateHyperLink',
]);
```
4 changes: 4 additions & 0 deletions src/PhpWord/Element/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class Field extends AbstractElement
],
'options' => ['Path', 'PreserveFormat'],
],
'REF' => array(
'properties' => array('name' => ''),
'options' => array('f', 'h', 'n', 'p', 'r', 't', 'w'),
),
];

/**
Expand Down
102 changes: 102 additions & 0 deletions src/PhpWord/Writer/Word2007/Element/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,106 @@ private function buildPropertiesAndOptions(\PhpOffice\PhpWord\Element\Field $ele

return $propertiesAndOptions;
}

/**
* Writes a REF field
*
* @param \PhpOffice\PhpWord\Element\Field $element
*/
protected function writeRef(\PhpOffice\PhpWord\Element\Field $element)
{
$xmlWriter = $this->getXmlWriter();
$this->startElementP();

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'begin');
$xmlWriter->endElement(); // w:fldChar
$xmlWriter->endElement(); // w:r

$instruction = ' ' . $element->getType() . ' ';

foreach ($element->getProperties() as $property) {
$instruction .= $property . ' ';
}
foreach ($element->getOptions() as $optionKey => $optionValue) {
$instruction .= $this->convertRefOption($optionKey, $optionValue) . ' ';
}

$xmlWriter->startElement('w:r');
$this->writeFontStyle();
$xmlWriter->startElement('w:instrText');
$xmlWriter->writeAttribute('xml:space', 'preserve');
$xmlWriter->text($instruction);
$xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r

if ($element->getText() != null) {
if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) {
$containerWriter = new Container($xmlWriter, $element->getText(), true);
$containerWriter->write();

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:instrText');
$xmlWriter->text('"' . $this->buildPropertiesAndOptions($element));
$xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:instrText');
$xmlWriter->writeAttribute('xml:space', 'preserve');
$xmlWriter->text(' ');
$xmlWriter->endElement(); // w:instrText
$xmlWriter->endElement(); // w:r
}
}

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'separate');
$xmlWriter->endElement(); // w:fldChar
$xmlWriter->endElement(); // w:r

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:rPr');
$xmlWriter->startElement('w:noProof');
$xmlWriter->endElement(); // w:noProof
$xmlWriter->endElement(); // w:rPr
$xmlWriter->writeElement('w:t', $element->getText() != null && is_string($element->getText()) ? $element->getText() : '1');
$xmlWriter->endElement(); // w:r

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'end');
$xmlWriter->endElement(); // w:fldChar
$xmlWriter->endElement(); // w:r

$this->endElementP(); // w:p
}

private function convertRefOption($optionKey, $optionValue)
{
if ($optionKey === 'NumberSeperatorSequence') {
return '\\d ' . $optionValue;
}

switch ($optionValue) {
case 'IncrementAndInsertText':
return '\\f';
case 'CreateHyperLink':
return '\\h';
case 'NoTrailingPeriod':
return '\\n';
case 'IncludeAboveOrBelow':
return '\\p';
case 'InsertParagraphNumberRelativeContext':
return '\\r';
case 'SuppressNonDelimiterNonNumericalText':
return '\\t';
case 'InsertParagraphNumberFullContext':
return '\\w';
default:
return '';
}
}
}
62 changes: 62 additions & 0 deletions tests/PhpWord/Writer/Word2007/Element/FieldTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace PhpOffice\PhpWord\Writer\Word2007\Element;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\TestHelperDOCX;
use PHPUnit\Framework\TestCase;

/**
* Test class for PhpOffice\PhpWord\Writer\Word2007\Field
*/
class FieldTest extends TestCase
{
/**
* Executed before each method of the class
*/
public function tearDown()
{
TestHelperDOCX::clear();
}

/**
* Test Field write
*/
public function testWriteWithRefType()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addField(
'REF',
array(
'name' => 'my-bookmark',
),
array(
'InsertParagraphNumberRelativeContext',
'CreateHyperLink',
)
);

$section->addListItem('line one item');
$section->addListItem('line two item');
$section->addBookmark('my-bookmark');
$section->addListItem('line three item');

$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');

$refFieldPath = '/w:document/w:body/w:p[1]/w:r[2]/w:instrText';

$this->assertTrue($doc->elementExists($refFieldPath));

$bookMarkElement = $doc->getElement($refFieldPath);

$this->assertNotNull($bookMarkElement);

$this->assertEquals(' REF my-bookmark \r \h ', $bookMarkElement->textContent);

$bookmarkPath = '/w:document/w:body/w:bookmarkStart';

$this->assertTrue($doc->elementExists($bookmarkPath));
$this->assertEquals('my-bookmark', $doc->getElementAttribute("$bookmarkPath", 'w:name'));
}
}

0 comments on commit 1cb0092

Please sign in to comment.