From b051762a6fa23cbec839ff90d6d1e816c6aa4ddb Mon Sep 17 00:00:00 2001 From: Vincent Kool Date: Sat, 20 Aug 2022 23:24:54 +0200 Subject: [PATCH 1/4] Added code to read FormFields (text input, dropdown and checkbox) from a Word file --- src/PhpWord/Reader/Word2007/AbstractPart.php | 143 +++++++++++++++++- .../Reader/Word2007/ElementTest.php | 141 ++++++++++++++++- 2 files changed, 280 insertions(+), 4 deletions(-) diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 2741841ef3..5674fcffc5 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -24,6 +24,7 @@ use PhpOffice\PhpWord\ComplexType\TblWidth as TblWidthComplexType; use PhpOffice\PhpWord\Element\AbstractContainer; use PhpOffice\PhpWord\Element\AbstractElement; +use PhpOffice\PhpWord\Element\FormField; use PhpOffice\PhpWord\Element\TextRun; use PhpOffice\PhpWord\Element\TrackChange; use PhpOffice\PhpWord\PhpWord; @@ -192,8 +193,48 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par // Paragraph style $paragraphStyle = $xmlReader->elementExists('w:pPr', $domNode) ? $this->readParagraphStyle($xmlReader, $domNode) : null; - // PreserveText - if ($xmlReader->elementExists('w:r/w:instrText', $domNode)) { + if ($xmlReader->elementExists('w:r/w:fldChar/w:ffData', $domNode)) { + // FormField + $partOfFormField = false; + $formNodes = array(); + $formType = null; +// $field = new FormField("type", "forntsyle", "paragraphstyle"): + $textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag', $domNode); + if (0 === $textRunContainers) { + $parent->addTextBreak(null, $paragraphStyle); + } else { + $nodes = $xmlReader->getElements('*', $domNode); + $paragraph = $parent->addTextRun($paragraphStyle); + foreach ($nodes as $node) { + if($xmlReader->elementExists('w:fldChar/w:ffData', $node)) { + $partOfFormField = true; + $formNodes[] = $node; + if($xmlReader->elementExists('w:fldChar/w:ffData/w:ddList', $node)) { + $formType = "dropdown"; + } elseif ($xmlReader->elementExists('w:fldChar/w:ffData/w:textInput', $node)) { + $formType = "textinput"; + } elseif ($xmlReader->elementExists('w:fldChar/w:ffData/w:checkBox', $node)) { + $formType = "checkbox"; + } + } elseif ( + $partOfFormField && + $xmlReader->elementExists('w:fldChar', $node) && + "end" == $xmlReader->getAttribute('w:fldCharType', $node, 'w:fldChar') + ) { + $formNodes[] = $node; + $partOfFormField = false; + // Process the form fields + $this->readFormField($xmlReader, $formNodes, $paragraph, $docPart, $paragraphStyle, $formType); + } elseif ($partOfFormField){ + $formNodes[] = $node; + } else { + // normal runs + $this->readRun($xmlReader, $node, $paragraph, $docPart, $paragraphStyle); + } + } + } + } elseif ($xmlReader->elementExists('w:r/w:instrText', $domNode)) { + // PreserveText $ignoreText = false; $textContent = ''; $fontStyle = $this->readFontStyle($xmlReader, $domNode); @@ -283,7 +324,103 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par } /** - * Returns the depth of the Heading, returns 0 for a Title. + * @param XMLReader $xmlReader + * @param \DOMElement[] $domNodes + * @param AbstractContainer $parent + * @param string $docPart + * @param null $paragraphStyle + * @param string $formType + * @return void + */ + private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $docPart = 'document', $paragraphStyle = null, $formType) + { + if(!in_array($formType, array("textinput", "checkbox", "dropdown"))) return; + + $formField = $parent->addFormField($formType, null, $paragraphStyle); + $ffData = $xmlReader->getElement("w:fldChar/w:ffData", $domNodes[0]); + + foreach ($xmlReader->getElements("*", $ffData) as $node) { + /** @var \DOMElement $node */ + switch ($node->localName) { + case "name": + $formField->setName($node->getAttribute("w:val")); + break; + case "ddList": + $listEntries = array(); + foreach ($xmlReader->getElements("*", $node) as $ddListNode) { + switch ($ddListNode->localName) { + case "result": + $formField->setValue($xmlReader->getAttribute("w:val", $ddListNode)); + break; + case "default": + $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + break; + case "listEntry": + $listEntries[] = $xmlReader->getAttribute("w:val", $ddListNode); + break; + } + } + $formField->setEntries($listEntries); + if (!is_null($formField->getValue())) { + $formField->setText($listEntries[$formField->getValue()]); + } + break; + case "textInput": + foreach ($xmlReader->getElements("*", $node) as $ddListNode) { + switch ($ddListNode->localName) { + case "default": + $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + break; + case "format": + case "maxLength": + break; + } + } + break; + case "checkBox": + foreach ($xmlReader->getElements("*", $node) as $ddListNode) { + + switch ($ddListNode->localName) { + case "default": + $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + break; + case "checked": + $formField->setValue($xmlReader->getAttribute("w:val", $ddListNode)); + break; + case "size": + case "sizeAuto": + break; + } + } + break; + } + } + + if ("textinput" == $formType) { + $ignoreText = true; + $textContent = ""; + foreach ($domNodes as $node) { + if ($xmlReader->elementExists('w:fldChar', $node)) { + $fldCharType = $xmlReader->getAttribute('w:fldCharType', $node, 'w:fldChar'); + if ('separate' == $fldCharType) { + $ignoreText = false; + } elseif ('end' == $fldCharType) { + $ignoreText = true; + } + } + + if (false === $ignoreText) { + $textContent .= $xmlReader->getValue('w:t', $node); + } + } + $formField->setValue(htmlspecialchars($textContent, ENT_QUOTES, 'UTF-8')); + $formField->setText(htmlspecialchars($textContent, ENT_QUOTES, 'UTF-8')); + } + } + + + /** + * Returns the depth of the Heading, returns 0 for a Title * * @return null|number */ diff --git a/tests/PhpWordTests/Reader/Word2007/ElementTest.php b/tests/PhpWordTests/Reader/Word2007/ElementTest.php index f96d8ac1a2..11a87f5f22 100644 --- a/tests/PhpWordTests/Reader/Word2007/ElementTest.php +++ b/tests/PhpWordTests/Reader/Word2007/ElementTest.php @@ -355,4 +355,143 @@ public function testReadDrawing(): void $elements = $phpWord->getSection(0)->getElements(); self::assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); } -} + + + /** + * Test reading FormField - DROPDOWN + */ + public function testReadFormFieldDropdown() + { + $documentXml = ' + + Reference + + + + + + + + + + + + + + + + + + + + FORMDROPDOWN + + + + + + + + + + + + + + + + + + + '; + + $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + + $elements = $phpWord->getSection(0)->getElements(); + $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + + $subElements = $elements[0]->getElements(); + + $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); + $this->assertEquals("Reference", $subElements[0]->getText()); + + $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); + $this->assertEquals("dropdown", $subElements[1]->getType()); + $this->assertEquals("DropDownList1", $subElements[1]->getName()); + $this->assertEquals("2", $subElements[1]->getValue()); + $this->assertEquals("Option Two", $subElements[1]->getText()); + $this->assertEquals(array("TBD", "Option One", "Option Two", "Option Three", "Other"), $subElements[1]->getEntries()); + + } + + + + /** + * Test reading FormField - textinput + */ + public function testReadFormFieldTextinput() + { + $documentXml = ' + + Fieldname + + + + + + + + + + + + + + + + FORMTEXT + + + + + + + + + + + + + + + + + + This is some sample text + + + + + + + + '; + + $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + + $elements = $phpWord->getSection(0)->getElements(); + $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + + $subElements = $elements[0]->getElements(); + + $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); + $this->assertEquals("Fieldname", $subElements[0]->getText()); + + $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); + $this->assertEquals("textinput", $subElements[1]->getType()); + $this->assertEquals("TextInput2", $subElements[1]->getName()); + $this->assertEquals("This is some sample text", $subElements[1]->getValue()); + $this->assertEquals("This is some sample text", $subElements[1]->getText()); + } + +} \ No newline at end of file From f76668fa6bbcc1f786bb7dc8087c1f3c6c783b26 Mon Sep 17 00:00:00 2001 From: Vincent Kool Date: Sat, 20 Aug 2022 23:44:03 +0200 Subject: [PATCH 2/4] Fixed code style issues and added a testcase for reading a FormField of type checkbox --- src/PhpWord/Reader/Word2007/AbstractPart.php | 82 +++++++++---------- .../Reader/Word2007/ElementTest.php | 81 ++++++++++++++---- 2 files changed, 105 insertions(+), 58 deletions(-) diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 5674fcffc5..41f6c64a42 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -206,26 +206,25 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par $nodes = $xmlReader->getElements('*', $domNode); $paragraph = $parent->addTextRun($paragraphStyle); foreach ($nodes as $node) { - if($xmlReader->elementExists('w:fldChar/w:ffData', $node)) { + if ($xmlReader->elementExists('w:fldChar/w:ffData', $node)) { $partOfFormField = true; $formNodes[] = $node; - if($xmlReader->elementExists('w:fldChar/w:ffData/w:ddList', $node)) { - $formType = "dropdown"; + if ($xmlReader->elementExists('w:fldChar/w:ffData/w:ddList', $node)) { + $formType = 'dropdown'; } elseif ($xmlReader->elementExists('w:fldChar/w:ffData/w:textInput', $node)) { - $formType = "textinput"; + $formType = 'textinput'; } elseif ($xmlReader->elementExists('w:fldChar/w:ffData/w:checkBox', $node)) { - $formType = "checkbox"; + $formType = 'checkbox'; } - } elseif ( - $partOfFormField && + } elseif ($partOfFormField && $xmlReader->elementExists('w:fldChar', $node) && - "end" == $xmlReader->getAttribute('w:fldCharType', $node, 'w:fldChar') + 'end' == $xmlReader->getAttribute('w:fldCharType', $node, 'w:fldChar') ) { $formNodes[] = $node; $partOfFormField = false; // Process the form fields $this->readFormField($xmlReader, $formNodes, $paragraph, $docPart, $paragraphStyle, $formType); - } elseif ($partOfFormField){ + } elseif ($partOfFormField) { $formNodes[] = $node; } else { // normal runs @@ -330,33 +329,34 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par * @param string $docPart * @param null $paragraphStyle * @param string $formType - * @return void */ - private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $docPart = 'document', $paragraphStyle = null, $formType) + private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $docPart, $paragraphStyle, $formType) { - if(!in_array($formType, array("textinput", "checkbox", "dropdown"))) return; + if (!in_array($formType, array('textinput', 'checkbox', 'dropdown'))) { + return; + } $formField = $parent->addFormField($formType, null, $paragraphStyle); - $ffData = $xmlReader->getElement("w:fldChar/w:ffData", $domNodes[0]); + $ffData = $xmlReader->getElement('w:fldChar/w:ffData', $domNodes[0]); - foreach ($xmlReader->getElements("*", $ffData) as $node) { + foreach ($xmlReader->getElements('*', $ffData) as $node) { /** @var \DOMElement $node */ switch ($node->localName) { - case "name": - $formField->setName($node->getAttribute("w:val")); + case 'name': + $formField->setName($node->getAttribute('w:val')); break; - case "ddList": + case 'ddList': $listEntries = array(); - foreach ($xmlReader->getElements("*", $node) as $ddListNode) { + foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { - case "result": - $formField->setValue($xmlReader->getAttribute("w:val", $ddListNode)); + case 'result': + $formField->setValue($xmlReader->getAttribute('w:val', $ddListNode)); break; - case "default": - $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + case 'default': + $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); break; - case "listEntry": - $listEntries[] = $xmlReader->getAttribute("w:val", $ddListNode); + case 'listEntry': + $listEntries[] = $xmlReader->getAttribute('w:val', $ddListNode); break; } } @@ -365,30 +365,29 @@ private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $ $formField->setText($listEntries[$formField->getValue()]); } break; - case "textInput": - foreach ($xmlReader->getElements("*", $node) as $ddListNode) { + case 'textInput': + foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { - case "default": - $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + case 'default': + $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); break; - case "format": - case "maxLength": + case 'format': + case 'maxLength': break; } } break; - case "checkBox": - foreach ($xmlReader->getElements("*", $node) as $ddListNode) { - + case 'checkBox': + foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { - case "default": - $formField->setDefault($xmlReader->getAttribute("w:val", $ddListNode)); + case 'default': + $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); break; - case "checked": - $formField->setValue($xmlReader->getAttribute("w:val", $ddListNode)); + case 'checked': + $formField->setValue($xmlReader->getAttribute('w:val', $ddListNode)); break; - case "size": - case "sizeAuto": + case 'size': + case 'sizeAuto': break; } } @@ -396,9 +395,9 @@ private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $ } } - if ("textinput" == $formType) { + if ('textinput' == $formType) { $ignoreText = true; - $textContent = ""; + $textContent = ''; foreach ($domNodes as $node) { if ($xmlReader->elementExists('w:fldChar', $node)) { $fldCharType = $xmlReader->getAttribute('w:fldCharType', $node, 'w:fldChar'); @@ -418,7 +417,6 @@ private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $ } } - /** * Returns the depth of the Heading, returns 0 for a Title * diff --git a/tests/PhpWordTests/Reader/Word2007/ElementTest.php b/tests/PhpWordTests/Reader/Word2007/ElementTest.php index 11a87f5f22..2a867741a9 100644 --- a/tests/PhpWordTests/Reader/Word2007/ElementTest.php +++ b/tests/PhpWordTests/Reader/Word2007/ElementTest.php @@ -356,7 +356,6 @@ public function testReadDrawing(): void self::assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); } - /** * Test reading FormField - DROPDOWN */ @@ -413,19 +412,16 @@ public function testReadFormFieldDropdown() $subElements = $elements[0]->getElements(); $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); - $this->assertEquals("Reference", $subElements[0]->getText()); + $this->assertEquals('Reference', $subElements[0]->getText()); $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); - $this->assertEquals("dropdown", $subElements[1]->getType()); - $this->assertEquals("DropDownList1", $subElements[1]->getName()); - $this->assertEquals("2", $subElements[1]->getValue()); - $this->assertEquals("Option Two", $subElements[1]->getText()); - $this->assertEquals(array("TBD", "Option One", "Option Two", "Option Three", "Other"), $subElements[1]->getEntries()); - + $this->assertEquals('dropdown', $subElements[1]->getType()); + $this->assertEquals('DropDownList1', $subElements[1]->getName()); + $this->assertEquals('2', $subElements[1]->getValue()); + $this->assertEquals('Option Two', $subElements[1]->getText()); + $this->assertEquals(array('TBD', 'Option One', 'Option Two', 'Option Three', 'Other'), $subElements[1]->getEntries()); } - - /** * Test reading FormField - textinput */ @@ -485,13 +481,66 @@ public function testReadFormFieldTextinput() $subElements = $elements[0]->getElements(); $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); - $this->assertEquals("Fieldname", $subElements[0]->getText()); + $this->assertEquals('Fieldname', $subElements[0]->getText()); $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); - $this->assertEquals("textinput", $subElements[1]->getType()); - $this->assertEquals("TextInput2", $subElements[1]->getName()); - $this->assertEquals("This is some sample text", $subElements[1]->getValue()); - $this->assertEquals("This is some sample text", $subElements[1]->getText()); + $this->assertEquals('textinput', $subElements[1]->getType()); + $this->assertEquals('TextInput2', $subElements[1]->getName()); + $this->assertEquals('This is some sample text', $subElements[1]->getValue()); + $this->assertEquals('This is some sample text', $subElements[1]->getText()); } -} \ No newline at end of file + /** + * Test reading FormField - checkbox + */ + public function testReadFormFieldCheckbox() + { + $documentXml = ' + + + + + + + + + + + + + + + + + + FORMCHECKBOX + + + + + + + + + + + + + + '; + + $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + + $elements = $phpWord->getSection(0)->getElements(); + $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + + $subElements = $elements[0]->getElements(); + +// $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); +// $this->assertEquals('Fieldname', $subElements[0]->getText()); + + $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[0]); + $this->assertEquals('checkbox', $subElements[0]->getType()); + $this->assertEquals('SomeCheckbox', $subElements[0]->getName()); + } +} From c2f923b16274a3ec7aa9155d01827ce78be2f2fd Mon Sep 17 00:00:00 2001 From: Vincent Kool Date: Sat, 20 Aug 2022 23:58:48 +0200 Subject: [PATCH 3/4] Fixed minor issue found by Scrutinizer --- src/PhpWord/Reader/Word2007/AbstractPart.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 41f6c64a42..4a8af46293 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -223,7 +223,7 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par $formNodes[] = $node; $partOfFormField = false; // Process the form fields - $this->readFormField($xmlReader, $formNodes, $paragraph, $docPart, $paragraphStyle, $formType); + $this->readFormField($xmlReader, $formNodes, $paragraph, $paragraphStyle, $formType); } elseif ($partOfFormField) { $formNodes[] = $node; } else { @@ -326,11 +326,10 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par * @param XMLReader $xmlReader * @param \DOMElement[] $domNodes * @param AbstractContainer $parent - * @param string $docPart - * @param null $paragraphStyle + * @param mixed $paragraphStyle * @param string $formType */ - private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $docPart, $paragraphStyle, $formType) + private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $paragraphStyle, $formType) { if (!in_array($formType, array('textinput', 'checkbox', 'dropdown'))) { return; From 69d786246d082fb51b85f8033f73aa3bd74a99e2 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Mon, 12 Aug 2024 13:47:07 +0200 Subject: [PATCH 4/4] Fixed CI --- docs/changes/2.x/2.0.0.md | 1 + phpstan-baseline.neon | 5 -- src/PhpWord/Reader/Word2007/AbstractPart.php | 34 ++++++----- .../Reader/Word2007/ElementTest.php | 60 +++++++++---------- 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md index 06a7ba3675..e658f1a787 100644 --- a/docs/changes/2.x/2.0.0.md +++ b/docs/changes/2.x/2.0.0.md @@ -8,6 +8,7 @@ - PDF Writer : Documented how to specify a PDF renderer, when working with the PDF writer, as well as the three available choices by [@settermjd](https://github.com/settermjd) in [#2642](https://github.com/PHPOffice/PHPWord/pull/2642) - Word2007 Reader: Support for Paragraph Border Style by [@damienfa](https://github.com/damienfa) in [#2651](https://github.com/PHPOffice/PHPWord/pull/2651) - Word2007 Writer: Support for field REF by [@crystoline](https://github.com/crystoline) in [#2652](https://github.com/PHPOffice/PHPWord/pull/2652) +- Word2007 Reader : Support for FormFields by [@vincentKool](https://github.com/vincentKool) in [#2653](https://github.com/PHPOffice/PHPWord/pull/2653) ### Bug fixes diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 8e47429ad9..026fd8b59a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -235,11 +235,6 @@ parameters: count: 1 path: src/PhpWord/Reader/Word2007/AbstractPart.php - - - message: "#^Parameter \\#1 \\$count of method PhpOffice\\\\PhpWord\\\\Element\\\\AbstractContainer\\:\\:addTextBreak\\(\\) expects int, null given\\.$#" - count: 1 - path: src/PhpWord/Reader/Word2007/AbstractPart.php - - message: "#^Parameter \\#1 \\$depth of method PhpOffice\\\\PhpWord\\\\Element\\\\AbstractContainer\\:\\:addListItemRun\\(\\) expects int, string\\|null given\\.$#" count: 1 diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 4a8af46293..0f3d8bf711 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -196,13 +196,10 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par if ($xmlReader->elementExists('w:r/w:fldChar/w:ffData', $domNode)) { // FormField $partOfFormField = false; - $formNodes = array(); + $formNodes = []; $formType = null; -// $field = new FormField("type", "forntsyle", "paragraphstyle"): $textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag', $domNode); - if (0 === $textRunContainers) { - $parent->addTextBreak(null, $paragraphStyle); - } else { + if ($textRunContainers > 0) { $nodes = $xmlReader->getElements('*', $domNode); $paragraph = $parent->addTextRun($paragraphStyle); foreach ($nodes as $node) { @@ -312,7 +309,7 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par // Text and TextRun $textRunContainers = $xmlReader->countElements('w:r|w:ins|w:del|w:hyperlink|w:smartTag|w:commentReference|w:commentRangeStart|w:commentRangeEnd', $domNode); if (0 === $textRunContainers) { - $parent->addTextBreak(null, $paragraphStyle); + $parent->addTextBreak(1, $paragraphStyle); } else { $nodes = $xmlReader->getElements('*', $domNode); $paragraph = $parent->addTextRun($paragraphStyle); @@ -323,15 +320,14 @@ protected function readParagraph(XMLReader $xmlReader, DOMElement $domNode, $par } /** - * @param XMLReader $xmlReader - * @param \DOMElement[] $domNodes + * @param DOMElement[] $domNodes * @param AbstractContainer $parent * @param mixed $paragraphStyle * @param string $formType */ - private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $paragraphStyle, $formType) + private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $paragraphStyle, $formType): void { - if (!in_array($formType, array('textinput', 'checkbox', 'dropdown'))) { + if (!in_array($formType, ['textinput', 'checkbox', 'dropdown'])) { return; } @@ -339,57 +335,67 @@ private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $ $ffData = $xmlReader->getElement('w:fldChar/w:ffData', $domNodes[0]); foreach ($xmlReader->getElements('*', $ffData) as $node) { - /** @var \DOMElement $node */ + /** @var DOMElement $node */ switch ($node->localName) { case 'name': $formField->setName($node->getAttribute('w:val')); + break; case 'ddList': - $listEntries = array(); + $listEntries = []; foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { case 'result': $formField->setValue($xmlReader->getAttribute('w:val', $ddListNode)); + break; case 'default': $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); + break; case 'listEntry': $listEntries[] = $xmlReader->getAttribute('w:val', $ddListNode); + break; } } $formField->setEntries($listEntries); - if (!is_null($formField->getValue())) { + if (null !== $formField->getValue()) { $formField->setText($listEntries[$formField->getValue()]); } + break; case 'textInput': foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { case 'default': $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); + break; case 'format': case 'maxLength': break; } } + break; case 'checkBox': foreach ($xmlReader->getElements('*', $node) as $ddListNode) { switch ($ddListNode->localName) { case 'default': $formField->setDefault($xmlReader->getAttribute('w:val', $ddListNode)); + break; case 'checked': $formField->setValue($xmlReader->getAttribute('w:val', $ddListNode)); + break; case 'size': case 'sizeAuto': break; } } + break; } } @@ -417,7 +423,7 @@ private function readFormField(XMLReader $xmlReader, array $domNodes, $parent, $ } /** - * Returns the depth of the Heading, returns 0 for a Title + * Returns the depth of the Heading, returns 0 for a Title. * * @return null|number */ diff --git a/tests/PhpWordTests/Reader/Word2007/ElementTest.php b/tests/PhpWordTests/Reader/Word2007/ElementTest.php index 2a867741a9..3685cbea03 100644 --- a/tests/PhpWordTests/Reader/Word2007/ElementTest.php +++ b/tests/PhpWordTests/Reader/Word2007/ElementTest.php @@ -357,9 +357,9 @@ public function testReadDrawing(): void } /** - * Test reading FormField - DROPDOWN + * Test reading FormField - DROPDOWN. */ - public function testReadFormFieldDropdown() + public function testReadFormFieldDropdown(): void { $documentXml = ' @@ -404,28 +404,28 @@ public function testReadFormFieldDropdown() '; - $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + $phpWord = $this->getDocumentFromString(['document' => $documentXml]); $elements = $phpWord->getSection(0)->getElements(); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + self::assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); $subElements = $elements[0]->getElements(); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); - $this->assertEquals('Reference', $subElements[0]->getText()); + self::assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); + self::assertEquals('Reference', $subElements[0]->getText()); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); - $this->assertEquals('dropdown', $subElements[1]->getType()); - $this->assertEquals('DropDownList1', $subElements[1]->getName()); - $this->assertEquals('2', $subElements[1]->getValue()); - $this->assertEquals('Option Two', $subElements[1]->getText()); - $this->assertEquals(array('TBD', 'Option One', 'Option Two', 'Option Three', 'Other'), $subElements[1]->getEntries()); + self::assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); + self::assertEquals('dropdown', $subElements[1]->getType()); + self::assertEquals('DropDownList1', $subElements[1]->getName()); + self::assertEquals('2', $subElements[1]->getValue()); + self::assertEquals('Option Two', $subElements[1]->getText()); + self::assertEquals(['TBD', 'Option One', 'Option Two', 'Option Three', 'Other'], $subElements[1]->getEntries()); } /** - * Test reading FormField - textinput + * Test reading FormField - textinput. */ - public function testReadFormFieldTextinput() + public function testReadFormFieldTextinput(): void { $documentXml = ' @@ -473,27 +473,27 @@ public function testReadFormFieldTextinput() '; - $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + $phpWord = $this->getDocumentFromString(['document' => $documentXml]); $elements = $phpWord->getSection(0)->getElements(); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + self::assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); $subElements = $elements[0]->getElements(); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); - $this->assertEquals('Fieldname', $subElements[0]->getText()); + self::assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); + self::assertEquals('Fieldname', $subElements[0]->getText()); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); - $this->assertEquals('textinput', $subElements[1]->getType()); - $this->assertEquals('TextInput2', $subElements[1]->getName()); - $this->assertEquals('This is some sample text', $subElements[1]->getValue()); - $this->assertEquals('This is some sample text', $subElements[1]->getText()); + self::assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[1]); + self::assertEquals('textinput', $subElements[1]->getType()); + self::assertEquals('TextInput2', $subElements[1]->getName()); + self::assertEquals('This is some sample text', $subElements[1]->getValue()); + self::assertEquals('This is some sample text', $subElements[1]->getText()); } /** - * Test reading FormField - checkbox + * Test reading FormField - checkbox. */ - public function testReadFormFieldCheckbox() + public function testReadFormFieldCheckbox(): void { $documentXml = ' @@ -529,18 +529,18 @@ public function testReadFormFieldCheckbox() '; - $phpWord = $this->getDocumentFromString(array('document' => $documentXml)); + $phpWord = $this->getDocumentFromString(['document' => $documentXml]); $elements = $phpWord->getSection(0)->getElements(); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); + self::assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]); $subElements = $elements[0]->getElements(); // $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $subElements[0]); // $this->assertEquals('Fieldname', $subElements[0]->getText()); - $this->assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[0]); - $this->assertEquals('checkbox', $subElements[0]->getType()); - $this->assertEquals('SomeCheckbox', $subElements[0]->getName()); + self::assertInstanceOf('PhpOffice\PhpWord\Element\FormField', $subElements[0]); + self::assertEquals('checkbox', $subElements[0]->getType()); + self::assertEquals('SomeCheckbox', $subElements[0]->getName()); } }