diff --git a/CHANGELOG.md b/CHANGELOG.md index fce2bdac..58dd0aff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3; new r - PDF Writer: Add TCPDF and mPDF as optional PDF renderer library - @ivanlanin - ODT Writer: Enable title element and custom document properties - @ivanlanin - ODT Reader: Ability to read standard and custom document properties - @ivanlanin +- Word2007 Writer: Enable the missing custom document properties writer - @ivanlanin ### Bugfixes diff --git a/src/PhpWord/Shared/XMLWriter.php b/src/PhpWord/Shared/XMLWriter.php index 683e09c0..dc85bfc1 100644 --- a/src/PhpWord/Shared/XMLWriter.php +++ b/src/PhpWord/Shared/XMLWriter.php @@ -58,11 +58,6 @@ class XMLWriter */ public function __construct($tempLocation = self::STORAGE_MEMORY, $tempFolder = './') { - // Define date format - if (!defined('DATE_W3C')) { - define('DATE_W3C', 'Y-m-d\TH:i:sP'); - } - // Create internal XMLWriter $this->xmlWriter = new \XMLWriter(); diff --git a/src/PhpWord/Writer/ODText/Part/AbstractPart.php b/src/PhpWord/Writer/ODText/Part/AbstractPart.php index d5397ffd..31118ef9 100644 --- a/src/PhpWord/Writer/ODText/Part/AbstractPart.php +++ b/src/PhpWord/Writer/ODText/Part/AbstractPart.php @@ -28,6 +28,11 @@ use PhpOffice\PhpWord\Writer\Word2007\Part\AbstractPart as Word2007AbstractPart; */ abstract class AbstractPart extends Word2007AbstractPart { + /** + * @var string Date format + */ + protected $dateFormat = 'Y-m-d\TH:i:s.000'; + /** * Write common root attributes */ diff --git a/src/PhpWord/Writer/ODText/Part/Meta.php b/src/PhpWord/Writer/ODText/Part/Meta.php index 50a38047..0d240a68 100644 --- a/src/PhpWord/Writer/ODText/Part/Meta.php +++ b/src/PhpWord/Writer/ODText/Part/Meta.php @@ -53,12 +53,12 @@ class Meta extends AbstractPart $xmlWriter->writeElement('dc:subject', $docProps->getSubject()); $xmlWriter->writeElement('dc:description', $docProps->getDescription()); $xmlWriter->writeElement('dc:creator', $docProps->getLastModifiedBy()); - $xmlWriter->writeElement('dc:date', gmdate('Y-m-d\TH:i:s.000', $docProps->getModified())); + $xmlWriter->writeElement('dc:date', gmdate($this->dateFormat, $docProps->getModified())); // Extended properties $xmlWriter->writeElement('meta:generator', 'PHPWord'); $xmlWriter->writeElement('meta:initial-creator', $docProps->getCreator()); - $xmlWriter->writeElement('meta:creation-date', gmdate('Y-m-d\TH:i:s.000', $docProps->getCreated())); + $xmlWriter->writeElement('meta:creation-date', gmdate($this->dateFormat, $docProps->getCreated())); $xmlWriter->writeElement('meta:keyword', $docProps->getKeywords()); // Category, company, and manager are put in meta namespace diff --git a/src/PhpWord/Writer/Word2007.php b/src/PhpWord/Writer/Word2007.php index 7d3c73bc..751b58b6 100644 --- a/src/PhpWord/Writer/Word2007.php +++ b/src/PhpWord/Writer/Word2007.php @@ -53,23 +53,24 @@ class Word2007 extends AbstractWriter implements WriterInterface // Create parts $this->parts = array( - 'ContentTypes' => '[Content_Types].xml', - 'Rels' => '_rels/.rels', - 'DocPropsApp' => 'docProps/app.xml', - 'DocPropsCore' => 'docProps/core.xml', - 'RelsDocument' => 'word/_rels/document.xml.rels', - 'Document' => 'word/document.xml', - 'Styles' => 'word/styles.xml', - 'Numbering' => 'word/numbering.xml', - 'Settings' => 'word/settings.xml', - 'WebSettings' => 'word/webSettings.xml', - 'FontTable' => 'word/fontTable.xml', - 'Theme' => 'word/theme/theme1.xml', - 'RelsPart' => '', - 'Header' => '', - 'Footer' => '', - 'Footnotes' => '', - 'Endnotes' => '', + 'ContentTypes' => '[Content_Types].xml', + 'Rels' => '_rels/.rels', + 'DocPropsApp' => 'docProps/app.xml', + 'DocPropsCore' => 'docProps/core.xml', + 'DocPropsCustom' => 'docProps/custom.xml', + 'RelsDocument' => 'word/_rels/document.xml.rels', + 'Document' => 'word/document.xml', + 'Styles' => 'word/styles.xml', + 'Numbering' => 'word/numbering.xml', + 'Settings' => 'word/settings.xml', + 'WebSettings' => 'word/webSettings.xml', + 'FontTable' => 'word/fontTable.xml', + 'Theme' => 'word/theme/theme1.xml', + 'RelsPart' => '', + 'Header' => '', + 'Footer' => '', + 'Footnotes' => '', + 'Endnotes' => '', ); foreach (array_keys($this->parts) as $partName) { $partClass = get_class($this) . '\\Part\\' . $partName; diff --git a/src/PhpWord/Writer/Word2007/Part/AbstractPart.php b/src/PhpWord/Writer/Word2007/Part/AbstractPart.php index fbd4a6e5..610a7616 100644 --- a/src/PhpWord/Writer/Word2007/Part/AbstractPart.php +++ b/src/PhpWord/Writer/Word2007/Part/AbstractPart.php @@ -33,6 +33,11 @@ abstract class AbstractPart */ protected $parentWriter; + /** + * @var string Date format + */ + protected $dateFormat = 'Y-m-d\TH:i:sP'; + /** * Write part * diff --git a/src/PhpWord/Writer/Word2007/Part/ContentTypes.php b/src/PhpWord/Writer/Word2007/Part/ContentTypes.php index f8cb2f26..b6f23f47 100644 --- a/src/PhpWord/Writer/Word2007/Part/ContentTypes.php +++ b/src/PhpWord/Writer/Word2007/Part/ContentTypes.php @@ -40,6 +40,7 @@ class ContentTypes extends AbstractPart $overrides = array( '/docProps/core.xml' => $openXMLPrefix . 'package.core-properties+xml', '/docProps/app.xml' => $openXMLPrefix . 'officedocument.extended-properties+xml', + '/docProps/custom.xml' => $openXMLPrefix . 'officedocument.custom-properties+xml', '/word/document.xml' => $wordMLPrefix . 'document.main+xml', '/word/styles.xml' => $wordMLPrefix . 'styles+xml', '/word/numbering.xml' => $wordMLPrefix . 'numbering+xml', diff --git a/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php b/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php index 2b3bce5a..38f6d235 100644 --- a/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php +++ b/src/PhpWord/Writer/Word2007/Part/DocPropsCore.php @@ -54,13 +54,13 @@ class DocPropsCore extends AbstractPart // dcterms:created $xmlWriter->startElement('dcterms:created'); $xmlWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $xmlWriter->writeRaw(date(DATE_W3C, $phpWord->getDocumentProperties()->getCreated())); + $xmlWriter->writeRaw(date($this->dateFormat, $phpWord->getDocumentProperties()->getCreated())); $xmlWriter->endElement(); // dcterms:modified $xmlWriter->startElement('dcterms:modified'); $xmlWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); - $xmlWriter->writeRaw(date(DATE_W3C, $phpWord->getDocumentProperties()->getModified())); + $xmlWriter->writeRaw(date($this->dateFormat, $phpWord->getDocumentProperties()->getModified())); $xmlWriter->endElement(); $xmlWriter->endElement(); // cp:coreProperties diff --git a/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php b/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php new file mode 100644 index 00000000..c5a3cf9e --- /dev/null +++ b/src/PhpWord/Writer/Word2007/Part/DocPropsCustom.php @@ -0,0 +1,78 @@ +getParentWriter()->getPhpWord(); + $xmlWriter = $this->getXmlWriter(); + + $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); + $xmlWriter->startElement('Properties'); + $xmlWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); + $xmlWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + $docProps = $phpWord->getDocumentProperties(); + $properties = $docProps->getCustomProperties(); + foreach ($properties as $key => $property) { + $propertyValue = $docProps->getCustomPropertyValue($property); + $propertyType = $docProps->getCustomPropertyType($property); + + $xmlWriter->startElement('property'); + $xmlWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); + $xmlWriter->writeAttribute('pid', $key + 2); + $xmlWriter->writeAttribute('name', $property); + switch ($propertyType) { + case 'i': + $xmlWriter->writeElement('vt:i4', $propertyValue); + break; + case 'f': + $xmlWriter->writeElement('vt:r8', $propertyValue); + break; + case 'b': + $xmlWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); + break; + case 'd': + $xmlWriter->startElement('vt:filetime'); + $xmlWriter->writeRaw(date($this->dateFormat, $propertyValue)); + $xmlWriter->endElement(); + break; + default: + $xmlWriter->writeElement('vt:lpwstr', $propertyValue); + break; + } + $xmlWriter->endElement(); // property + } + + $xmlWriter->endElement(); // Properties + + return $xmlWriter->getData(); + } +} diff --git a/src/PhpWord/Writer/Word2007/Part/Rels.php b/src/PhpWord/Writer/Word2007/Part/Rels.php index af57a768..c1405258 100644 --- a/src/PhpWord/Writer/Word2007/Part/Rels.php +++ b/src/PhpWord/Writer/Word2007/Part/Rels.php @@ -35,9 +35,10 @@ class Rels extends AbstractPart public function write() { $xmlRels = array( - 'docProps/core.xml' => 'package/2006/relationships/metadata/core-properties', - 'docProps/app.xml' => 'officeDocument/2006/relationships/extended-properties', - 'word/document.xml' => 'officeDocument/2006/relationships/officeDocument', + 'docProps/core.xml' => 'package/2006/relationships/metadata/core-properties', + 'docProps/app.xml' => 'officeDocument/2006/relationships/extended-properties', + 'docProps/custom.xml' => 'officeDocument/2006/relationships/custom-properties', + 'word/document.xml' => 'officeDocument/2006/relationships/officeDocument', ); $xmlWriter = $this->getXmlWriter(); $this->writeRels($xmlWriter, $xmlRels);