diff --git a/CHANGELOG.md b/CHANGELOG.md index 22f22dd9..6f9bf239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This release added form fields (textinput, checkbox, and dropdown), drawing shap - FormField: Ability to add textinput, checkbox, and dropdown form elements - @ivanlanin GH-266 - Setting: Ability to define document protection (readOnly, comments, trackedChanges, forms) - @ivanlanin - Setting: Ability to remove [Compatibility Mode] text in the MS Word title bar - @ivanlanin +- SDT: Ability to add structured document tag elements (comboBox, dropDownList, date) - @ivanlanin ### Bugfixes diff --git a/samples/Sample_34_SDT.php b/samples/Sample_34_SDT.php index fc1e7de6..241dee2a 100644 --- a/samples/Sample_34_SDT.php +++ b/samples/Sample_34_SDT.php @@ -4,11 +4,20 @@ include_once 'Sample_Header.php'; // New Word document echo date('H:i:s'), " Create new PhpWord object", EOL; $phpWord = new \PhpOffice\PhpWord\PhpWord(); -$phpWord->getProtection()->setEditing('forms'); $section = $phpWord->addSection(); -$section->addSDT('comboBox')->setListItems(array('1' => 'Choice 1', '2' => 'Choice 2')); +$textrun = $section->addTextRun(); +$textrun->addText('Combobox: '); +$textrun->addSDT('comboBox')->setListItems(array('1' => 'Choice 1', '2' => 'Choice 2')); + +$textrun = $section->addTextRun(); +$textrun->addText('Date: '); +$textrun->addSDT('date'); + +$textrun = $section->addTextRun(); +$textrun->addText('Drop down list: '); +$textrun->addSDT('dropDownList')->setListItems(array('1' => 'Choice 1', '2' => 'Choice 2')); // Save file echo write($phpWord, basename(__FILE__, '.php'), $writers); diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index afde4270..b934b2d8 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -193,6 +193,7 @@ abstract class AbstractContainer extends AbstractElement 'Line' => $allContainers, 'Shape' => $allContainers, 'FormField' => $allContainers, + 'SDT' => $allContainers, 'TextRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'ListItem' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'ListItemRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), @@ -206,7 +207,6 @@ abstract class AbstractContainer extends AbstractElement 'TOC' => array('Section'), 'PageBreak' => array('Section'), 'Chart' => array('Section'), - 'SDT' => array('Section'), ); // Special condition, e.g. preservetext can only exists in cell when // the cell is located in header or footer diff --git a/src/PhpWord/Writer/Word2007/Element/SDT.php b/src/PhpWord/Writer/Word2007/Element/SDT.php index d25eaf98..94578e16 100644 --- a/src/PhpWord/Writer/Word2007/Element/SDT.php +++ b/src/PhpWord/Writer/Word2007/Element/SDT.php @@ -39,33 +39,72 @@ class SDT extends Text return; } $type = $element->getType(); - $listItems = $element->getListItems(); + $writeFormField = "write{$type}"; $this->startElementP(); $xmlWriter->startElement('w:sdt'); + // Properties $xmlWriter->startElement('w:sdtPr'); $xmlWriter->writeElementBlock('w:id', 'w:val', rand(100000000, 999999999)); $xmlWriter->writeElementBlock('w:lock', 'w:val', 'sdtLocked'); - - $xmlWriter->startElement('w:placeholder'); - $xmlWriter->writeElementBlock('w:docPart', 'w:val', 'string'); - $xmlWriter->endElement(); // w:placeholder - - $xmlWriter->startElement("w:{$type}"); - foreach ($listItems as $key => $val) { - $xmlWriter->writeElementBlock('w:listItem', array('w:value' => $key, 'w:displayText' => $val)); - } - $xmlWriter->endElement(); // w:{$type} - + $this->$writeFormField($xmlWriter, $element); $xmlWriter->endElement(); // w:sdtPr + // Content $xmlWriter->startElement('w:sdtContent'); + $xmlWriter->startElement('w:r'); + $xmlWriter->startElement('w:t'); + $xmlWriter->writeRaw('Pick value'); + $xmlWriter->endElement(); // w:t + $xmlWriter->endElement(); // w:r $xmlWriter->endElement(); // w:sdtContent $xmlWriter->endElement(); // w:sdt $this->endElementP(); // w:p } + + /** + * Write combo box + * + * @link http://www.datypic.com/sc/ooxml/t-w_CT_SdtComboBox.html + */ + private function writeComboBox(XMLWriter $xmlWriter, SDTElement $element) + { + $type = $element->getType(); + $listItems = $element->getListItems(); + + $xmlWriter->startElement("w:{$type}"); + foreach ($listItems as $key => $val) { + $xmlWriter->writeElementBlock('w:listItem', array('w:value' => $key, 'w:displayText' => $val)); + } + $xmlWriter->endElement(); // w:{$type} + } + + /** + * Write drop down list + * + * @link http://www.datypic.com/sc/ooxml/t-w_CT_SdtDropDownList.html + */ + private function writeDropDownList(XMLWriter $xmlWriter, SDTElement $element) + { + $this->writecomboBox($xmlWriter, $element); + } + + /** + * Write date + * + * @link http://www.datypic.com/sc/ooxml/t-w_CT_SdtDate.html + */ + private function writeDate(XMLWriter $xmlWriter, SDTElement $element) + { + $xmlWriter->startElement("w:date"); + $xmlWriter->writeElementBlock('w:dateFormat', 'w:val', 'd/M/yyyy'); + $xmlWriter->writeElementBlock('w:lid', 'w:val', 'en-US'); + $xmlWriter->writeElementBlock('w:storeMappedDataAs', 'w:val', 'dateTime'); + $xmlWriter->writeElementBlock('w:calendar', 'w:val', 'gregorian'); + $xmlWriter->endElement(); // w:date + } } diff --git a/tests/PhpWord/Tests/Writer/Word2007/ElementTest.php b/tests/PhpWord/Tests/Writer/Word2007/ElementTest.php index 752415a1..92a74c15 100644 --- a/tests/PhpWord/Tests/Writer/Word2007/ElementTest.php +++ b/tests/PhpWord/Tests/Writer/Word2007/ElementTest.php @@ -196,4 +196,24 @@ class ElementTest extends \PHPUnit_Framework_TestCase $this->assertTrue($doc->elementExists($path . '/w:checkBox')); $this->assertTrue($doc->elementExists($path . '/w:ddList')); } + + /** + * Test SDT elements + */ + public function testSDTElements() + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + + $section->addSDT('comboBox'); + $section->addSDT('dropDownList'); + $section->addSDT('date'); + + $doc = TestHelperDOCX::getDocument($phpWord); + + $path = "/w:document/w:body/w:p/w:sdt/w:sdtPr"; + $this->assertTrue($doc->elementExists($path . '/w:comboBox')); + $this->assertTrue($doc->elementExists($path . '/w:dropDownList')); + $this->assertTrue($doc->elementExists($path . '/w:date')); + } }