From ad58e726e53e4eabf124515084c1b9aa1c1cb4e4 Mon Sep 17 00:00:00 2001 From: Bruno Casado Date: Mon, 20 Jan 2014 10:55:54 -0200 Subject: [PATCH 01/29] Add some tests to new wrapping image --- samples/Sample_03_Image.php | 107 +++++++++++++++++++++++++++++++++ samples/assets/img/flowers.jpg | Bin 0 -> 126991 bytes 2 files changed, 107 insertions(+) create mode 100644 samples/Sample_03_Image.php create mode 100644 samples/assets/img/flowers.jpg diff --git a/samples/Sample_03_Image.php b/samples/Sample_03_Image.php new file mode 100644 index 00000000..2d6b8bcd --- /dev/null +++ b/samples/Sample_03_Image.php @@ -0,0 +1,107 @@ +'); +} + +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , ' Create new PHPWord object' , EOL; +$PHPWord = new PHPWord(); + +// Create a new Section +$section = $PHPWord->createSection(); + +// Behind Test +$section->addText('Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!'); +$section->addImage( + 'assets/img/flowers.jpg', + array( + 'width' => 400, + 'height' => 400, + 'marginTop' => -1, + 'marginLeft' => 1, + 'wrappingStyle' => PHPWord_Style_Image::WRAPPING_STYLE_BEHIND + ) +); + +// Square Test +$section = $PHPWord->createSection(); +$section->addText('Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!'); +$section->addImage( + 'assets/img/flowers.jpg', + array( + 'width' => 400, + 'height' => 400, + 'marginTop' => -1, + 'marginLeft' => 1, + 'wrappingStyle' => PHPWord_Style_Image::WRAPPING_STYLE_SQUARE + ) +); + +// tight Test +$section = $PHPWord->createSection(); +$section->addText('Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!'); +$section->addImage( + 'assets/img/flowers.jpg', + array( + 'width' => 400, + 'height' => 400, + 'marginTop' => -1, + 'marginLeft' => 1, + 'wrappingStyle' => PHPWord_Style_Image::WRAPPING_STYLE_TIGHT + ) +); + +// infront Test +$section = $PHPWord->createSection(); +$section->addText('Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!'); +$section->addImage( + 'assets/img/flowers.jpg', + array( + 'width' => 400, + 'height' => 400, + 'marginTop' => -1, + 'marginLeft' => 1, + 'wrappingStyle' => PHPWord_Style_Image::WRAPPING_STYLE_INFRONT + ) +); + +// inline Test +$section = $PHPWord->createSection(); +$section->addText('Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World! Hello World!'); +$section->addImage( + 'assets/img/flowers.jpg', + array( + 'width' => 400, + 'height' => 400, + 'align' => "center", + 'wrappingStyle' => PHPWord_Style_Image::WRAPPING_STYLE_INLINE + ) +); + +// Save File +echo date('H:i:s') , ' Write to Word2007 format' , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); +$objWriter->save(str_replace('.php', '.docx', __FILE__)); + +echo date('H:i:s') , ' Write to OpenDocumentText format' , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); +$objWriter->save(str_replace('.php', '.odt', __FILE__)); + +echo date('H:i:s') , ' Write to RTF format' , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); +$objWriter->save(str_replace('.php', '.rtf', __FILE__)); + + +// Echo memory peak usage +echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , ' MB' , EOL; + +// Echo done +echo date('H:i:s') , ' Done writing file' , EOL; \ No newline at end of file diff --git a/samples/assets/img/flowers.jpg b/samples/assets/img/flowers.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd55c65e0e8ebc037831766083f7349b71b6f603 GIT binary patch literal 126991 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 literal 0 HcmV?d00001 From 833dfea1e00adb8978d5a585fbb2052ade5b029e Mon Sep 17 00:00:00 2001 From: japonicus Date: Tue, 8 Apr 2014 17:42:01 +0100 Subject: [PATCH 02/29] Keep image aspect ratio if only 1 dimension styled If only one of image width or height is specified, then scale missing dimension to maintain the aspect ratio. --- src/PhpWord/Element/Image.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Element/Image.php b/src/PhpWord/Element/Image.php index d49972d2..611b36b3 100755 --- a/src/PhpWord/Element/Image.php +++ b/src/PhpWord/Element/Image.php @@ -131,9 +131,17 @@ class Image extends AbstractElement $this->source = $source; $this->isWatermark = $isWatermark; $this->style = $this->setStyle(new ImageStyle(), $style, true); - if ($this->style->getWidth() == null && $this->style->getHeight() == null) { - $this->style->setWidth($imgData[0]); - $this->style->setHeight($imgData[1]); + $styleWidth = $this->style->getWidth(); + $styleHeight = $this->style->getHeight(); + if (!($styleWidth && $styleHeight)) { + if ($styleWidth == null && $styleHeight == null) { + $this->style->setWidth($imgData[0]); + $this->style->setHeight($imgData[1]); + } else if ($styleWidth) { + $this->style->setHeight($imgData[1] * ($styleWidth / $imgData[0])); + } else { + $this->style->setWidth($imgData[0] * ($styleHeight / $imgData[1])); + } } $this->setImageFunctions(); } From 47669f501abfd2fd23346a814b2b68b43ee24390 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 16:16:22 +0700 Subject: [PATCH 03/29] Ability to create custom list #10 and to read list definition from DOCX --- CHANGELOG.md | 5 +- samples/Sample_14_ListItem.php | 73 ++-- src/PhpWord/Element/AbstractElement.php | 3 - src/PhpWord/Element/ListItem.php | 18 +- src/PhpWord/Endnotes.php | 1 - src/PhpWord/PhpWord.php | 11 + src/PhpWord/Reader/Word2007.php | 155 ++++++- src/PhpWord/Shared/XMLReader.php | 14 +- src/PhpWord/Style.php | 43 +- src/PhpWord/Style/AbstractStyle.php | 117 +++++- src/PhpWord/Style/ListItem.php | 220 +++++++++- src/PhpWord/Style/Numbering.php | 123 ++++++ src/PhpWord/Style/NumberingLevel.php | 378 ++++++++++++++++++ src/PhpWord/Template.php | 2 +- src/PhpWord/Writer/Word2007.php | 17 +- src/PhpWord/Writer/Word2007/Base.php | 4 +- src/PhpWord/Writer/Word2007/Notes.php | 5 +- src/PhpWord/Writer/Word2007/Numbering.php | 177 ++++++++ src/PhpWord/Writer/Word2007/Styles.php | 36 +- src/PhpWord/_staticDocParts/numbering.xml | 2 - .../Tests/Writer/Word2007/DocumentTest.php | 10 +- 21 files changed, 1276 insertions(+), 138 deletions(-) create mode 100644 src/PhpWord/Style/Numbering.php create mode 100644 src/PhpWord/Style/NumberingLevel.php create mode 100644 src/PhpWord/Writer/Word2007/Numbering.php delete mode 100644 src/PhpWord/_staticDocParts/numbering.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 72b93e7b..f96b4a63 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers ## 0.9.2 - Not yet released -This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. +This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. ### Features @@ -27,8 +27,9 @@ This release marked heavy refactorings on internal code structure with the creat - Object: Ability to add object in header, footer, textrun, and footnote - @ivanlanin GH-187 - Media: Add `Media::resetElements()` to reset all media data - @juzi GH-19 - General: Add `Style::resetStyles()`, `Footnote::resetElements()`, and `TOC::resetTitles()` - @ivanlanin GH-187 -- Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table - @ivanlanin +- Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table, and list - @ivanlanin - Endnote: Ability to add endnotes - @ivanlanin +- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 ### Bugfixes diff --git a/samples/Sample_14_ListItem.php b/samples/Sample_14_ListItem.php index 4cd9edea..45d9c1a7 100644 --- a/samples/Sample_14_ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -8,41 +8,52 @@ $phpWord = new \PhpOffice\PhpWord\PhpWord(); // Begin code $section = $phpWord->addSection(); -// Add listitem elements -$section->addListItem('List Item 1', 0); -$section->addListItem('List Item 2', 0); -$section->addListItem('List Item 3', 0); -$section->addTextBreak(2); +// Style definition -// Add listitem elements -$section->addListItem('List Item 1', 0); -$section->addListItem('List Item 1.1', 1); -$section->addListItem('List Item 1.2', 1); -$section->addListItem('List Item 1.3 (styled)', 1, array('bold'=>true)); -$section->addListItem('List Item 1.3.1', 2); -$section->addListItem('List Item 1.3.2', 2); -$section->addTextBreak(2); - -// Add listitem elements -$listStyle = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER); -$section->addListItem('List Item 1', 0, null, $listStyle); -$section->addListItem('List Item 2', 0, null, $listStyle); -$section->addListItem('List Item 3', 0, null, $listStyle); -$section->addTextBreak(2); - -// Add listitem elements $phpWord->addFontStyle('myOwnStyle', array('color'=>'FF0000')); $phpWord->addParagraphStyle('P-Style', array('spaceAfter'=>95)); -$listStyle = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED); -$section->addListItem('List Item 1', 0, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 2', 0, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 3', 1, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 4', 1, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 5', 2, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 6', 1, 'myOwnStyle', $listStyle, 'P-Style'); -$section->addListItem('List Item 7', 0, 'myOwnStyle', $listStyle, 'P-Style'); +$phpWord->addNumberingStyle( + 'multilevel', + array('type' => 'multilevel', 'levels' => array( + array('format' => 'decimal', 'text' => '%1.', 'left' => 360, 'hanging' => 360, 'tabPos' => 360), + array('format' => 'upperLetter', 'text' => '%2.', 'left' => 720, 'hanging' => 360, 'tabPos' => 720), + ) + ) +); +$predefinedMultilevel = array('listType' => \PhpOffice\PhpWord\Style\ListItem::TYPE_NUMBER_NESTED); + +// Lists + +$section->addText('Multilevel list.'); +$section->addListItem('List Item I', 0, null, 'multilevel'); +$section->addListItem('List Item I.a', 1, null, 'multilevel'); +$section->addListItem('List Item I.b', 1, null, 'multilevel'); +$section->addListItem('List Item II', 0, null, 'multilevel'); +$section->addListItem('List Item II.a', 1, null, 'multilevel'); +$section->addListItem('List Item III', 0, null, 'multilevel'); +$section->addTextBreak(2); + +$section->addText('Basic simple bulleted list.'); +$section->addListItem('List Item 1'); +$section->addListItem('List Item 2'); +$section->addListItem('List Item 3'); +$section->addTextBreak(2); + +$section->addText('Continue from multilevel list above.'); +$section->addListItem('List Item IV', 0, null, 'multilevel'); +$section->addListItem('List Item IV.a', 1, null, 'multilevel'); +$section->addTextBreak(2); + +$section->addText('Multilevel predefined list.'); +$section->addListItem('List Item 1', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 2', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 3', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 4', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 5', 2, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 6', 1, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addListItem('List Item 7', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); +$section->addTextBreak(2); -// End code // Save file $name = basename(__FILE__, '.php'); diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index 56505cbc..6562cb5b 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -469,9 +469,6 @@ abstract class AbstractElement { if (!is_null($styleValue) && is_array($styleValue)) { foreach ($styleValue as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } $styleObject->setStyleValue($key, $value); } $style = $styleObject; diff --git a/src/PhpWord/Element/ListItem.php b/src/PhpWord/Element/ListItem.php index 5d19097e..39bd6b1b 100644 --- a/src/PhpWord/Element/ListItem.php +++ b/src/PhpWord/Element/ListItem.php @@ -44,15 +44,21 @@ class ListItem extends AbstractElement * * @param string $text * @param int $depth - * @param mixed $styleFont - * @param mixed $styleList - * @param mixed $styleParagraph + * @param mixed $fontStyle + * @param array|string|null $listStyle + * @param mixed $paragraphStyle */ - public function __construct($text, $depth = 0, $styleFont = null, $styleList = null, $styleParagraph = null) + public function __construct($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null) { - $this->textObject = new Text($text, $styleFont, $styleParagraph); + $this->textObject = new Text($text, $fontStyle, $paragraphStyle); $this->depth = $depth; - $this->style = $this->setStyle(new ListItemStyle(), $styleList, true); + + // Version >= 0.9.2 will pass numbering style name. Older version will use old method + if (!is_null($listStyle) && is_string($listStyle)) { + $this->style = new ListItemStyle($listStyle); + } else { + $this->style = $this->setStyle(new ListItemStyle(), $listStyle, true); + } } /** diff --git a/src/PhpWord/Endnotes.php b/src/PhpWord/Endnotes.php index 86c923d3..4a065b96 100644 --- a/src/PhpWord/Endnotes.php +++ b/src/PhpWord/Endnotes.php @@ -9,7 +9,6 @@ namespace PhpOffice\PhpWord; -use PhpOffice\PhpWord\Media; use PhpOffice\PhpWord\Element\Endnote; /** diff --git a/src/PhpWord/PhpWord.php b/src/PhpWord/PhpWord.php index c9bf4b63..2764a3a1 100644 --- a/src/PhpWord/PhpWord.php +++ b/src/PhpWord/PhpWord.php @@ -214,6 +214,17 @@ class PhpWord Style::addLinkStyle($styleName, $styles); } + /** + * Adds a numbering style + * + * @param string $styleName + * @param mixed $styles + */ + public function addNumberingStyle($styleName, $styles) + { + Style::addNumberingStyle($styleName, $styles); + } + /** * Get all sections * diff --git a/src/PhpWord/Reader/Word2007.php b/src/PhpWord/Reader/Word2007.php index 36c81c3b..e03d28a0 100644 --- a/src/PhpWord/Reader/Word2007.php +++ b/src/PhpWord/Reader/Word2007.php @@ -11,8 +11,6 @@ namespace PhpOffice\PhpWord\Reader; use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\Settings; -use PhpOffice\PhpWord\Footnote; -use PhpOffice\PhpWord\Endnotes; use PhpOffice\PhpWord\DocumentProperties; use PhpOffice\PhpWord\Shared\XMLReader; use PhpOffice\PhpWord\Element\Section; @@ -52,6 +50,19 @@ class Word2007 extends AbstractReader implements ReaderInterface $this->readRelationships($filename); + + // Read styles and numbering first + foreach ($this->rels['document'] as $rId => $rel) { + switch ($rel['type']) { + case 'styles': + $this->readStyles($filename, $rel['target']); + break; + case 'numbering': + $this->readNumbering($filename, $rel['target']); + break; + } + } + // Read main relationship foreach ($this->rels['main'] as $rId => $rel) { switch ($rel['type']) { @@ -87,14 +98,9 @@ class Word2007 extends AbstractReader implements ReaderInterface } } - // Read document relationships + // Read footnotes and endnotes foreach ($this->rels['document'] as $rId => $rel) { switch ($rel['type']) { - - case 'styles': - $this->readStyles($filename, $rel['target']); - break; - case 'footnotes': case 'endnotes': $this->readNotes($filename, $rel['target'], $rel['type']); @@ -178,7 +184,6 @@ class Word2007 extends AbstractReader implements ReaderInterface $nodes = $xmlReader->getElements('*'); if ($nodes->length > 0) { foreach ($nodes as $node) { - $nodeName = $node->nodeName; $propertyName = $xmlReader->getAttribute('name', $node); $attributeNode = $xmlReader->getElement('*', $node); $attributeType = $attributeNode->nodeName; @@ -206,6 +211,7 @@ class Word2007 extends AbstractReader implements ReaderInterface $section = $this->phpWord->addSection(); foreach ($nodes as $node) { switch ($node->nodeName) { + case 'w:p': // Paragraph if ($xmlReader->getAttribute('w:type', $node, 'w:r/w:br') == 'page') { $section->addPageBreak(); // PageBreak @@ -221,9 +227,11 @@ class Word2007 extends AbstractReader implements ReaderInterface $section = $this->phpWord->addSection(); } break; + case 'w:tbl': // Table $this->readTable($xmlReader, $node, $section, 'document'); break; + case 'w:sectPr': // Last section $settings = $this->readSectionStyle($xmlReader, $node); $section->setSettings($settings); @@ -255,6 +263,7 @@ class Word2007 extends AbstractReader implements ReaderInterface } // $default = ($xmlReader->getAttribute('w:default', $node) == 1); switch ($type) { + case 'paragraph': $pStyle = $this->readParagraphStyle($xmlReader, $node); $fStyle = $this->readFontStyle($xmlReader, $node); @@ -264,12 +273,14 @@ class Word2007 extends AbstractReader implements ReaderInterface $this->phpWord->addFontStyle($name, $fStyle, $pStyle); } break; + case 'character': $fStyle = $this->readFontStyle($xmlReader, $node); if (!empty($fStyle)) { $this->phpWord->addFontStyle($name, $fStyle); } break; + case 'table': $tStyle = $this->readTableStyle($xmlReader, $node); if (!empty($tStyle)) { @@ -281,6 +292,98 @@ class Word2007 extends AbstractReader implements ReaderInterface } } + /** + * Read numbering.xml + * + * @param string $filename + * @param string $xmlFile + */ + private function readNumbering($filename, $xmlFile) + { + $abstracts = array(); + $numberings = array(); + $xmlReader = new XMLReader(); + $xmlReader->getDomFromZip($filename, $xmlFile); + + // Abstract numbering definition + $nodes = $xmlReader->getElements('w:abstractNum'); + if ($nodes->length > 0) { + foreach ($nodes as $node) { + $abstractId = $xmlReader->getAttribute('w:abstractNumId', $node); + $abstracts[$abstractId] = array('levels' => array()); + $abstract = &$abstracts[$abstractId]; + $subnodes = $xmlReader->getElements('*', $node); + foreach ($subnodes as $subnode) { + switch ($subnode->nodeName) { + case 'w:multiLevelType': + $abstract['type'] = $xmlReader->getAttribute('w:val', $subnode); + break; + case 'w:lvl': + $levelId = $xmlReader->getAttribute('w:ilvl', $subnode); + $abstract['levels'][$levelId] = $this->readNumberingLevel($xmlReader, $subnode, $levelId); + break; + } + } + } + } + + // Numbering instance definition + $nodes = $xmlReader->getElements('w:num'); + if ($nodes->length > 0) { + foreach ($nodes as $node) { + $numId = $xmlReader->getAttribute('w:numId', $node); + $abstractId = $xmlReader->getAttribute('w:val', $node, 'w:abstractNumId'); + $numberings[$numId] = $abstracts[$abstractId]; + $numberings[$numId]['numId'] = $numId; + $subnodes = $xmlReader->getElements('w:lvlOverride/w:lvl', $node); + foreach ($subnodes as $subnode) { + $levelId = $xmlReader->getAttribute('w:ilvl', $subnode); + $overrides = $this->readNumberingLevel($xmlReader, $subnode, $levelId); + foreach ($overrides as $key => $value) { + $numberings[$numId]['levels'][$levelId][$key] = $value; + } + } + } + } + + // Push to Style collection + foreach ($numberings as $numId => $numbering) { + $this->phpWord->addNumberingStyle("PHPWordList{$numId}", $numbering); + } + } + + /** + * Read numbering level definition from w:abstractNum and w:num + * + * @param integer $levelId + * @return array + */ + private function readNumberingLevel(XMLReader $xmlReader, \DOMElement $subnode, $levelId) + { + $level = array(); + + $level['level'] = $levelId; + $level['start'] = $xmlReader->getAttribute('w:val', $subnode, 'w:start'); + $level['format'] = $xmlReader->getAttribute('w:val', $subnode, 'w:numFmt'); + $level['restart'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlRestart'); + $level['suffix'] = $xmlReader->getAttribute('w:val', $subnode, 'w:suff'); + $level['text'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlText'); + $level['align'] = $xmlReader->getAttribute('w:val', $subnode, 'w:lvlJc'); + $level['tab'] = $xmlReader->getAttribute('w:pos', $subnode, 'w:pPr/w:tabs/w:tab'); + $level['left'] = $xmlReader->getAttribute('w:left', $subnode, 'w:pPr/w:ind'); + $level['hanging'] = $xmlReader->getAttribute('w:hanging', $subnode, 'w:pPr/w:ind'); + $level['font'] = $xmlReader->getAttribute('w:ascii', $subnode, 'w:rPr/w:rFonts'); + $level['hint'] = $xmlReader->getAttribute('w:hint', $subnode, 'w:rPr/w:rFonts'); + + foreach ($level as $key => $value) { + if (is_null($value)) { + unset($level[$key]); + } + } + + return $level; + } + /** * Read header footer * @@ -325,6 +428,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @param string $filename * @param string $xmlFile + * @param string $notesType */ private function readNotes($filename, $xmlFile, $notesType = 'footnotes') { @@ -362,7 +466,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @todo Get font style for preserve text */ - private function readParagraph(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart) + private function readParagraph(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart) { // Paragraph style $pStyle = null; @@ -396,6 +500,17 @@ class Word2007 extends AbstractReader implements ReaderInterface } $parent->addPreserveText($textContent, $fStyle, $pStyle); + // List item + } elseif ($xmlReader->elementExists('w:pPr/w:numPr', $domNode)) { + $textContent = ''; + $numId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:numId'); + $levelId = $xmlReader->getAttribute('w:val', $domNode, 'w:pPr/w:numPr/w:ilvl'); + $nodes = $xmlReader->getElements('w:r', $domNode); + foreach ($nodes as $node) { + $textContent .= $xmlReader->getValue('w:t', $node); + } + $parent->addListItem($textContent, $levelId, null, "PHPWordList{$numId}", $pStyle); + // Text and TextRun } else { $runCount = $xmlReader->countElements('w:r', $domNode); @@ -421,13 +536,15 @@ class Word2007 extends AbstractReader implements ReaderInterface /** * Read w:r * + * @param \PhpOffice\PhpWord\Shared\XMLReader $xmlReader + * @param \DOMElement $domNode * @param mixed $parent * @param string $docPart * @param mixed $pStyle * * @todo Footnote paragraph style */ - private function readRun(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart, $pStyle = null) + private function readRun(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart, $pStyle = null) { if (!in_array($domNode->nodeName, array('w:r', 'w:hyperlink'))) { return; @@ -484,7 +601,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * @param mixed $parent * @param string $docPart */ - private function readTable(XMLReader $xmlReader, \DOMNode $domNode, &$parent, $docPart) + private function readTable(XMLReader $xmlReader, \DOMElement $domNode, &$parent, $docPart) { // Table style $tblStyle = null; @@ -539,7 +656,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @return array|null */ - private function readSectionStyle(XMLReader $xmlReader, \DOMNode $domNode) + private function readSectionStyle(XMLReader $xmlReader, \DOMElement $domNode) { $ret = null; $mapping = array( @@ -554,6 +671,7 @@ class Word2007 extends AbstractReader implements ReaderInterface } $property = $mapping[$node->nodeName]; switch ($node->nodeName) { + case 'w:type': $ret['breakType'] = $xmlReader->getAttribute('w:val', $node); break; @@ -598,7 +716,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @return string|array|null */ - private function readParagraphStyle(XMLReader $xmlReader, \DOMNode $domNode) + private function readParagraphStyle(XMLReader $xmlReader, \DOMElement $domNode) { $style = null; if ($xmlReader->elementExists('w:pPr', $domNode)) { @@ -620,6 +738,7 @@ class Word2007 extends AbstractReader implements ReaderInterface } $property = $mapping[$node->nodeName]; switch ($node->nodeName) { + case 'w:ind': $style['indent'] = $xmlReader->getAttribute('w:left', $node); $style['hanging'] = $xmlReader->getAttribute('w:hanging', $node); @@ -660,7 +779,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @return string|array|null */ - private function readFontStyle(XMLReader $xmlReader, \DOMNode $domNode) + private function readFontStyle(XMLReader $xmlReader, \DOMElement $domNode) { $style = null; // Hyperlink has an extra w:r child @@ -686,6 +805,7 @@ class Word2007 extends AbstractReader implements ReaderInterface } $property = $mapping[$node->nodeName]; switch ($node->nodeName) { + case 'w:rFonts': $style['name'] = $xmlReader->getAttribute('w:ascii', $node); $style['hint'] = $xmlReader->getAttribute('w:hint', $node); @@ -729,7 +849,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * @return string|array|null * @todo Capture w:tblStylePr w:type="firstRow" */ - private function readTableStyle(XMLReader $xmlReader, \DOMNode $domNode) + private function readTableStyle(XMLReader $xmlReader, \DOMElement $domNode) { $style = null; $margins = array('top', 'left', 'bottom', 'right'); @@ -752,6 +872,7 @@ class Word2007 extends AbstractReader implements ReaderInterface } // $property = $mapping[$node->nodeName]; switch ($node->nodeName) { + case 'w:tblCellMar': foreach ($margins as $side) { $ucfSide = ucfirst($side); @@ -779,7 +900,7 @@ class Word2007 extends AbstractReader implements ReaderInterface * * @return array|null */ - private function readCellStyle(XMLReader $xmlReader, \DOMNode $domNode) + private function readCellStyle(XMLReader $xmlReader, \DOMElement $domNode) { $style = null; $mapping = array( diff --git a/src/PhpWord/Shared/XMLReader.php b/src/PhpWord/Shared/XMLReader.php index e5b5facc..17e8454d 100644 --- a/src/PhpWord/Shared/XMLReader.php +++ b/src/PhpWord/Shared/XMLReader.php @@ -70,7 +70,7 @@ class XMLReader * @param string $path * @return \DOMNodeList */ - public function getElements($path, \DOMNode $contextNode = null) + public function getElements($path, \DOMElement $contextNode = null) { if ($this->dom === null) { return array(); @@ -86,9 +86,9 @@ class XMLReader * Get element * * @param string $path - * @return \DOMNode|null + * @return \DOMElement|null */ - public function getElement($path, \DOMNode $contextNode) + public function getElement($path, \DOMElement $contextNode) { $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { @@ -105,7 +105,7 @@ class XMLReader * @param string $path * @return string|null */ - public function getAttribute($attribute, \DOMNode $contextNode, $path = null) + public function getAttribute($attribute, \DOMElement $contextNode, $path = null) { if (is_null($path)) { $return = $contextNode->getAttribute($attribute); @@ -127,7 +127,7 @@ class XMLReader * @param string $path * @return string|null */ - public function getValue($path, \DOMNode $contextNode) + public function getValue($path, \DOMElement $contextNode) { $elements = $this->getElements($path, $contextNode); if ($elements->length > 0) { @@ -143,7 +143,7 @@ class XMLReader * @param string $path * @return integer */ - public function countElements($path, \DOMNode $contextNode) + public function countElements($path, \DOMElement $contextNode) { $elements = $this->getElements($path, $contextNode); @@ -156,7 +156,7 @@ class XMLReader * @param string $path * @return boolean */ - public function elementExists($path, \DOMNode $contextNode) + public function elementExists($path, \DOMElement $contextNode) { return $this->getElements($path, $contextNode)->length > 0; } diff --git a/src/PhpWord/Style.php b/src/PhpWord/Style.php index 5afbb91b..eb01786c 100755 --- a/src/PhpWord/Style.php +++ b/src/PhpWord/Style.php @@ -12,6 +12,7 @@ namespace PhpOffice\PhpWord; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Paragraph; use PhpOffice\PhpWord\Style\Table; +use PhpOffice\PhpWord\Style\Numbering; /** * Style collection @@ -68,11 +69,7 @@ class Style */ public static function addTableStyle($styleName, $styleTable, $styleFirstRow = null) { - if (!array_key_exists($styleName, self::$styles)) { - $style = new Table($styleTable, $styleFirstRow); - - self::$styles[$styleName] = $style; - } + self::setStyleValues($styleName, null, new Table($styleTable, $styleFirstRow)); } /** @@ -84,12 +81,36 @@ class Style */ public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = null) { - $styleName = 'Heading_' . $titleCount; self::setStyleValues("Heading_{$titleCount}", $styleFont, new Font('title', $styleParagraph)); } + /** + * Add numbering style + * + * @param string $styleName + * @param array $styleValues + * @return Numbering + * @since 0.9.2 + */ + public static function addNumberingStyle($styleName, $styleValues) + { + self::setStyleValues($styleName, $styleValues, new Numbering()); + } + + /** + * Count styles + * + * @return integer + * @since 0.9.2 + */ + public static function countStyles() + { + return count(self::$styles); + } + /** * Reset styles + * @since 0.9.2 */ public static function resetStyles() { @@ -120,6 +141,7 @@ class Style * Get style by name * * @param string $styleName + * @return Paragraph|Font|Table|Numbering|null */ public static function getStyle($styleName) { @@ -131,24 +153,21 @@ class Style } /** - * Set style values + * Set style values and put it to static style collection * * @param string $styleName * @param array $styleValues - * @param mixed $styleObject + * @param Paragraph|Font|Table|Numbering $styleObject */ private static function setStyleValues($styleName, $styleValues, $styleObject) { if (!array_key_exists($styleName, self::$styles)) { if (is_array($styleValues)) { foreach ($styleValues as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } $styleObject->setStyleValue($key, $value); } } - + $styleObject->setIndex(self::countStyles() + 1); // One based index self::$styles[$styleName] = $styleObject; } } diff --git a/src/PhpWord/Style/AbstractStyle.php b/src/PhpWord/Style/AbstractStyle.php index c17ea6e2..e77c26a6 100644 --- a/src/PhpWord/Style/AbstractStyle.php +++ b/src/PhpWord/Style/AbstractStyle.php @@ -16,6 +16,37 @@ namespace PhpOffice\PhpWord\Style; */ abstract class AbstractStyle { + /** + * Index number in Style collection for named style + * + * This number starts from one and defined in Style::setStyleValues() + * + * @var integer|null + */ + protected $index; + + /** + * Get index number + * + * @return integer|null + */ + public function getIndex() + { + return $this->index; + } + + /** + * Set index number + * + * @param integer|null $value + */ + public function setIndex($value = null) + { + $this->index = $this->setIntVal($value, $this->index); + + return $this; + } + /** * Set style value template method * @@ -23,8 +54,7 @@ abstract class AbstractStyle * * @param string $key * @param string $value - * - * @todo Implement type check mechanism, e.g. boolean, integer, enum, defaults + * @return self */ public function setStyleValue($key, $value) { @@ -39,5 +69,88 @@ abstract class AbstractStyle if (method_exists($this, $method)) { $this->$method($value); } + + return $this; + } + + /** + * Set style by using associative array + * + * @param array $styles + * @return self + */ + public function setStyleByArray($styles = array()) + { + foreach ($styles as $key => $value) { + $this->setStyleValue($key, $value); + } + + return $this; + } + + /** + * Set boolean value + * + * @param mixed $value + * @param boolean|null $default + * @return boolean|null + */ + protected function setBoolVal($value, $default = null) + { + if (!is_bool($value)) { + $value = $default; + } + + return $value; + } + + /** + * Set integer value + * + * @param mixed $value + * @param integer|null $default + * @return integer|null + */ + protected function setIntVal($value, $default = null) + { + $value = intval($value); + if (!is_int($value)) { + $value = $default; + } + + return $value; + } + + /** + * Set float value + * + * @param mixed $value + * @param float|null $default + * @return float|null + */ + protected function setFloatVal($value, $default = null) + { + $value = floatval($value); + if (!is_float($value)) { + $value = $default; + } + + return $value; + } + + /** + * Set enum value + * + * @param mixed $value + * @param array $enum + * @param mixed $default + */ + protected function setEnumVal($value, $enum, $default = null) + { + if (!in_array($value, $enum)) { + $value = $default; + } + + return $value; } } diff --git a/src/PhpWord/Style/ListItem.php b/src/PhpWord/Style/ListItem.php index ecc4274c..93a3bb07 100644 --- a/src/PhpWord/Style/ListItem.php +++ b/src/PhpWord/Style/ListItem.php @@ -9,46 +9,240 @@ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Style\Numbering; + /** * List item style + * + * Before version 0.9.2, numbering style is defined statically with $listType. + * After version 0.9.2, numbering style is defined by using Numbering and + * recorded by $numStyle. $listStyle is maintained for backward compatility */ class ListItem extends AbstractStyle { + const TYPE_SQUARE_FILLED = 1; + const TYPE_BULLET_FILLED = 3; // default + const TYPE_BULLET_EMPTY = 5; const TYPE_NUMBER = 7; const TYPE_NUMBER_NESTED = 8; const TYPE_ALPHANUM = 9; - const TYPE_BULLET_FILLED = 3; - const TYPE_BULLET_EMPTY = 5; - const TYPE_SQUARE_FILLED = 1; /** - * List Type + * Legacy list type + * + * @var integer */ private $listType; /** - * Create a new ListItem Style + * Numbering style name + * + * @var string + * @since 0.9.2 */ - public function __construct() - { - $this->listType = self::TYPE_BULLET_FILLED; - } + private $numStyle; /** - * Set List Type + * Numbering definition instance ID * - * @param int $pValue + * @var integer + * @since 0.9.2 */ - public function setListType($pValue = self::TYPE_BULLET_FILLED) + private $numId; + + /** + * Create new instance + * + * @param string $numStyle + */ + public function __construct($numStyle = null) { - $this->listType = $pValue; + if (!is_null($numStyle)) { + $this->setNumStyle($numStyle); + } else { + $this->setListType(); + } } /** * Get List Type + * + * @return integer */ public function getListType() { return $this->listType; } + + /** + * Set legacy list type for version < 0.9.2 + * + * @param integer $value + */ + public function setListType($value = self::TYPE_BULLET_FILLED) + { + $enum = array(self::TYPE_SQUARE_FILLED, self::TYPE_BULLET_FILLED, + self::TYPE_BULLET_EMPTY, self::TYPE_NUMBER, + self::TYPE_NUMBER_NESTED, self::TYPE_ALPHANUM); + $this->listType = $this->setEnumVal($value, $enum, $this->listType); + $this->getListTypeStyle(); + } + + /** + * Get numbering style name + * + * @return integer + */ + public function getNumStyle() + { + return $this->numStyle; + } + + /** + * Set numbering style name + * + * @param string $value + */ + public function setNumStyle($value) + { + $this->numStyle = $value; + $numStyleObject = Style::getStyle($this->numStyle); + if (!is_null($numStyleObject)) { + $this->numId = $numStyleObject->getIndex(); + $numStyleObject->setNumId($this->numId); + } + } + + /** + * Get numbering Id + * + * @return integer + */ + public function getNumId() + { + return $this->numId; + } + + /** + * Get legacy numbering definition + * + * @param integer $listType + * @return array + * @since 0.9.2 + */ + private function getListTypeStyle() + { + // Check if legacy style already registered in global Style collection + $numStyle = "PHPWordList{$this->listType}"; + if (!is_null(Style::getStyle($numStyle))) { + $this->setNumStyle($numStyle); + return; + } + + // Property mapping for numbering level information + $properties = array('start', 'format', 'text', 'align', 'tabPos', 'left', 'hanging', 'font', 'hint'); + + // Legacy level information + $listTypeStyles = array( + self::TYPE_SQUARE_FILLED => array( + 'type' => 'hybridMultilevel', + 'levels' => array( + 0 => '1, bullet, , left, 720, 720, 360, Wingdings, default', + 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', + 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', + 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', + 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', + 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', + 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', + 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', + 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default', + ), + ), + self::TYPE_BULLET_FILLED => array( + 'type' => 'hybridMultilevel', + 'levels' => array( + 0 => '1, bullet, , left, 720, 720, 360, Symbol, default', + 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', + 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', + 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', + 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', + 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', + 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', + 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', + 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default', + ), + ), + self::TYPE_BULLET_EMPTY => array( + 'type' => 'hybridMultilevel', + 'levels' => array( + 0 => '1, bullet, o, left, 720, 720, 360, Courier New, default', + 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', + 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', + 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', + 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', + 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', + 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', + 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', + 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default', + ), + ), + self::TYPE_NUMBER => array( + 'type' => 'hybridMultilevel', + 'levels' => array( + 0 => '1, decimal, %1., left, 720, 720, 360, , default', + 1 => '1, bullet, o, left, 1440, 1440, 360, Courier New, default', + 2 => '1, bullet, , left, 2160, 2160, 360, Wingdings, default', + 3 => '1, bullet, , left, 2880, 2880, 360, Symbol, default', + 4 => '1, bullet, o, left, 3600, 3600, 360, Courier New, default', + 5 => '1, bullet, , left, 4320, 4320, 360, Wingdings, default', + 6 => '1, bullet, , left, 5040, 5040, 360, Symbol, default', + 7 => '1, bullet, o, left, 5760, 5760, 360, Courier New, default', + 8 => '1, bullet, , left, 6480, 6480, 360, Wingdings, default', + ), + ), + self::TYPE_NUMBER_NESTED => array( + 'type' => 'multilevel', + 'levels' => array( + 0 => '1, decimal, %1., left, 360, 360, 360, , ', + 1 => '1, decimal, %1.%2., left, 792, 792, 432, , ', + 2 => '1, decimal, %1.%2.%3., left, 1224, 1224, 504, , ', + 3 => '1, decimal, %1.%2.%3.%4., left, 1800, 1728, 648, , ', + 4 => '1, decimal, %1.%2.%3.%4.%5., left, 2520, 2232, 792, , ', + 5 => '1, decimal, %1.%2.%3.%4.%5.%6., left, 2880, 2736, 936, , ', + 6 => '1, decimal, %1.%2.%3.%4.%5.%6.%7., left, 3600, 3240, 1080, , ', + 7 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8., left, 3960, 3744, 1224, , ', + 8 => '1, decimal, %1.%2.%3.%4.%5.%6.%7.%8.%9., left, 4680, 4320, 1440, , ', + ), + ), + self::TYPE_ALPHANUM => array( + 'type' => 'multilevel', + 'levels' => array( + 0 => '1, decimal, %1., left, 720, 720, 360, , ', + 1 => '1, lowerLetter, %2., left, 1440, 1440, 360, , ', + 2 => '1, lowerRoman, %3., right, 2160, 2160, 180, , ', + 3 => '1, decimal, %4., left, 2880, 2880, 360, , ', + 4 => '1, lowerLetter, %5., left, 3600, 3600, 360, , ', + 5 => '1, lowerRoman, %6., right, 4320, 4320, 180, , ', + 6 => '1, decimal, %7., left, 5040, 5040, 360, , ', + 7 => '1, lowerLetter, %8., left, 5760, 5760, 360, , ', + 8 => '1, lowerRoman, %9., right, 6480, 6480, 180, , ', + ), + ), + ); + + // Populate style and register to global Style register + $style = $listTypeStyles[$this->listType]; + foreach ($style['levels'] as $key => $value) { + $levelProperties = explode(', ', $value); + $level['level'] = $key; + for ($i = 0; $i < count($properties); $i++) { + $property = $properties[$i]; + $level[$property] = $levelProperties[$i]; + } + $style['levels'][$key] = $level; + } + Style::addNumberingStyle($numStyle, $style); + $this->setNumStyle($numStyle); + } } diff --git a/src/PhpWord/Style/Numbering.php b/src/PhpWord/Style/Numbering.php new file mode 100644 index 00000000..ce935b98 --- /dev/null +++ b/src/PhpWord/Style/Numbering.php @@ -0,0 +1,123 @@ +numId; + } + + /** + * Set Id + * + * @param integer $value + * @return self + */ + public function setNumId($value) + { + $this->numId = $this->setIntVal($value, $this->numId); + return $this; + } + + /** + * Get multilevel type + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Set multilevel type + * + * @param string $value + * @return self + */ + public function setType($value) + { + $enum = array('singleLevel', 'multilevel', 'hybridMultilevel'); + $this->type = $this->setEnumVal($value, $enum, $this->type); + return $this; + } + + /** + * Get levels + * + * @return NumberingLevel[] + */ + public function getLevels() + { + return $this->levels; + } + + /** + * Set multilevel type + * + * @param array $values + * @return self + */ + public function setLevels($values) + { + if (is_array($values)) { + foreach ($values as $key => $value) { + $numberingLevel = new NumberingLevel(); + if (is_array($value)) { + $numberingLevel->setStyleByArray($value); + $numberingLevel->setLevel($key); + } + $this->levels[$key] = $numberingLevel; + } + } + + return $this; + } +} diff --git a/src/PhpWord/Style/NumberingLevel.php b/src/PhpWord/Style/NumberingLevel.php new file mode 100644 index 00000000..77b63b40 --- /dev/null +++ b/src/PhpWord/Style/NumberingLevel.php @@ -0,0 +1,378 @@ +level; + } + + /** + * Set level + * + * @param integer $value + * @return self + */ + public function setLevel($value) + { + $this->level = $this->setIntVal($value, $this->level); + return $this; + } + + /** + * Get start + * + * @return integer + */ + public function getStart() + { + return $this->start; + } + + /** + * Set start + * + * @param integer $value + * @return self + */ + public function setStart($value) + { + $this->start = $this->setIntVal($value, $this->start); + return $this; + } + + /** + * Get format + * + * @return string + */ + public function getFormat() + { + return $this->format; + } + + /** + * Set format + * + * @param string $value + * @return self + */ + public function setFormat($value) + { + $enum = array('bullet', 'decimal', 'upperRoman', 'lowerRoman', 'upperLetter', 'lowerLetter'); + $this->format = $this->setEnumVal($value, $enum, $this->format); + return $this; + } + + /** + * Get start + * + * @return integer + */ + public function getRestart() + { + return $this->restart; + } + + /** + * Set start + * + * @param integer $value + * @return self + */ + public function setRestart($value) + { + $this->restart = $this->setIntVal($value, $this->restart); + return $this; + } + + /** + * Get suffix + * + * @return string + */ + public function getSuffix() + { + return $this->suffix; + } + + /** + * Set suffix + * + * @param string $value + * @return self + */ + public function setSuffix($value) + { + $enum = array('tab', 'space', 'nothing'); + $this->suffix = $this->setEnumVal($value, $enum, $this->suffix); + return $this; + } + + /** + * Get text + * + * @return string + */ + public function getText() + { + return $this->text; + } + + /** + * Set text + * + * @param string $value + * @return self + */ + public function setText($value) + { + $this->text = $value; + return $this; + } + + /** + * Get align + * + * @return string + */ + public function getAlign() + { + return $this->align; + } + + /** + * Set align + * + * @param string $value + * @return self + */ + public function setAlign($value) + { + $enum = array('left', 'center', 'right', 'both'); + $this->align = $this->setEnumVal($value, $enum, $this->align); + return $this; + } + + /** + * Get left + * + * @return integer + */ + public function getLeft() + { + return $this->left; + } + + /** + * Set left + * + * @param integer $value + * @return self + */ + public function setLeft($value) + { + $this->left = $this->setIntVal($value, $this->left); + return $this; + } + + /** + * Get hanging + * + * @return integer + */ + public function getHanging() + { + return $this->hanging; + } + + /** + * Set hanging + * + * @param integer $value + * @return self + */ + public function setHanging($value) + { + $this->hanging = $this->setIntVal($value, $this->hanging); + return $this; + } + + /** + * Get tab + * + * @return integer + */ + public function getTabPos() + { + return $this->tabPos; + } + + /** + * Set tab + * + * @param integer $value + * @return self + */ + public function setTabPos($value) + { + $this->tabPos = $this->setIntVal($value, $this->tabPos); + return $this; + } + + /** + * Get font + * + * @return string + */ + public function getFont() + { + return $this->font; + } + + /** + * Set font + * + * @param string $value + * @return self + */ + public function setFont($value) + { + $this->font = $value; + return $this; + } + + /** + * Get hint + * + * @return string + */ + public function getHint() + { + return $this->hint; + } + + /** + * Set hint + * + * @param string $value + * @return self + */ + public function setHint($value) + { + $enum = array('default', 'eastAsia', 'cs'); + $this->hint = $this->setEnumVal($value, $enum, $this->hint); + return $this; + } +} diff --git a/src/PhpWord/Template.php b/src/PhpWord/Template.php index b0be592d..9f71d306 100644 --- a/src/PhpWord/Template.php +++ b/src/PhpWord/Template.php @@ -432,6 +432,6 @@ class Template */ public function deleteTemplateBlock($blockname, $replacement = '') { - $this->deleteBlock($blockname, $replacement); + $this->deleteBlock($blockname); } } diff --git a/src/PhpWord/Writer/Word2007.php b/src/PhpWord/Writer/Word2007.php index b44708a3..7b552905 100755 --- a/src/PhpWord/Writer/Word2007.php +++ b/src/PhpWord/Writer/Word2007.php @@ -9,17 +9,18 @@ namespace PhpOffice\PhpWord\Writer; -use PhpOffice\PhpWord\Exception\Exception; -use PhpOffice\PhpWord\PhpWord; -use PhpOffice\PhpWord\Media; use PhpOffice\PhpWord\Element\Section; +use PhpOffice\PhpWord\Exception\Exception; +use PhpOffice\PhpWord\Media; +use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\Writer\Word2007\ContentTypes; -use PhpOffice\PhpWord\Writer\Word2007\Rels; use PhpOffice\PhpWord\Writer\Word2007\DocProps; use PhpOffice\PhpWord\Writer\Word2007\Document; use PhpOffice\PhpWord\Writer\Word2007\Footer; -use PhpOffice\PhpWord\Writer\Word2007\Notes; use PhpOffice\PhpWord\Writer\Word2007\Header; +use PhpOffice\PhpWord\Writer\Word2007\Notes; +use PhpOffice\PhpWord\Writer\Word2007\Numbering; +use PhpOffice\PhpWord\Writer\Word2007\Rels; use PhpOffice\PhpWord\Writer\Word2007\Styles; /** @@ -57,6 +58,7 @@ class Word2007 extends AbstractWriter implements WriterInterface $this->writerParts['docprops'] = new DocProps(); $this->writerParts['document'] = new Document(); $this->writerParts['styles'] = new Styles(); + $this->writerParts['numbering'] = new Numbering(); $this->writerParts['header'] = new Header(); $this->writerParts['footer'] = new Footer(); $this->writerParts['footnotes'] = new Notes(); @@ -97,7 +99,6 @@ class Word2007 extends AbstractWriter implements WriterInterface $this->addHeaderFooterMedia($objZip, 'footer'); // Add header/footer contents - $overrides = array(); $rId = Media::countElements('section') + 6; // @see Rels::writeDocRels for 6 first elements $sections = $this->phpWord->getSections(); foreach ($sections as $section) { @@ -116,9 +117,9 @@ class Word2007 extends AbstractWriter implements WriterInterface $objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('rels')->writeDocRels($this->docRels)); $objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->phpWord)); $objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->phpWord)); + $objZip->addFromString('word/numbering.xml', $this->getWriterPart('numbering')->writeNumbering()); // Write static files - $objZip->addFile(__DIR__ . '/../_staticDocParts/numbering.xml', 'word/numbering.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/settings.xml', 'word/settings.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/theme1.xml', 'word/theme/theme1.xml'); $objZip->addFile(__DIR__ . '/../_staticDocParts/webSettings.xml', 'word/webSettings.xml'); @@ -224,8 +225,8 @@ class Word2007 extends AbstractWriter implements WriterInterface * Add footnotes/endnotes * * @param mixed $objZip - * @param string $elmType * @param integer $rId + * @param string $notesType */ private function addNotes($objZip, &$rId, $notesType = 'footnote') { diff --git a/src/PhpWord/Writer/Word2007/Base.php b/src/PhpWord/Writer/Word2007/Base.php index 4fd38b57..b74211a5 100644 --- a/src/PhpWord/Writer/Word2007/Base.php +++ b/src/PhpWord/Writer/Word2007/Base.php @@ -279,7 +279,7 @@ class Base extends AbstractWriterPart { $textObject = $listItem->getTextObject(); $depth = $listItem->getDepth(); - $listType = $listItem->getStyle()->getListType(); + $numId = $listItem->getStyle()->getNumId(); $styleParagraph = $textObject->getParagraphStyle(); $xmlWriter->startElement('w:p'); @@ -290,7 +290,7 @@ class Base extends AbstractWriterPart $xmlWriter->writeAttribute('w:val', $depth); $xmlWriter->endElement(); // w:ilvl $xmlWriter->startElement('w:numId'); - $xmlWriter->writeAttribute('w:val', $listType); + $xmlWriter->writeAttribute('w:val', $numId); $xmlWriter->endElement(); // w:numId $xmlWriter->endElement(); // w:numPr $xmlWriter->endElement(); // w:pPr diff --git a/src/PhpWord/Writer/Word2007/Notes.php b/src/PhpWord/Writer/Word2007/Notes.php index 96393b4c..3b70ee74 100644 --- a/src/PhpWord/Writer/Word2007/Notes.php +++ b/src/PhpWord/Writer/Word2007/Notes.php @@ -69,7 +69,7 @@ class Notes extends Base // Content foreach ($elements as $element) { if ($element instanceof Footnote || $element instanceof Endnote) { - $this->writeNote($xmlWriter, $element, null, $notesTypes); + $this->writeNote($xmlWriter, $element, $notesTypes); } } @@ -83,10 +83,9 @@ class Notes extends Base * * @param XMLWriter $xmlWriter * @param Footnote|Endnote $element - * @param boolean $withoutP * @param string $notesTypes */ - protected function writeNote(XMLWriter $xmlWriter, $element, $withoutP = false, $notesTypes = 'footnotes') + protected function writeNote(XMLWriter $xmlWriter, $element, $notesTypes = 'footnotes') { $isFootnote = ($notesTypes == 'footnotes'); $elementNode = $isFootnote ? 'w:footnote' : 'w:endnote'; diff --git a/src/PhpWord/Writer/Word2007/Numbering.php b/src/PhpWord/Writer/Word2007/Numbering.php new file mode 100644 index 00000000..da127891 --- /dev/null +++ b/src/PhpWord/Writer/Word2007/Numbering.php @@ -0,0 +1,177 @@ +getXmlWriter(); + + $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); + $xmlWriter->startElement('w:numbering'); + $xmlWriter->writeAttribute('xmlns:ve', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + $xmlWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $xmlWriter->writeAttribute('xmlns:m', 'http://schemas.openxmlformats.org/officeDocument/2006/math'); + $xmlWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $xmlWriter->writeAttribute('xmlns:wp', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing'); + $xmlWriter->writeAttribute('xmlns:w10', 'urn:schemas-microsoft-com:office:word'); + $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); + $xmlWriter->writeAttribute('xmlns:wne', 'http://schemas.microsoft.com/office/word/2006/wordml'); + + // Abstract numbering definitions + foreach ($styles as $style) { + if ($style instanceof NumberingStyle) { + $levels = $style->getLevels(); + + $xmlWriter->startElement('w:abstractNum'); + $xmlWriter->writeAttribute('w:abstractNumId', $style->getNumId()); + + $xmlWriter->startElement('w:nsid'); + $xmlWriter->writeAttribute('w:val', $this->getRandomHexNumber()); + $xmlWriter->endElement(); // w:nsid + + $xmlWriter->startElement('w:multiLevelType'); + $xmlWriter->writeAttribute('w:val', $style->getType()); + $xmlWriter->endElement(); // w:multiLevelType + + if (is_array($levels)) { + foreach ($levels as $levelNum => $levelObject) { + if ($levelObject instanceof NumberingLevel) { + $start = $levelObject->getStart(); + $format = $levelObject->getFormat(); + $restart = $levelObject->getRestart(); + $suffix = $levelObject->getSuffix(); + $text = $levelObject->getText(); + $align = $levelObject->getAlign(); + $tabPos = $levelObject->getTabPos(); + $left = $levelObject->getLeft(); + $hanging = $levelObject->getHanging(); + $font = $levelObject->getFont(); + $hint = $levelObject->getHint(); + + $xmlWriter->startElement('w:lvl'); + $xmlWriter->writeAttribute('w:ilvl', $levelNum); + + if (!is_null($start)) { + $xmlWriter->startElement('w:start'); + $xmlWriter->writeAttribute('w:val', $start); + $xmlWriter->endElement(); // w:start + } + if (!is_null($format)) { + $xmlWriter->startElement('w:numFmt'); + $xmlWriter->writeAttribute('w:val', $format); + $xmlWriter->endElement(); // w:numFmt + } + if (!is_null($restart)) { + $xmlWriter->startElement('w:lvlRestart'); + $xmlWriter->writeAttribute('w:val', $restart); + $xmlWriter->endElement(); // w:lvlRestart + } + if (!is_null($suffix)) { + $xmlWriter->startElement('w:suff'); + $xmlWriter->writeAttribute('w:val', $suffix); + $xmlWriter->endElement(); // w:suff + } + if (!is_null($text)) { + $xmlWriter->startElement('w:lvlText'); + $xmlWriter->writeAttribute('w:val', $text); + $xmlWriter->endElement(); // w:start + } + if (!is_null($align)) { + $xmlWriter->startElement('w:lvlJc'); + $xmlWriter->writeAttribute('w:val', $align); + $xmlWriter->endElement(); // w:lvlJc + } + if (!is_null($tabPos) || !is_null($left) || !is_null($hanging)) { + $xmlWriter->startElement('w:pPr'); + if (!is_null($tabPos)) { + $xmlWriter->startElement('w:tabs'); + $xmlWriter->startElement('w:tab'); + $xmlWriter->writeAttribute('w:val', 'num'); + $xmlWriter->writeAttribute('w:pos', $tabPos); + $xmlWriter->endElement(); // w:tab + $xmlWriter->endElement(); // w:tabs + } + if (!is_null($left) || !is_null($hanging)) { + $xmlWriter->startElement('w:ind'); + if (!is_null($left)) { + $xmlWriter->writeAttribute('w:left', $left); + } + if (!is_null($hanging)) { + $xmlWriter->writeAttribute('w:hanging', $hanging); + } + $xmlWriter->endElement(); // w:ind + } + $xmlWriter->endElement(); // w:pPr + } + if (!is_null($font) || !is_null($hint)) { + $xmlWriter->startElement('w:rPr'); + $xmlWriter->startElement('w:rFonts'); + if (!is_null($font)) { + $xmlWriter->writeAttribute('w:ascii', $font); + $xmlWriter->writeAttribute('w:hAnsi', $font); + $xmlWriter->writeAttribute('w:cs', $font); + } + if (!is_null($hint)) { + $xmlWriter->writeAttribute('w:hint', $hint); + } + $xmlWriter->endElement(); // w:rFonts + $xmlWriter->endElement(); // w:rPr + } + $xmlWriter->endElement(); // w:lvl + } + } + } + $xmlWriter->endElement(); // w:abstractNum + } + } + + // Numbering definition instances + foreach ($styles as $style) { + if ($style instanceof NumberingStyle) { + $xmlWriter->startElement('w:num'); + $xmlWriter->writeAttribute('w:numId', $style->getNumId()); + $xmlWriter->startElement('w:abstractNumId'); + $xmlWriter->writeAttribute('w:val', $style->getNumId()); + $xmlWriter->endElement(); // w:abstractNumId + $xmlWriter->endElement(); // w:num + } + } + + $xmlWriter->endElement(); + + return $xmlWriter->getData(); + } + + /** + * Get random hexadecimal number value + * + * @param int $length + * @return string + */ + private function getRandomHexNumber($length = 8) + { + return strtoupper(substr(md5(rand()), 0, $length)); + } +} diff --git a/src/PhpWord/Writer/Word2007/Styles.php b/src/PhpWord/Writer/Word2007/Styles.php index f0305f7f..14a54b2d 100644 --- a/src/PhpWord/Writer/Word2007/Styles.php +++ b/src/PhpWord/Writer/Word2007/Styles.php @@ -15,9 +15,12 @@ use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Paragraph; use PhpOffice\PhpWord\Style\Table; +use PhpOffice\PhpWord\Style\Numbering; /** * Word2007 styles part writer + * + * @todo Do something with the numbering style introduced in 0.9.2 */ class Styles extends Base { @@ -38,37 +41,32 @@ class Styles extends Base // XML header $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); $xmlWriter->startElement('w:styles'); - $xmlWriter->writeAttribute( - 'xmlns:r', - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - ); - $xmlWriter->writeAttribute( - 'xmlns:w', - 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' - ); + $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); + // Write default styles $styles = Style::getStyles(); $this->writeDefaultStyles($xmlWriter, $phpWord, $styles); - // Write other styles + + // Write styles if (count($styles) > 0) { foreach ($styles as $styleName => $style) { if ($styleName == 'Normal') { continue; } - if ($style instanceof Font) { + $styleClass = str_replace('PhpOffice\\PhpWord\\Style\\', '', get_class($style)); + // Font style + if ($style instanceof Font) { $paragraphStyle = $style->getParagraphStyle(); $styleType = $style->getStyleType(); - $type = ($styleType == 'title') ? 'paragraph' : 'character'; - if (!is_null($paragraphStyle)) { $type = 'paragraph'; } $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', $type); - if ($styleType == 'title') { $arrStyle = explode('_', $styleName); $styleId = 'Heading' . $arrStyle[1]; @@ -80,11 +78,9 @@ class Styles extends Base $xmlWriter->writeAttribute('w:val', $styleLink); $xmlWriter->endElement(); } - $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); - if (!is_null($paragraphStyle)) { // Point parent style to Normal $xmlWriter->startElement('w:basedOn'); @@ -94,19 +90,17 @@ class Styles extends Base } $this->writeFontStyle($xmlWriter, $style); - $xmlWriter->endElement(); + // Paragraph style } elseif ($style instanceof Paragraph) { $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', 'paragraph'); $xmlWriter->writeAttribute('w:customStyle', '1'); $xmlWriter->writeAttribute('w:styleId', $styleName); - $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); - // Parent style $basedOn = $style->getBasedOn(); if (!is_null($basedOn)) { @@ -114,7 +108,6 @@ class Styles extends Base $xmlWriter->writeAttribute('w:val', $basedOn); $xmlWriter->endElement(); } - // Next paragraph style $next = $style->getNext(); if (!is_null($next)) { @@ -126,22 +119,20 @@ class Styles extends Base $this->writeParagraphStyle($xmlWriter, $style); $xmlWriter->endElement(); + // Table style } elseif ($style instanceof Table) { $xmlWriter->startElement('w:style'); $xmlWriter->writeAttribute('w:type', 'table'); $xmlWriter->writeAttribute('w:customStyle', '1'); $xmlWriter->writeAttribute('w:styleId', $styleName); - $xmlWriter->startElement('w:name'); $xmlWriter->writeAttribute('w:val', $styleName); $xmlWriter->endElement(); - $xmlWriter->startElement('w:uiPriority'); $xmlWriter->writeAttribute('w:val', '99'); $xmlWriter->endElement(); $this->writeTableStyle($xmlWriter, $style); - $xmlWriter->endElement(); // w:style } } @@ -149,7 +140,6 @@ class Styles extends Base $xmlWriter->endElement(); // w:styles - // Return return $xmlWriter->getData(); } diff --git a/src/PhpWord/_staticDocParts/numbering.xml b/src/PhpWord/_staticDocParts/numbering.xml deleted file mode 100644 index ac229f40..00000000 --- a/src/PhpWord/_staticDocParts/numbering.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/tests/PhpWord/Tests/Writer/Word2007/DocumentTest.php b/tests/PhpWord/Tests/Writer/Word2007/DocumentTest.php index 8cceecb3..fa11638e 100644 --- a/tests/PhpWord/Tests/Writer/Word2007/DocumentTest.php +++ b/tests/PhpWord/Tests/Writer/Word2007/DocumentTest.php @@ -99,12 +99,12 @@ class DocumentTest extends \PHPUnit_Framework_TestCase $objectSrc = __DIR__ . "/../../_files/documents/sheet.xls"; $phpWord = new PhpWord(); - $phpWord->addParagraphStyle('pStyle', array('align' => 'center')); - $phpWord->addFontStyle('fStyle', array('size' => '20')); - $phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true)); + $phpWord->addParagraphStyle('pStyle', array('align' => 'center')); // Style #1 + $phpWord->addFontStyle('fStyle', array('size' => '20')); // Style #2 + $phpWord->addTitleStyle(1, array('color' => '333333', 'bold' => true)); // Style #3 $fontStyle = new Font('text', array('align' => 'center')); $section = $phpWord->addSection(); - $section->addListItem('List Item', 0, null, null, 'pStyle'); + $section->addListItem('List Item', 0, null, null, 'pStyle'); // Style #4 $section->addObject($objectSrc, array('align' => 'center')); $section->addTOC($fontStyle); $section->addTitle('Title 1', 1); @@ -113,7 +113,7 @@ class DocumentTest extends \PHPUnit_Framework_TestCase // List item $element = $doc->getElement('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId'); - $this->assertEquals(3, $element->getAttribute('w:val')); + $this->assertEquals(4, $element->getAttribute('w:val')); // Object $element = $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:object/o:OLEObject'); From 297eeaadf0f7fd6f36db34c81cfc1b4e23fec5b1 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 17:59:48 +0700 Subject: [PATCH 04/29] Documentation for new ListItem feature --- docs/elements.rst | 38 ++++++++++++++++++++++++++ src/PhpWord/Reader/Word2007.php | 20 ++++++++++---- src/PhpWord/Style.php | 20 +++++++------- src/PhpWord/Style/ListItem.php | 6 ++-- src/PhpWord/Style/NumberingLevel.php | 2 +- src/PhpWord/Template.php | 13 --------- src/PhpWord/Writer/Word2007/Styles.php | 2 -- 7 files changed, 66 insertions(+), 35 deletions(-) diff --git a/docs/elements.rst b/docs/elements.rst index 62ee007f..b6842b65 100644 --- a/docs/elements.rst +++ b/docs/elements.rst @@ -207,10 +207,14 @@ Lists To add a list item use the function ``addListItem``. +Basic usage: + .. code-block:: php $section->addListItem($text, [$depth], [$fontStyle], [$listStyle], [$paragraphStyle]); +Parameters: + - ``$text`` Text that appears in the document. - ``$depth`` Depth of list item. - ``$fontStyle`` See "Font style" section. @@ -219,6 +223,40 @@ To add a list item use the function ``addListItem``. PHPWord\_Style\_ListItem. - ``$paragraphStyle`` See "Paragraph style" section. +Advanced usage: + +You can also create your own numbering style by changing the ``$listStyle`` parameter +with the name of your numbering style. + +.. code-block:: php + + $phpWord->addNumberingStyle( + 'multilevel', + array('type' => 'multilevel', 'levels' => array( + array('format' => 'decimal', 'text' => '%1.', 'left' => 360, 'hanging' => 360, 'tabPos' => 360), + array('format' => 'upperLetter', 'text' => '%2.', 'left' => 720, 'hanging' => 360, 'tabPos' => 720), + ) + ) + ); + $section->addListItem('List Item I', 0, null, 'multilevel'); + $section->addListItem('List Item I.a', 1, null, 'multilevel'); + $section->addListItem('List Item I.b', 1, null, 'multilevel'); + $section->addListItem('List Item II', 0, null, 'multilevel'); + +Level styles: + +- ``start`` Starting value +- ``format`` Numbering format bullet|decimal|upperRoman|lowerRoman|upperLetter|lowerLetter +- ``restart`` Restart numbering level symbol +- ``suffix`` Content between numbering symbol and paragraph text tab|space|nothing +- ``text`` Numbering level text e.g. %1 for nonbullet or bullet character +- ``align`` Numbering symbol align left|center|right|both +- ``left`` See paragraph style +- ``hanging`` See paragraph style +- ``tabPos`` See paragraph style +- ``font`` Font name +- ``hint`` See font style + Tables ------ diff --git a/src/PhpWord/Reader/Word2007.php b/src/PhpWord/Reader/Word2007.php index e03d28a0..4ff84c3f 100644 --- a/src/PhpWord/Reader/Word2007.php +++ b/src/PhpWord/Reader/Word2007.php @@ -221,9 +221,11 @@ class Word2007 extends AbstractReader implements ReaderInterface // Section properties if ($xmlReader->elementExists('w:pPr/w:sectPr', $node)) { $settingsNode = $xmlReader->getElement('w:pPr/w:sectPr', $node); - $settings = $this->readSectionStyle($xmlReader, $settingsNode); - $section->setSettings($settings); - $this->readHeaderFooter($filename, $settings, $section); + if (!is_null($settingsNode)) { + $settings = $this->readSectionStyle($xmlReader, $settingsNode); + $section->setSettings($settings); + $this->readHeaderFooter($filename, $settings, $section); + } $section = $this->phpWord->addSection(); } break; @@ -268,7 +270,9 @@ class Word2007 extends AbstractReader implements ReaderInterface $pStyle = $this->readParagraphStyle($xmlReader, $node); $fStyle = $this->readFontStyle($xmlReader, $node); if (empty($fStyle)) { - $this->phpWord->addParagraphStyle($name, $pStyle); + if (is_array($pStyle)) { + $this->phpWord->addParagraphStyle($name, $pStyle); + } } else { $this->phpWord->addFontStyle($name, $fStyle, $pStyle); } @@ -634,8 +638,9 @@ class Word2007 extends AbstractReader implements ReaderInterface } elseif ($rowNode->nodeName == 'w:tc') { // Cell $cellWidth = $xmlReader->getAttribute('w:w', $rowNode, 'w:tcPr/w:tcW'); $cellStyle = null; - if ($xmlReader->elementExists('w:tcPr', $rowNode)) { - $cellStyle = $this->readCellStyle($xmlReader, $xmlReader->getElement('w:tcPr', $rowNode)); + $cellStyleNode = $xmlReader->getElement('w:tcPr', $rowNode); + if (!is_null($cellStyleNode)) { + $cellStyle = $this->readCellStyle($xmlReader, $cellStyleNode); } $cell = $row->addCell($cellWidth, $cellStyle); @@ -786,6 +791,9 @@ class Word2007 extends AbstractReader implements ReaderInterface if ($domNode->nodeName == 'w:hyperlink') { $domNode = $xmlReader->getElement('w:r', $domNode); } + if (is_null($domNode)) { + return $style; + } if ($xmlReader->elementExists('w:rPr', $domNode)) { if ($xmlReader->elementExists('w:rPr/w:rStyle', $domNode)) { $style = $xmlReader->getAttribute('w:val', $domNode, 'w:rPr/w:rStyle'); diff --git a/src/PhpWord/Style.php b/src/PhpWord/Style.php index eb01786c..084d7131 100755 --- a/src/PhpWord/Style.php +++ b/src/PhpWord/Style.php @@ -34,7 +34,7 @@ class Style */ public static function addParagraphStyle($styleName, $styles) { - self::setStyleValues($styleName, $styles, new Paragraph()); + self::setStyleValues($styleName, new Paragraph(), $styles); } /** @@ -46,7 +46,7 @@ class Style */ public static function addFontStyle($styleName, $styleFont, $styleParagraph = null) { - self::setStyleValues($styleName, $styleFont, new Font('text', $styleParagraph)); + self::setStyleValues($styleName, new Font('text', $styleParagraph), $styleFont); } /** @@ -57,7 +57,7 @@ class Style */ public static function addLinkStyle($styleName, $styles) { - self::setStyleValues($styleName, $styles, new Font('link')); + self::setStyleValues($styleName, new Font('link'), $styles); } /** @@ -65,11 +65,11 @@ class Style * * @param string $styleName * @param array $styleTable - * @param array $styleFirstRow + * @param array|null $styleFirstRow */ public static function addTableStyle($styleName, $styleTable, $styleFirstRow = null) { - self::setStyleValues($styleName, null, new Table($styleTable, $styleFirstRow)); + self::setStyleValues($styleName, new Table($styleTable, $styleFirstRow), null); } /** @@ -81,7 +81,7 @@ class Style */ public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = null) { - self::setStyleValues("Heading_{$titleCount}", $styleFont, new Font('title', $styleParagraph)); + self::setStyleValues("Heading_{$titleCount}", new Font('title', $styleParagraph), $styleFont); } /** @@ -94,7 +94,7 @@ class Style */ public static function addNumberingStyle($styleName, $styleValues) { - self::setStyleValues($styleName, $styleValues, new Numbering()); + self::setStyleValues($styleName, new Numbering(), $styleValues); } /** @@ -156,13 +156,13 @@ class Style * Set style values and put it to static style collection * * @param string $styleName - * @param array $styleValues * @param Paragraph|Font|Table|Numbering $styleObject + * @param array|null $styleValues */ - private static function setStyleValues($styleName, $styleValues, $styleObject) + private static function setStyleValues($styleName, $styleObject, $styleValues = null) { if (!array_key_exists($styleName, self::$styles)) { - if (is_array($styleValues)) { + if (!is_null($styleValues) && is_array($styleValues)) { foreach ($styleValues as $key => $value) { $styleObject->setStyleValue($key, $value); } diff --git a/src/PhpWord/Style/ListItem.php b/src/PhpWord/Style/ListItem.php index 93a3bb07..f9e5e947 100644 --- a/src/PhpWord/Style/ListItem.php +++ b/src/PhpWord/Style/ListItem.php @@ -10,7 +10,6 @@ namespace PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style; -use PhpOffice\PhpWord\Style\Numbering; /** * List item style @@ -92,7 +91,7 @@ class ListItem extends AbstractStyle /** * Get numbering style name * - * @return integer + * @return string */ public function getNumStyle() { @@ -108,7 +107,7 @@ class ListItem extends AbstractStyle { $this->numStyle = $value; $numStyleObject = Style::getStyle($this->numStyle); - if (!is_null($numStyleObject)) { + if ($numStyleObject instanceof Numbering) { $this->numId = $numStyleObject->getIndex(); $numStyleObject->setNumId($this->numId); } @@ -234,6 +233,7 @@ class ListItem extends AbstractStyle // Populate style and register to global Style register $style = $listTypeStyles[$this->listType]; foreach ($style['levels'] as $key => $value) { + $level = array(); $levelProperties = explode(', ', $value); $level['level'] = $key; for ($i = 0; $i < count($properties); $i++) { diff --git a/src/PhpWord/Style/NumberingLevel.php b/src/PhpWord/Style/NumberingLevel.php index 77b63b40..2979f0c2 100644 --- a/src/PhpWord/Style/NumberingLevel.php +++ b/src/PhpWord/Style/NumberingLevel.php @@ -115,7 +115,7 @@ class NumberingLevel extends AbstractStyle */ public function getLevel() { - return $level->level; + return $this->level; } /** diff --git a/src/PhpWord/Template.php b/src/PhpWord/Template.php index 9f71d306..65ffd75f 100644 --- a/src/PhpWord/Template.php +++ b/src/PhpWord/Template.php @@ -421,17 +421,4 @@ class Template } return substr($this->documentXML, $startPosition, ($endPosition - $startPosition)); } - - /** - * Delete a block of text - * - * @param string $blockname - * @param string $replacement - * @deprecated - * @codeCoverageIgnore - */ - public function deleteTemplateBlock($blockname, $replacement = '') - { - $this->deleteBlock($blockname); - } } diff --git a/src/PhpWord/Writer/Word2007/Styles.php b/src/PhpWord/Writer/Word2007/Styles.php index 14a54b2d..ae784982 100644 --- a/src/PhpWord/Writer/Word2007/Styles.php +++ b/src/PhpWord/Writer/Word2007/Styles.php @@ -15,7 +15,6 @@ use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Paragraph; use PhpOffice\PhpWord\Style\Table; -use PhpOffice\PhpWord\Style\Numbering; /** * Word2007 styles part writer @@ -54,7 +53,6 @@ class Styles extends Base if ($styleName == 'Normal') { continue; } - $styleClass = str_replace('PhpOffice\\PhpWord\\Style\\', '', get_class($style)); // Font style if ($style instanceof Font) { From 42167f88558bf03d14b33c0305d0872052fb6bcb Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 18:16:24 +0700 Subject: [PATCH 05/29] Fix documentation format and some type check --- docs/general.rst | 4 ++-- src/PhpWord/Reader/Word2007.php | 8 ++++++-- src/PhpWord/Style/AbstractStyle.php | 2 +- src/PhpWord/Style/ListItem.php | 3 --- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/general.rst b/docs/general.rst index c267d87d..40c8da7e 100644 --- a/docs/general.rst +++ b/docs/general.rst @@ -63,9 +63,9 @@ XML Writer compatibility ~~~~~~~~~~~~~~~~~~~~~~~~ This option sets -```XMLWriter::setIndent`` `__ +`XMLWriter::setIndent `__ and -```XMLWriter::setIndentString`` `__. +`XMLWriter::setIndentString `__. The default value of this option is ``true`` (compatible), which is `required for OpenOffice `__ to render OOXML document correctly. You can set this option to ``false`` diff --git a/src/PhpWord/Reader/Word2007.php b/src/PhpWord/Reader/Word2007.php index 4ff84c3f..8df6c4ec 100644 --- a/src/PhpWord/Reader/Word2007.php +++ b/src/PhpWord/Reader/Word2007.php @@ -224,7 +224,9 @@ class Word2007 extends AbstractReader implements ReaderInterface if (!is_null($settingsNode)) { $settings = $this->readSectionStyle($xmlReader, $settingsNode); $section->setSettings($settings); - $this->readHeaderFooter($filename, $settings, $section); + if (!is_null($settings)) { + $this->readHeaderFooter($filename, $settings, $section); + } } $section = $this->phpWord->addSection(); } @@ -237,7 +239,9 @@ class Word2007 extends AbstractReader implements ReaderInterface case 'w:sectPr': // Last section $settings = $this->readSectionStyle($xmlReader, $node); $section->setSettings($settings); - $this->readHeaderFooter($filename, $settings, $section); + if (!is_null($settings)) { + $this->readHeaderFooter($filename, $settings, $section); + } break; } } diff --git a/src/PhpWord/Style/AbstractStyle.php b/src/PhpWord/Style/AbstractStyle.php index e77c26a6..11bfd8a4 100644 --- a/src/PhpWord/Style/AbstractStyle.php +++ b/src/PhpWord/Style/AbstractStyle.php @@ -107,7 +107,7 @@ abstract class AbstractStyle /** * Set integer value * - * @param mixed $value + * @param integer|null $value * @param integer|null $default * @return integer|null */ diff --git a/src/PhpWord/Style/ListItem.php b/src/PhpWord/Style/ListItem.php index f9e5e947..bb04d0e6 100644 --- a/src/PhpWord/Style/ListItem.php +++ b/src/PhpWord/Style/ListItem.php @@ -100,8 +100,6 @@ class ListItem extends AbstractStyle /** * Set numbering style name - * - * @param string $value */ public function setNumStyle($value) { @@ -126,7 +124,6 @@ class ListItem extends AbstractStyle /** * Get legacy numbering definition * - * @param integer $listType * @return array * @since 0.9.2 */ From ae652a63795ef0b273f9b6c1717bd3bb66971db2 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 19:04:53 +0700 Subject: [PATCH 06/29] Update upcoming version number to 0.10.0 as per #178 --- CHANGELOG.md | 4 ++-- src/PhpWord/Element/AbstractElement.php | 6 +++--- src/PhpWord/Element/Endnote.php | 2 +- src/PhpWord/Element/Footer.php | 4 ++-- src/PhpWord/Element/Footnote.php | 4 ++-- src/PhpWord/Element/Header.php | 2 +- src/PhpWord/Element/ListItem.php | 2 +- src/PhpWord/Element/Object.php | 4 ++-- src/PhpWord/Element/Section.php | 12 ++++++------ src/PhpWord/Endnotes.php | 2 +- src/PhpWord/Footnotes.php | 22 ++++++++++----------- src/PhpWord/Media.php | 26 ++++++++++++------------- src/PhpWord/PhpWord.php | 2 +- src/PhpWord/Reader/Word2007.php | 2 +- src/PhpWord/Shared/XMLReader.php | 2 +- src/PhpWord/Shared/ZipArchive.php | 2 +- src/PhpWord/Style.php | 6 +++--- src/PhpWord/Style/AbstractStyle.php | 4 ++-- src/PhpWord/Style/ListItem.php | 12 ++++++------ src/PhpWord/Style/Numbering.php | 2 +- src/PhpWord/Style/NumberingLevel.php | 2 +- src/PhpWord/Writer/AbstractWriter.php | 2 +- src/PhpWord/Writer/ODText/Base.php | 2 +- src/PhpWord/Writer/Word2007/Rels.php | 2 +- src/PhpWord/Writer/Word2007/Styles.php | 2 +- 25 files changed, 66 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f96b4a63..d00f16c7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ This is the changelog between releases of PHPWord. Releases are listed in reverse chronological order with the latest version listed on top, while additions/changes in each release are listed in chronological order. Changes in each release are divided into three parts: added or change features, bugfixes, and miscellaneous improvements. Each line contains short information about the change made, the person who made it, and the related issue number(s) in GitHub. -## 0.9.2 - Not yet released +## 0.10.0 - Not yet released This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. @@ -29,7 +29,7 @@ This release marked heavy refactorings on internal code structure with the creat - General: Add `Style::resetStyles()`, `Footnote::resetElements()`, and `TOC::resetTitles()` - @ivanlanin GH-187 - Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table, and list - @ivanlanin - Endnote: Ability to add endnotes - @ivanlanin -- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 +- ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 ### Bugfixes diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index 6562cb5b..b7a03934 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -34,7 +34,7 @@ use PhpOffice\PhpWord\Element\CheckBox; /** * Container abstract class * - * @since 0.9.2 + * @since 0.10.0 */ abstract class AbstractElement { @@ -563,7 +563,7 @@ abstract class AbstractElement * Create textrun element * * @param mixed $paragraphStyle - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function createTextRun($paragraphStyle = null) @@ -575,7 +575,7 @@ abstract class AbstractElement * Create footnote element * * @param mixed $paragraphStyle - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function createFootnote($paragraphStyle = null) diff --git a/src/PhpWord/Element/Endnote.php b/src/PhpWord/Element/Endnote.php index 084119c2..bdcf8e76 100644 --- a/src/PhpWord/Element/Endnote.php +++ b/src/PhpWord/Element/Endnote.php @@ -14,7 +14,7 @@ use PhpOffice\PhpWord\Style\Paragraph; /** * Endnote element * - * @since 0.9.2 + * @since 0.10.0 */ class Endnote extends Footnote { diff --git a/src/PhpWord/Element/Footer.php b/src/PhpWord/Element/Footer.php index 6d441126..8db9c6eb 100755 --- a/src/PhpWord/Element/Footer.php +++ b/src/PhpWord/Element/Footer.php @@ -44,7 +44,7 @@ class Footer extends AbstractElement * Set type * * @param string $value - * @since 0.9.2 + * @since 0.10.0 */ public function setType($value = self::AUTO) { @@ -55,7 +55,7 @@ class Footer extends AbstractElement * Get type * * @return string - * @since 0.9.2 + * @since 0.10.0 */ public function getType() { diff --git a/src/PhpWord/Element/Footnote.php b/src/PhpWord/Element/Footnote.php index 4dcc1fd4..8f1cf7bc 100644 --- a/src/PhpWord/Element/Footnote.php +++ b/src/PhpWord/Element/Footnote.php @@ -48,7 +48,7 @@ class Footnote extends AbstractElement * Get Footnote Reference ID * * @return int - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function getReferenceId() @@ -60,7 +60,7 @@ class Footnote extends AbstractElement * Set Footnote Reference ID * * @param int $rId - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function setReferenceId($rId) diff --git a/src/PhpWord/Element/Header.php b/src/PhpWord/Element/Header.php index c14ed0e7..e4211d29 100755 --- a/src/PhpWord/Element/Header.php +++ b/src/PhpWord/Element/Header.php @@ -64,7 +64,7 @@ class Header extends AbstractElement * Set header type * * @param string $value - * @since 0.9.2 + * @since 0.10.0 */ public function setType($value = self::AUTO) { diff --git a/src/PhpWord/Element/ListItem.php b/src/PhpWord/Element/ListItem.php index 39bd6b1b..bebf8b38 100644 --- a/src/PhpWord/Element/ListItem.php +++ b/src/PhpWord/Element/ListItem.php @@ -53,7 +53,7 @@ class ListItem extends AbstractElement $this->textObject = new Text($text, $fontStyle, $paragraphStyle); $this->depth = $depth; - // Version >= 0.9.2 will pass numbering style name. Older version will use old method + // Version >= 0.10.0 will pass numbering style name. Older version will use old method if (!is_null($listStyle) && is_string($listStyle)) { $this->style = new ListItemStyle($listStyle); } else { diff --git a/src/PhpWord/Element/Object.php b/src/PhpWord/Element/Object.php index fc373fbc..81004872 100644 --- a/src/PhpWord/Element/Object.php +++ b/src/PhpWord/Element/Object.php @@ -101,7 +101,7 @@ class Object extends AbstractElement * Get Object ID * * @return int - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function getObjectId() @@ -113,7 +113,7 @@ class Object extends AbstractElement * Set Object ID * * @param int $objId - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function setObjectId($objId) diff --git a/src/PhpWord/Element/Section.php b/src/PhpWord/Element/Section.php index 6abbbf98..82060e85 100644 --- a/src/PhpWord/Element/Section.php +++ b/src/PhpWord/Element/Section.php @@ -113,7 +113,7 @@ class Section extends AbstractElement * * @param string $type * @return Header - * @since 0.9.2 + * @since 0.10.0 */ public function addHeader($type = Header::AUTO) { @@ -125,7 +125,7 @@ class Section extends AbstractElement * * @param string $type * @return Footer - * @since 0.9.2 + * @since 0.10.0 */ public function addFooter($type = Header::AUTO) { @@ -177,7 +177,7 @@ class Section extends AbstractElement * @param boolean $header * @return Header|Footer * @throws Exception - * @since 0.9.2 + * @since 0.10.0 */ private function addHeaderFooter($type = Header::AUTO, $header = true) { @@ -201,7 +201,7 @@ class Section extends AbstractElement * Create header * * @return Header - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function createHeader() @@ -213,7 +213,7 @@ class Section extends AbstractElement * Create footer * * @return Footer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function createFooter() @@ -225,7 +225,7 @@ class Section extends AbstractElement * Get footer * * @return Footer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function getFooter() diff --git a/src/PhpWord/Endnotes.php b/src/PhpWord/Endnotes.php index 4a065b96..206814e8 100644 --- a/src/PhpWord/Endnotes.php +++ b/src/PhpWord/Endnotes.php @@ -14,7 +14,7 @@ use PhpOffice\PhpWord\Element\Endnote; /** * Endnote collection * - * @since 0.9.2 + * @since 0.10.0 */ class Endnotes { diff --git a/src/PhpWord/Footnotes.php b/src/PhpWord/Footnotes.php index 57cfdab8..5ff9e8d1 100644 --- a/src/PhpWord/Footnotes.php +++ b/src/PhpWord/Footnotes.php @@ -29,7 +29,7 @@ class Footnotes * * @param Footnote $element * @return integer Reference ID - * @since 0.9.2 + * @since 0.10.0 */ public static function addElement($element) { @@ -44,7 +44,7 @@ class Footnotes * * @param integer $index * @param Footnote $element - * @since 0.9.2 + * @since 0.10.0 */ public static function setElement($index, $element) { @@ -58,7 +58,7 @@ class Footnotes * * @param integer $index * @return Footnote - * @since 0.9.2 + * @since 0.10.0 */ public static function getElement($index) { @@ -73,7 +73,7 @@ class Footnotes * Get elements * * @return array - * @since 0.9.2 + * @since 0.10.0 */ public static function getElements() { @@ -84,7 +84,7 @@ class Footnotes * Get element count * * @return integer - * @since 0.9.2 + * @since 0.10.0 */ public static function countElements() { @@ -94,7 +94,7 @@ class Footnotes /** * Reset elements * - * @since 0.9.2 + * @since 0.10.0 */ public static function resetElements() { @@ -106,7 +106,7 @@ class Footnotes * * @param Footnote $element * @return integer Reference ID - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addFootnoteElement($element) @@ -118,7 +118,7 @@ class Footnotes * Get Footnote Elements * * @return array - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function getFootnoteElements() @@ -130,7 +130,7 @@ class Footnotes * Get Footnote Elements Count * * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function countFootnoteElements() @@ -143,7 +143,7 @@ class Footnotes * * @param string $linkSrc * @return integer Reference ID - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addFootnoteLinkElement($linkSrc) @@ -155,7 +155,7 @@ class Footnotes * Get Footnote Link Elements * * @return array - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function getFootnoteLinkElements() diff --git a/src/PhpWord/Media.php b/src/PhpWord/Media.php index 74f046bf..66079fd7 100755 --- a/src/PhpWord/Media.php +++ b/src/PhpWord/Media.php @@ -32,7 +32,7 @@ class Media * @param string $source * @param Image $image * @return integer - * @since 0.9.2 + * @since 0.10.0 */ public static function addElement($container, $mediaType, $source, Image $image = null) { @@ -97,7 +97,7 @@ class Media * @param string $container section|headerx|footerx|footnote|endnote * @param string $mediaType image|object|link * @return integer - * @since 0.9.2 + * @since 0.10.0 */ public static function countElements($container, $mediaType = null) { @@ -124,7 +124,7 @@ class Media * @param string $container section|headerx|footerx|footnote|endnote * @param string $mediaType image|object|link * @return array - * @since 0.9.2 + * @since 0.10.0 */ public static function getElements($container, $mediaType = null) { @@ -170,7 +170,7 @@ class Media * @param string $type * @param Image $image * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addSectionMediaElement($src, $type, Image $image = null) @@ -183,7 +183,7 @@ class Media * * @param string $linkSrc * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addSectionLinkElement($linkSrc) @@ -196,7 +196,7 @@ class Media * * @param string $key * @return array - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function getSectionMediaElements($key = null) @@ -209,7 +209,7 @@ class Media * * @param string $key * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function countSectionMediaElements($key = null) @@ -224,7 +224,7 @@ class Media * @param string $src * @param Image $image * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addHeaderMediaElement($headerCount, $src, Image $image = null) @@ -237,7 +237,7 @@ class Media * * @param string $key * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function countHeaderMediaElements($key) @@ -249,7 +249,7 @@ class Media * Get Header Media Elements * * @return array - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function getHeaderMediaElements() @@ -264,7 +264,7 @@ class Media * @param string $src * @param Image $image * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function addFooterMediaElement($footerCount, $src, Image $image = null) @@ -277,7 +277,7 @@ class Media * * @param string $key * @return integer - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function countFooterMediaElements($key) @@ -289,7 +289,7 @@ class Media * Get Footer Media Elements * * @return array - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public static function getFooterMediaElements() diff --git a/src/PhpWord/PhpWord.php b/src/PhpWord/PhpWord.php index 2764a3a1..73ba1cc3 100644 --- a/src/PhpWord/PhpWord.php +++ b/src/PhpWord/PhpWord.php @@ -256,7 +256,7 @@ class PhpWord * * @param array $settings * @return Section - * @deprecated 0.9.2 + * @deprecated 0.10.0 * @codeCoverageIgnore */ public function createSection($settings = null) diff --git a/src/PhpWord/Reader/Word2007.php b/src/PhpWord/Reader/Word2007.php index 8df6c4ec..5901046c 100644 --- a/src/PhpWord/Reader/Word2007.php +++ b/src/PhpWord/Reader/Word2007.php @@ -18,7 +18,7 @@ use PhpOffice\PhpWord\Element\Section; /** * Reader for Word2007 * - * @since 0.9.2 + * @since 0.10.0 * @todo title, list, watermark, checkbox, toc * @todo Partly done: image, object */ diff --git a/src/PhpWord/Shared/XMLReader.php b/src/PhpWord/Shared/XMLReader.php index 17e8454d..b7f5549e 100644 --- a/src/PhpWord/Shared/XMLReader.php +++ b/src/PhpWord/Shared/XMLReader.php @@ -15,7 +15,7 @@ use PhpOffice\PhpWord\Settings; /** * XML Reader wrapper * - * @since 0.9.2 + * @since 0.10.0 */ class XMLReader { diff --git a/src/PhpWord/Shared/ZipArchive.php b/src/PhpWord/Shared/ZipArchive.php index 60b7198c..d8519aca 100644 --- a/src/PhpWord/Shared/ZipArchive.php +++ b/src/PhpWord/Shared/ZipArchive.php @@ -22,7 +22,7 @@ require_once 'PCLZip/pclzip.lib.php'; /** * PCLZip wrapper * - * @since 0.9.2 + * @since 0.10.0 */ class ZipArchive { diff --git a/src/PhpWord/Style.php b/src/PhpWord/Style.php index 084d7131..e0b5d439 100755 --- a/src/PhpWord/Style.php +++ b/src/PhpWord/Style.php @@ -90,7 +90,7 @@ class Style * @param string $styleName * @param array $styleValues * @return Numbering - * @since 0.9.2 + * @since 0.10.0 */ public static function addNumberingStyle($styleName, $styleValues) { @@ -101,7 +101,7 @@ class Style * Count styles * * @return integer - * @since 0.9.2 + * @since 0.10.0 */ public static function countStyles() { @@ -110,7 +110,7 @@ class Style /** * Reset styles - * @since 0.9.2 + * @since 0.10.0 */ public static function resetStyles() { diff --git a/src/PhpWord/Style/AbstractStyle.php b/src/PhpWord/Style/AbstractStyle.php index 11bfd8a4..2c88bdb2 100644 --- a/src/PhpWord/Style/AbstractStyle.php +++ b/src/PhpWord/Style/AbstractStyle.php @@ -12,7 +12,7 @@ namespace PhpOffice\PhpWord\Style; /** * Abstract style class * - * @since 0.9.2 + * @since 0.10.0 */ abstract class AbstractStyle { @@ -58,7 +58,7 @@ abstract class AbstractStyle */ public function setStyleValue($key, $value) { - // Backward compability check for versions < 0.9.2 which use underscore + // Backward compability check for versions < 0.10.0 which use underscore // prefix for their private properties if (substr($key, 0, 1) == '_') { $key = substr($key, 1); diff --git a/src/PhpWord/Style/ListItem.php b/src/PhpWord/Style/ListItem.php index bb04d0e6..3c762920 100644 --- a/src/PhpWord/Style/ListItem.php +++ b/src/PhpWord/Style/ListItem.php @@ -14,8 +14,8 @@ use PhpOffice\PhpWord\Style; /** * List item style * - * Before version 0.9.2, numbering style is defined statically with $listType. - * After version 0.9.2, numbering style is defined by using Numbering and + * Before version 0.10.0, numbering style is defined statically with $listType. + * After version 0.10.0, numbering style is defined by using Numbering and * recorded by $numStyle. $listStyle is maintained for backward compatility */ class ListItem extends AbstractStyle @@ -38,7 +38,7 @@ class ListItem extends AbstractStyle * Numbering style name * * @var string - * @since 0.9.2 + * @since 0.10.0 */ private $numStyle; @@ -46,7 +46,7 @@ class ListItem extends AbstractStyle * Numbering definition instance ID * * @var integer - * @since 0.9.2 + * @since 0.10.0 */ private $numId; @@ -75,7 +75,7 @@ class ListItem extends AbstractStyle } /** - * Set legacy list type for version < 0.9.2 + * Set legacy list type for version < 0.10.0 * * @param integer $value */ @@ -125,7 +125,7 @@ class ListItem extends AbstractStyle * Get legacy numbering definition * * @return array - * @since 0.9.2 + * @since 0.10.0 */ private function getListTypeStyle() { diff --git a/src/PhpWord/Style/Numbering.php b/src/PhpWord/Style/Numbering.php index ce935b98..8c2e4a69 100644 --- a/src/PhpWord/Style/Numbering.php +++ b/src/PhpWord/Style/Numbering.php @@ -17,7 +17,7 @@ use PhpOffice\PhpWord\Style\NumberingLevel; * @link http://www.schemacentral.com/sc/ooxml/e-w_numbering.html * @link http://www.schemacentral.com/sc/ooxml/e-w_abstractNum-1.html * @link http://www.schemacentral.com/sc/ooxml/e-w_num-1.html - * @since 0.9.2 + * @since 0.10.0 */ class Numbering extends AbstractStyle { diff --git a/src/PhpWord/Style/NumberingLevel.php b/src/PhpWord/Style/NumberingLevel.php index 2979f0c2..dff7de22 100644 --- a/src/PhpWord/Style/NumberingLevel.php +++ b/src/PhpWord/Style/NumberingLevel.php @@ -13,7 +13,7 @@ namespace PhpOffice\PhpWord\Style; * Numbering level definition * * @link http://www.schemacentral.com/sc/ooxml/e-w_lvl-1.html - * @since 0.9.2 + * @since 0.10.0 */ class NumberingLevel extends AbstractStyle { diff --git a/src/PhpWord/Writer/AbstractWriter.php b/src/PhpWord/Writer/AbstractWriter.php index faa13ea6..684a5d32 100644 --- a/src/PhpWord/Writer/AbstractWriter.php +++ b/src/PhpWord/Writer/AbstractWriter.php @@ -16,7 +16,7 @@ use PhpOffice\PhpWord\Settings; /** * Abstract writer class * - * @since 0.9.2 + * @since 0.10.0 */ abstract class AbstractWriter implements WriterInterface { diff --git a/src/PhpWord/Writer/ODText/Base.php b/src/PhpWord/Writer/ODText/Base.php index a1f0d315..24eab60c 100644 --- a/src/PhpWord/Writer/ODText/Base.php +++ b/src/PhpWord/Writer/ODText/Base.php @@ -17,7 +17,7 @@ use PhpOffice\PhpWord\Shared\XMLWriter; /** * ODT base part writer * - * @since 0.9.2 + * @since 0.10.0 */ class Base extends AbstractWriterPart { diff --git a/src/PhpWord/Writer/Word2007/Rels.php b/src/PhpWord/Writer/Word2007/Rels.php index c708eeaf..ab3198dd 100755 --- a/src/PhpWord/Writer/Word2007/Rels.php +++ b/src/PhpWord/Writer/Word2007/Rels.php @@ -15,7 +15,7 @@ use PhpOffice\PhpWord\Shared\XMLWriter; /** * Word2007 relationship writer * - * @since 0.9.2 + * @since 0.10.0 */ class Rels extends AbstractWriterPart { diff --git a/src/PhpWord/Writer/Word2007/Styles.php b/src/PhpWord/Writer/Word2007/Styles.php index ae784982..38217847 100644 --- a/src/PhpWord/Writer/Word2007/Styles.php +++ b/src/PhpWord/Writer/Word2007/Styles.php @@ -19,7 +19,7 @@ use PhpOffice\PhpWord\Style\Table; /** * Word2007 styles part writer * - * @todo Do something with the numbering style introduced in 0.9.2 + * @todo Do something with the numbering style introduced in 0.10.0 */ class Styles extends Base { From a3a9af51e5ed991e75825de38a77404a0559f58e Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 21:16:07 +0700 Subject: [PATCH 07/29] Additional unit tests and some code deduplication --- src/PhpWord/Element/Section.php | 3 -- src/PhpWord/Shared/String.php | 17 +++++++ src/PhpWord/Style/AbstractStyle.php | 16 +++--- src/PhpWord/Style/Cell.php | 6 +-- src/PhpWord/Style/Font.php | 2 - src/PhpWord/Style/Paragraph.php | 7 +-- src/PhpWord/Style/Row.php | 35 +++++-------- src/PhpWord/Style/Section.php | 6 +-- src/PhpWord/Style/TOC.php | 11 ----- src/PhpWord/Style/Table.php | 12 ++--- src/PhpWord/TOC.php | 6 --- .../Tests/Style/NumberingLevelTest.php | 49 +++++++++++++++++++ 12 files changed, 96 insertions(+), 74 deletions(-) create mode 100644 tests/PhpWord/Tests/Style/NumberingLevelTest.php diff --git a/src/PhpWord/Element/Section.php b/src/PhpWord/Element/Section.php index 82060e85..9e5dbd0a 100644 --- a/src/PhpWord/Element/Section.php +++ b/src/PhpWord/Element/Section.php @@ -66,9 +66,6 @@ class Section extends AbstractElement if (is_null($value)) { continue; } - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } $this->settings->setSettingValue($key, $value); } } diff --git a/src/PhpWord/Shared/String.php b/src/PhpWord/Shared/String.php index e603f034..95f75f13 100644 --- a/src/PhpWord/Shared/String.php +++ b/src/PhpWord/Shared/String.php @@ -77,6 +77,23 @@ class String return $value; } + /** + * Return name without underscore for < 0.10.0 variable name compatibility + * + * @param string $value + * @return string + */ + public static function removeUnderscorePrefix($value) + { + if (!is_null($value)) { + if (substr($value, 0, 1) == '_') { + $value = substr($value, 1); + } + } + + return $value; + } + /** * Build control characters array */ diff --git a/src/PhpWord/Style/AbstractStyle.php b/src/PhpWord/Style/AbstractStyle.php index 2c88bdb2..45ba17a7 100644 --- a/src/PhpWord/Style/AbstractStyle.php +++ b/src/PhpWord/Style/AbstractStyle.php @@ -9,6 +9,8 @@ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Shared\String; + /** * Abstract style class * @@ -50,7 +52,10 @@ abstract class AbstractStyle /** * Set style value template method * - * Some child classes have their own specific overrides + * Some child classes have their own specific overrides. + * Backward compability check for versions < 0.10.0 which use underscore + * prefix for their private properties. + * Check if the set method is exists. Throws an exception? * * @param string $key * @param string $value @@ -58,14 +63,7 @@ abstract class AbstractStyle */ public function setStyleValue($key, $value) { - // Backward compability check for versions < 0.10.0 which use underscore - // prefix for their private properties - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } - - // Check if the set method is exists. Throws an exception? - $method = 'set' . $key; + $method = 'set' . String::removeUnderscorePrefix($key); if (method_exists($this, $method)) { $this->$method($value); } diff --git a/src/PhpWord/Style/Cell.php b/src/PhpWord/Style/Cell.php index 2e1f9d79..64a7f35a 100644 --- a/src/PhpWord/Style/Cell.php +++ b/src/PhpWord/Style/Cell.php @@ -9,6 +9,8 @@ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Shared\String; + /** * Table cell style */ @@ -145,9 +147,7 @@ class Cell extends AbstractStyle */ public function setStyleValue($key, $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } + $key = String::removeUnderscorePrefix($key); if ($key == 'borderSize') { $this->setBorderSize($value); } elseif ($key == 'borderColor') { diff --git a/src/PhpWord/Style/Font.php b/src/PhpWord/Style/Font.php index 2fef3a66..dd8ff02a 100644 --- a/src/PhpWord/Style/Font.php +++ b/src/PhpWord/Style/Font.php @@ -193,8 +193,6 @@ class Font extends AbstractStyle if ($key === 'line-height') { $this->setLineHeight($value); null; - } elseif (substr($key, 0, 1) == '_') { - $key = substr($key, 1); } $this->setStyleValue($key, $value); } diff --git a/src/PhpWord/Style/Paragraph.php b/src/PhpWord/Style/Paragraph.php index 8feb7924..57ad4405 100755 --- a/src/PhpWord/Style/Paragraph.php +++ b/src/PhpWord/Style/Paragraph.php @@ -10,6 +10,7 @@ namespace PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Exception\InvalidStyleException; +use PhpOffice\PhpWord\Shared\String; /** * Paragraph style @@ -127,8 +128,6 @@ class Paragraph extends AbstractStyle foreach ($style as $key => $value) { if ($key === 'line-height') { null; - } elseif (substr($key, 0, 1) == '_') { - $key = substr($key, 1); } $this->setStyleValue($key, $value); } @@ -144,9 +143,7 @@ class Paragraph extends AbstractStyle */ public function setStyleValue($key, $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } + $key = String::removeUnderscorePrefix($key); if ($key == 'indent' || $key == 'hanging') { $value = $value * 720; } elseif ($key == 'spacing') { diff --git a/src/PhpWord/Style/Row.php b/src/PhpWord/Style/Row.php index d4dc642f..698adea4 100644 --- a/src/PhpWord/Style/Row.php +++ b/src/PhpWord/Style/Row.php @@ -45,16 +45,12 @@ class Row extends AbstractStyle /** * Set tblHeader * - * @param boolean $pValue - * @return $this + * @param boolean $value + * @return self */ - public function setTblHeader($pValue = false) + public function setTblHeader($value = false) { - if (!is_bool($pValue)) { - $pValue = false; - } - $this->tblHeader = $pValue; - return $this; + $this->tblHeader = $this->setBoolVal($value, $this->tblHeader); } /** @@ -70,16 +66,12 @@ class Row extends AbstractStyle /** * Set cantSplit * - * @param boolean $pValue - * @return $this + * @param boolean $value + * @return self */ - public function setCantSplit($pValue = false) + public function setCantSplit($value = false) { - if (!is_bool($pValue)) { - $pValue = false; - } - $this->cantSplit = $pValue; - return $this; + $this->cantSplit = $this->setBoolVal($value, $this->cantSplit); } /** @@ -95,15 +87,12 @@ class Row extends AbstractStyle /** * Set exactHeight * - * @param bool $pValue - * @return $this + * @param bool $value + * @return self */ - public function setExactHeight($pValue = false) + public function setExactHeight($value = false) { - if (!is_bool($pValue)) { - $pValue = false; - } - $this->exactHeight = $pValue; + $this->exactHeight = $this->setBoolVal($value, $this->exactHeight); return $this; } diff --git a/src/PhpWord/Style/Section.php b/src/PhpWord/Style/Section.php index 6005e3ca..717fdaf7 100644 --- a/src/PhpWord/Style/Section.php +++ b/src/PhpWord/Style/Section.php @@ -9,6 +9,8 @@ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Shared\String; + /** * Section settings */ @@ -217,9 +219,7 @@ class Section extends AbstractStyle */ public function setSettingValue($key, $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } + $key = String::removeUnderscorePrefix($key); if ($key == 'orientation' && $value == 'landscape') { $this->setLandscape(); } elseif ($key == 'orientation' && is_null($value)) { diff --git a/src/PhpWord/Style/TOC.php b/src/PhpWord/Style/TOC.php index f7a752a9..e8a781b0 100644 --- a/src/PhpWord/Style/TOC.php +++ b/src/PhpWord/Style/TOC.php @@ -110,15 +110,4 @@ class TOC extends AbstractStyle { $this->indent = $pValue; } - - /** - * Set style value - * - * @param string $key - * @param string $value - */ - public function setStyleValue($key, $value) - { - $this->$key = $value; - } } diff --git a/src/PhpWord/Style/Table.php b/src/PhpWord/Style/Table.php index f7c98c36..000ecff7 100755 --- a/src/PhpWord/Style/Table.php +++ b/src/PhpWord/Style/Table.php @@ -9,6 +9,8 @@ namespace PhpOffice\PhpWord\Style; +use PhpOffice\PhpWord\Shared\String; + /** * Table style */ @@ -161,18 +163,12 @@ class Table extends AbstractStyle unset($this->firstRow->borderInsideHColor); unset($this->firstRow->borderInsideHSize); foreach ($styleFirstRow as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } $this->firstRow->setStyleValue($key, $value); } } if (!is_null($styleTable) && is_array($styleTable)) { foreach ($styleTable as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } $this->setStyleValue($key, $value); } } @@ -186,9 +182,7 @@ class Table extends AbstractStyle */ public function setStyleValue($key, $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } + $key = String::removeUnderscorePrefix($key); if ($key == 'borderSize') { $this->setBorderSize($value); } elseif ($key == 'borderColor') { diff --git a/src/PhpWord/TOC.php b/src/PhpWord/TOC.php index d84bf770..22c79634 100644 --- a/src/PhpWord/TOC.php +++ b/src/PhpWord/TOC.php @@ -82,9 +82,6 @@ class TOC if (!is_null($styleTOC) && is_array($styleTOC)) { foreach ($styleTOC as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } self::$TOCStyle->setStyleValue($key, $value); } } @@ -93,9 +90,6 @@ class TOC if (is_array($styleFont)) { self::$fontStyle = new Font(); foreach ($styleFont as $key => $value) { - if (substr($key, 0, 1) == '_') { - $key = substr($key, 1); - } self::$fontStyle->setStyleValue($key, $value); } } else { diff --git a/tests/PhpWord/Tests/Style/NumberingLevelTest.php b/tests/PhpWord/Tests/Style/NumberingLevelTest.php new file mode 100644 index 00000000..f3e28a0e --- /dev/null +++ b/tests/PhpWord/Tests/Style/NumberingLevelTest.php @@ -0,0 +1,49 @@ + 1, + 'start' => 1, + 'format' => 'decimal', + 'restart' => 1, + 'suffix' => 'space', + 'text' => '%1.', + 'align' => 'left', + 'left' => 360, + 'hanging' => 360, + 'tabPos' => 360, + 'font' => 'Arial', + 'hint' => 'default', + ); + foreach ($attributes as $key => $value) { + $set = "set{$key}"; + $get = "get{$key}"; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + } + } +} From a5c815d50cb4ba6caa23b49b91b2dc6fec23fab8 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Fri, 11 Apr 2014 23:02:05 +0700 Subject: [PATCH 08/29] ODT: Basic table writing support --- CHANGELOG.md | 1 + src/PhpWord/Element/AbstractElement.php | 100 ++++- src/PhpWord/Element/Table.php | 33 +- src/PhpWord/Writer/ODText/Content.php | 469 +++++++++++++++--------- 4 files changed, 412 insertions(+), 191 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00f16c7..03400d46 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This release marked heavy refactorings on internal code structure with the creat - Reader: Ability to read header, footer, footnotes, link, preservetext, textbreak, pagebreak, table, and list - @ivanlanin - Endnote: Ability to add endnotes - @ivanlanin - ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 +- ODT Writer: Basic table writing support - @ivanlanin ### Bugfixes diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index b7a03934..890227dc 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -81,6 +81,20 @@ abstract class AbstractElement */ protected $elements = array(); + /** + * Index of element in the elements collection (start with 1) + * + * @var integer + */ + protected $elementIndex = 1; + + /** + * Unique Id for element + * + * @var integer + */ + protected $elementId; + /** * Relation Id * @@ -108,7 +122,7 @@ abstract class AbstractElement $text = String::toUTF8($text); $textObject = new Text($text, $fontStyle, $paragraphStyle); $textObject->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $textObject; + $this->addElement($textObject); return $textObject; } @@ -125,7 +139,7 @@ abstract class AbstractElement $textRun = new TextRun($paragraphStyle); $textRun->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $textRun; + $this->addElement($textRun); return $textRun; } @@ -148,7 +162,7 @@ abstract class AbstractElement $link->setDocPart($this->getDocPart(), $this->getDocPartId()); $rId = Media::addElement($elementDocPart, 'link', $linkSrc); $link->setRelationId($rId); - $this->elements[] = $link; + $this->addElement($link); return $link; } @@ -179,7 +193,7 @@ abstract class AbstractElement $bookmarkId = $data[1]; $title->setAnchor($anchor); $title->setBookmarkId($bookmarkId); - $this->elements[] = $title; + $this->addElement($title); return $title; } @@ -198,7 +212,7 @@ abstract class AbstractElement $preserveText = new PreserveText(String::toUTF8($text), $fontStyle, $paragraphStyle); $preserveText->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $preserveText; + $this->addElement($preserveText); return $preserveText; } @@ -217,7 +231,7 @@ abstract class AbstractElement for ($i = 1; $i <= $count; $i++) { $textBreak = new TextBreak($fontStyle, $paragraphStyle); $textBreak->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $textBreak; + $this->addElement($textBreak); } } @@ -237,7 +251,7 @@ abstract class AbstractElement $listItem = new ListItem(String::toUTF8($text), $depth, $fontStyle, $styleList, $paragraphStyle); $listItem->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $listItem; + $this->addElement($listItem); return $listItem; } @@ -253,7 +267,7 @@ abstract class AbstractElement $this->checkValidity('table'); $table = new Table($this->getDocPart(), $this->getDocPartId(), $style); - $this->elements[] = $table; + $this->addElement($table); return $table; } @@ -275,7 +289,8 @@ abstract class AbstractElement $image->setDocPart($this->getDocPart(), $this->getDocPartId()); $rId = Media::addElement($elementDocPart, 'image', $src, $image); $image->setRelationId($rId); - $this->elements[] = $image; + $this->addElement($image); + return $image; } @@ -307,7 +322,8 @@ abstract class AbstractElement $object->setRelationId($rId); $rIdimg = Media::addElement($elementDocPart, 'image', $icon, new Image($icon)); $object->setImageRelationId($rIdimg); - $this->elements[] = $object; + $this->addElement($object); + return $object; } else { throw new InvalidObjectException(); @@ -329,7 +345,7 @@ abstract class AbstractElement $footnote->setDocPart('footnote', $this->getDocPartId()); $footnote->setRelationId($rId); - $this->elements[] = $footnote; + $this->addElement($footnote); return $footnote; } @@ -349,7 +365,7 @@ abstract class AbstractElement $endnote->setDocPart('endnote', $this->getDocPartId()); $endnote->setRelationId($rId); - $this->elements[] = $endnote; + $this->addElement($endnote); return $endnote; } @@ -369,7 +385,7 @@ abstract class AbstractElement $checkBox = new CheckBox(String::toUTF8($name), String::toUTF8($text), $fontStyle, $paragraphStyle); $checkBox->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->elements[] = $checkBox; + $this->addElement($checkBox); return $checkBox; } @@ -416,6 +432,16 @@ abstract class AbstractElement return $this->docPartId; } + /** + * Set element index and unique id, and add element into elements collection + */ + protected function addElement(AbstractElement $element) + { + $element->setElementIndex($this->countElements() + 1); + $element->setElementId(); + $this->elements[] = $element; + } + /** * Get all elements * @@ -426,6 +452,54 @@ abstract class AbstractElement return $this->elements; } + /** + * Count elements + * + * @return integer + */ + public function countElements() + { + return count($this->elements); + } + + /** + * Get element index + * + * @return int + */ + public function getElementIndex() + { + return $this->elementIndex; + } + + /** + * Set element index + * + * @param int $value + */ + public function setElementIndex($value) + { + $this->elementIndex = $value; + } + + /** + * Get element unique ID + * + * @return string + */ + public function getElementId() + { + return $this->elementId; + } + + /** + * Set element unique ID from 6 first digit of md5 + */ + public function setElementId() + { + $this->elementId = substr(md5(rand()), 0, 6); + } + /** * Get relation Id * diff --git a/src/PhpWord/Element/Table.php b/src/PhpWord/Element/Table.php index 90913582..3241a8e2 100644 --- a/src/PhpWord/Element/Table.php +++ b/src/PhpWord/Element/Table.php @@ -35,7 +35,7 @@ class Table extends AbstractElement /** * Table width * - * @var int + * @var integer */ private $width = null; @@ -44,7 +44,7 @@ class Table extends AbstractElement * Create a new table * * @param string $docPart - * @param int $docPartId + * @param integer $docPartId * @param mixed $style */ public function __construct($docPart, $docPartId, $style = null) @@ -56,7 +56,7 @@ class Table extends AbstractElement /** * Add a row * - * @param int $height + * @param integer $height * @param mixed $style */ public function addRow($height = null, $style = null) @@ -69,7 +69,7 @@ class Table extends AbstractElement /** * Add a cell * - * @param int $width + * @param integer $width * @param mixed $style * @return Cell */ @@ -103,7 +103,7 @@ class Table extends AbstractElement /** * Set table width * - * @param int $width + * @param integer $width */ public function setWidth($width) { @@ -113,10 +113,31 @@ class Table extends AbstractElement /** * Get table width * - * @return int + * @return integer */ public function getWidth() { return $this->width; } + + /** + * Get column count + * + * @return integer + */ + public function countColumns() + { + $columnCount = 0; + if (is_array($this->rows)) { + $rowCount = count($this->rows); + for ($i = 0; $i < $rowCount; $i++) { + $cellCount = count($this->rows[$i]->getCells()); + if ($columnCount < $cellCount) { + $columnCount = $cellCount; + } + } + } + + return $columnCount; + } } diff --git a/src/PhpWord/Writer/ODText/Content.php b/src/PhpWord/Writer/ODText/Content.php index 327aed34..e8f087fe 100644 --- a/src/PhpWord/Writer/ODText/Content.php +++ b/src/PhpWord/Writer/ODText/Content.php @@ -24,7 +24,6 @@ use PhpOffice\PhpWord\Shared\XMLWriter; use PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Paragraph; -use PhpOffice\PhpWord\TOC; /** * ODText content part writer @@ -34,7 +33,6 @@ class Content extends Base /** * Write content file to XML format * - * @param PhpWord $phpWord * @return string XML Output */ public function writeContent(PhpWord $phpWord = null) @@ -95,10 +93,304 @@ class Content extends Base } } - // office:font-face-decls - $this->writeFontFaces($xmlWriter); - // office:automatic-styles + $this->writeFontFaces($xmlWriter); // office:font-face-decls + + $this->writeAutomaticStyles($xmlWriter); // office:automatic-styles + + // Tables + $sections = $phpWord->getSections(); + $countSections = count($sections); + if ($countSections > 0) { + $sectionId = 0; + foreach ($sections as $section) { + $sectionId++; + $elements = $section->getElements(); + foreach ($elements as $element) { + if ($elements instanceof Table) { + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', $element->getElementId()); + $objWriter->writeAttribute('style:family', 'table'); + $objWriter->startElement('style:table-properties'); + //$objWriter->writeAttribute('style:width', 'table'); + $objWriter->writeAttribute('style:rel-width', 100); + $objWriter->writeAttribute('table:align', 'center'); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + } + + $xmlWriter->endElement(); + + // office:body + $xmlWriter->startElement('office:body'); + // office:text + $xmlWriter->startElement('office:text'); + // text:sequence-decls + $xmlWriter->startElement('text:sequence-decls'); + // text:sequence-decl + $xmlWriter->startElement('text:sequence-decl'); + $xmlWriter->writeAttribute('text:display-outline-level', 0); + $xmlWriter->writeAttribute('text:name', 'Illustration'); + $xmlWriter->endElement(); + // text:sequence-decl + $xmlWriter->startElement('text:sequence-decl'); + $xmlWriter->writeAttribute('text:display-outline-level', 0); + $xmlWriter->writeAttribute('text:name', 'Table'); + $xmlWriter->endElement(); + // text:sequence-decl + $xmlWriter->startElement('text:sequence-decl'); + $xmlWriter->writeAttribute('text:display-outline-level', 0); + $xmlWriter->writeAttribute('text:name', 'Text'); + $xmlWriter->endElement(); + // text:sequence-decl + $xmlWriter->startElement('text:sequence-decl'); + $xmlWriter->writeAttribute('text:display-outline-level', 0); + $xmlWriter->writeAttribute('text:name', 'Drawing'); + $xmlWriter->endElement(); + $xmlWriter->endElement(); + + $sections = $phpWord->getSections(); + $countSections = count($sections); + if ($countSections > 0) { + foreach ($sections as $section) { + $elements = $section->getElements(); + + foreach ($elements as $element) { + if ($element instanceof Text) { + $this->writeText($xmlWriter, $element); + } elseif ($element instanceof TextRun) { + $this->writeTextRun($xmlWriter, $element); + } elseif ($element instanceof Link) { + $this->writeLink($xmlWriter, $element); + } elseif ($element instanceof Title) { + $this->writeTitle($xmlWriter, $element); + } elseif ($element instanceof ListItem) { + $this->writeListItem($xmlWriter, $element); + } elseif ($element instanceof TextBreak) { + $this->writeTextBreak($xmlWriter); + } elseif ($element instanceof PageBreak) { + $this->writePageBreak($xmlWriter); + } elseif ($element instanceof Table) { + $this->writeTable($xmlWriter, $element); + } elseif ($element instanceof Image) { + $this->writeImage($xmlWriter, $element); + } elseif ($element instanceof Object) { + $this->writeObject($xmlWriter, $element); + } + } + } + } + $xmlWriter->endElement(); + $xmlWriter->endElement(); + $xmlWriter->endElement(); + + // Return + return $xmlWriter->getData(); + } + + /** + * Write text + * + * @param bool $withoutP + */ + protected function writeText(XMLWriter $xmlWriter, Text $text, $withoutP = false) + { + $styleFont = $text->getFontStyle(); + $styleParagraph = $text->getParagraphStyle(); + + // @todo Commented for TextRun. Should really checkout this value + // $SfIsObject = ($styleFont instanceof Font) ? true : false; + $SfIsObject = false; + + if ($SfIsObject) { + // Don't never be the case, because I browse all sections for cleaning all styles not declared + die('PhpWord : $SfIsObject wouldn\'t be an object'); + } else { + if (!$withoutP) { + $xmlWriter->startElement('text:p'); // text:p + } + if (empty($styleFont)) { + if (empty($styleParagraph)) { + $xmlWriter->writeAttribute('text:style-name', 'P1'); + } elseif (is_string($styleParagraph)) { + $xmlWriter->writeAttribute('text:style-name', $styleParagraph); + } + $xmlWriter->writeRaw($text->getText()); + } else { + if (empty($styleParagraph)) { + $xmlWriter->writeAttribute('text:style-name', 'Standard'); + } elseif (is_string($styleParagraph)) { + $xmlWriter->writeAttribute('text:style-name', $styleParagraph); + } + // text:span + $xmlWriter->startElement('text:span'); + if (is_string($styleFont)) { + $xmlWriter->writeAttribute('text:style-name', $styleFont); + } + $xmlWriter->writeRaw($text->getText()); + $xmlWriter->endElement(); + } + if (!$withoutP) { + $xmlWriter->endElement(); // text:p + } + } + } + + /** + * Write TextRun section + * + * @todo Enable all other section types + */ + protected function writeTextRun(XMLWriter $xmlWriter, TextRun $textrun) + { + $elements = $textrun->getElements(); + $xmlWriter->startElement('text:p'); + if (count($elements) > 0) { + foreach ($elements as $element) { + if ($element instanceof Text) { + $this->writeText($xmlWriter, $element, true); + } + } + } + $xmlWriter->endElement(); + } + + /** + * Write link element + */ + protected function writeLink(XMLWriter $xmlWriter, Link $link) + { + $this->writeUnsupportedElement($xmlWriter, 'Link'); + } + + /** + * Write title element + */ + protected function writeTitle(XMLWriter $xmlWriter, Title $title) + { + $this->writeUnsupportedElement($xmlWriter, 'Title'); + } + + /** + * Write preserve text + */ + protected function writePreserveText(XMLWriter $xmlWriter, PreserveText $preservetext) + { + $this->writeUnsupportedElement($xmlWriter, 'PreserveText'); + } + + /** + * Write list item + */ + protected function writeListItem(XMLWriter $xmlWriter, ListItem $listItem) + { + $this->writeUnsupportedElement($xmlWriter, 'ListItem'); + } + + /** + * Write text break + */ + protected function writeTextBreak(XMLWriter $xmlWriter) + { + $xmlWriter->startElement('text:p'); + $xmlWriter->writeAttribute('text:style-name', 'Standard'); + $xmlWriter->endElement(); + } + + /** + * Write page break + */ + protected function writePageBreak(XMLWriter $xmlWriter) + { + $this->writeUnsupportedElement($xmlWriter, 'PageBreak'); + } + + /** + * Write table + */ + protected function writeTable(XMLWriter $xmlWriter, Table $table) + { + $rows = $table->getRows(); + $rowCount = count($rows); + $colCount = $table->countColumns(); + if ($rowCount > 0) { + $xmlWriter->startElement('table:table'); + $xmlWriter->writeAttribute('table:name', $table->getElementId()); + $xmlWriter->writeAttribute('table:style', $table->getElementId()); + + $xmlWriter->startElement('table:table-column'); + $xmlWriter->writeAttribute('table:number-columns-repeated', $colCount); + $xmlWriter->endElement(); // table:table-column + + foreach ($rows as $row) { + $xmlWriter->startElement('table:table-row'); + foreach ($row->getCells() as $cell) { + $xmlWriter->startElement('table:table-cell'); + $xmlWriter->writeAttribute('office:value-type', 'string'); + $elements = $cell->getElements(); + if (count($elements) > 0) { + foreach ($elements as $element) { + if ($element instanceof Text) { + $this->writeText($xmlWriter, $element); + } elseif ($element instanceof TextRun) { + $this->writeTextRun($xmlWriter, $element); + } elseif ($element instanceof ListItem) { + $this->writeListItem($xmlWriter, $element); + } elseif ($element instanceof TextBreak) { + $this->writeTextBreak($xmlWriter); + } elseif ($element instanceof Image) { + $this->writeImage($xmlWriter, $element); + } elseif ($element instanceof Object) { + $this->writeObject($xmlWriter, $element); + } + } + } else { + $this->writeTextBreak($xmlWriter); + } + $xmlWriter->endElement(); // table:table-cell + } + $xmlWriter->endElement(); // table:table-row + } + $xmlWriter->endElement(); // table:table + } + } + + /** + * Write image + */ + protected function writeImage(XMLWriter $xmlWriter, Image $element) + { + $this->writeUnsupportedElement($xmlWriter, 'Image'); + } + + /** + * Write object + */ + protected function writeObject(XMLWriter $xmlWriter, Object $element) + { + $this->writeUnsupportedElement($xmlWriter, 'Object'); + } + + /** + * Write unsupported element + * + * @param string $element + */ + private function writeUnsupportedElement(XMLWriter $xmlWriter, $element) + { + $xmlWriter->startElement('text:p'); + $xmlWriter->writeRaw($element); + $xmlWriter->endElement(); + } + + /** + * Write automatic styles + */ + private function writeAutomaticStyles(XMLWriter $xmlWriter) + { $xmlWriter->startElement('office:automatic-styles'); $styles = Style::getStyles(); $numPStyles = 0; @@ -151,172 +443,5 @@ class Content extends Base $xmlWriter->endElement(); } } - $xmlWriter->endElement(); - - // office:body - $xmlWriter->startElement('office:body'); - // office:text - $xmlWriter->startElement('office:text'); - // text:sequence-decls - $xmlWriter->startElement('text:sequence-decls'); - // text:sequence-decl - $xmlWriter->startElement('text:sequence-decl'); - $xmlWriter->writeAttribute('text:display-outline-level', 0); - $xmlWriter->writeAttribute('text:name', 'Illustration'); - $xmlWriter->endElement(); - // text:sequence-decl - $xmlWriter->startElement('text:sequence-decl'); - $xmlWriter->writeAttribute('text:display-outline-level', 0); - $xmlWriter->writeAttribute('text:name', 'Table'); - $xmlWriter->endElement(); - // text:sequence-decl - $xmlWriter->startElement('text:sequence-decl'); - $xmlWriter->writeAttribute('text:display-outline-level', 0); - $xmlWriter->writeAttribute('text:name', 'Text'); - $xmlWriter->endElement(); - // text:sequence-decl - $xmlWriter->startElement('text:sequence-decl'); - $xmlWriter->writeAttribute('text:display-outline-level', 0); - $xmlWriter->writeAttribute('text:name', 'Drawing'); - $xmlWriter->endElement(); - $xmlWriter->endElement(); - - $sections = $phpWord->getSections(); - $countSections = count($sections); - if ($countSections > 0) { - foreach ($sections as $section) { - $elements = $section->getElements(); - - foreach ($elements as $element) { - if ($element instanceof Text) { - $this->writeText($xmlWriter, $element); - } elseif ($element instanceof TextRun) { - $this->writeTextRun($xmlWriter, $element); - } elseif ($element instanceof TextBreak) { - $this->writeTextBreak($xmlWriter); - } elseif ($element instanceof Link) { - $this->writeUnsupportedElement($xmlWriter, 'Link'); - } elseif ($element instanceof Title) { - $this->writeUnsupportedElement($xmlWriter, 'Title'); - } elseif ($element instanceof PageBreak) { - $this->writeUnsupportedElement($xmlWriter, 'Page Break'); - } elseif ($element instanceof Table) { - $this->writeUnsupportedElement($xmlWriter, 'Table'); - } elseif ($element instanceof ListItem) { - $this->writeUnsupportedElement($xmlWriter, 'List Item'); - } elseif ($element instanceof Image) { - $this->writeUnsupportedElement($xmlWriter, 'Image'); - } elseif ($element instanceof Object) { - $this->writeUnsupportedElement($xmlWriter, 'Object'); - } elseif ($element instanceof TOC) { - $this->writeUnsupportedElement($xmlWriter, 'TOC'); - } else { - $this->writeUnsupportedElement($xmlWriter, 'Element'); - } - } - } - } - $xmlWriter->endElement(); - $xmlWriter->endElement(); - $xmlWriter->endElement(); - - // Return - return $xmlWriter->getData(); - } - - /** - * Write text - * - * @param XMLWriter $xmlWriter - * @param Text $text - * @param bool $withoutP - */ - protected function writeText(XMLWriter $xmlWriter, Text $text, $withoutP = false) - { - $styleFont = $text->getFontStyle(); - $styleParagraph = $text->getParagraphStyle(); - - // @todo Commented for TextRun. Should really checkout this value - // $SfIsObject = ($styleFont instanceof Font) ? true : false; - $SfIsObject = false; - - if ($SfIsObject) { - // Don't never be the case, because I browse all sections for cleaning all styles not declared - die('PhpWord : $SfIsObject wouldn\'t be an object'); - } else { - if (!$withoutP) { - $xmlWriter->startElement('text:p'); // text:p - } - if (empty($styleFont)) { - if (empty($styleParagraph)) { - $xmlWriter->writeAttribute('text:style-name', 'P1'); - } elseif (is_string($styleParagraph)) { - $xmlWriter->writeAttribute('text:style-name', $styleParagraph); - } - $xmlWriter->writeRaw($text->getText()); - } else { - if (empty($styleParagraph)) { - $xmlWriter->writeAttribute('text:style-name', 'Standard'); - } elseif (is_string($styleParagraph)) { - $xmlWriter->writeAttribute('text:style-name', $styleParagraph); - } - // text:span - $xmlWriter->startElement('text:span'); - if (is_string($styleFont)) { - $xmlWriter->writeAttribute('text:style-name', $styleFont); - } - $xmlWriter->writeRaw($text->getText()); - $xmlWriter->endElement(); - } - if (!$withoutP) { - $xmlWriter->endElement(); // text:p - } - } - } - - /** - * Write TextRun section - * - * @param XMLWriter $xmlWriter - * @param TextRun $textrun - * @todo Enable all other section types - */ - protected function writeTextRun(XMLWriter $xmlWriter, TextRun $textrun) - { - $elements = $textrun->getElements(); - $xmlWriter->startElement('text:p'); - if (count($elements) > 0) { - foreach ($elements as $element) { - if ($element instanceof Text) { - $this->writeText($xmlWriter, $element, true); - } - } - } - $xmlWriter->endElement(); - } - - /** - * Write TextBreak - * - * @param XMLWriter $xmlWriter - */ - protected function writeTextBreak(XMLWriter $xmlWriter) - { - $xmlWriter->startElement('text:p'); - $xmlWriter->writeAttribute('text:style-name', 'Standard'); - $xmlWriter->endElement(); - } - - /** - * Write unsupported element - * - * @param XMLWriter $xmlWriter - * @param string $element - */ - private function writeUnsupportedElement($xmlWriter, $element) - { - $xmlWriter->startElement('text:p'); - $xmlWriter->writeRaw($element); - $xmlWriter->endElement(); } } From fb35a5f80cf3394d9774a934b851fc7c249bccf4 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sat, 12 Apr 2014 00:40:22 +0700 Subject: [PATCH 09/29] Change object name --- src/PhpWord/Writer/ODText/Content.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/PhpWord/Writer/ODText/Content.php b/src/PhpWord/Writer/ODText/Content.php index e8f087fe..01af3053 100644 --- a/src/PhpWord/Writer/ODText/Content.php +++ b/src/PhpWord/Writer/ODText/Content.php @@ -108,15 +108,15 @@ class Content extends Base $elements = $section->getElements(); foreach ($elements as $element) { if ($elements instanceof Table) { - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', $element->getElementId()); - $objWriter->writeAttribute('style:family', 'table'); - $objWriter->startElement('style:table-properties'); - //$objWriter->writeAttribute('style:width', 'table'); - $objWriter->writeAttribute('style:rel-width', 100); - $objWriter->writeAttribute('table:align', 'center'); - $objWriter->endElement(); - $objWriter->endElement(); + $xmlWriter->startElement('style:style'); + $xmlWriter->writeAttribute('style:name', $element->getElementId()); + $xmlWriter->writeAttribute('style:family', 'table'); + $xmlWriter->startElement('style:table-properties'); + //$xmlWriter->writeAttribute('style:width', 'table'); + $xmlWriter->writeAttribute('style:rel-width', 100); + $xmlWriter->writeAttribute('table:align', 'center'); + $xmlWriter->endElement(); + $xmlWriter->endElement(); } } } From 59e623bb752b50a1f0399e5474e9bf84eafae399 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Sat, 12 Apr 2014 00:56:24 +0200 Subject: [PATCH 10/29] Fixes #195 : Update general.rst --- docs/general.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/general.rst b/docs/general.rst index 40c8da7e..c7e55d5a 100644 --- a/docs/general.rst +++ b/docs/general.rst @@ -108,7 +108,7 @@ name. Use the following functions: .. code-block:: php - $properties = $phpWord->getProperties(); + $properties = $phpWord->getDocumentProperties(); $properties->setCreator('My name'); $properties->setCompany('My factory'); $properties->setTitle('My title'); From b40218da4571c5c32e42fb22e5df79a7a9764ffa Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Sat, 12 Apr 2014 00:59:29 +0200 Subject: [PATCH 11/29] Add some unit tests for Shared & Element (100%!) - @Progi1984 --- CHANGELOG.md | 2 ++ src/PhpWord/Shared/ZipArchive.php | 3 +- .../Tests/Element/AbstractElementTest.php | 30 ++++++++++++++++++ tests/PhpWord/Tests/Element/ImageTest.php | 15 +++++++++ tests/PhpWord/Tests/Element/TableTest.php | 22 ++++++++++--- tests/PhpWord/Tests/Shared/ZipArchiveTest.php | 31 +++++++++++++++++++ 6 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 tests/PhpWord/Tests/Element/AbstractElementTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 03400d46..6a932eda 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ This release marked heavy refactorings on internal code structure with the creat ### Bugfixes - Footnote: Footnote content doesn't show footnote reference number - @ivanlanin GH-170 +- Documentation : Error in a fonction - @theBeerNut GH-195 ### Deprecated @@ -63,6 +64,7 @@ This release marked heavy refactorings on internal code structure with the creat - Style: New `Style\AbstractStyle` abstract class - @ivanlanin GH-187 - Writer: New 'ODText\Base` class - @ivanlanin GH-187 - General: Rename `Footnote` to `Footnotes` to reflect the nature of collection - @ivanlanin +- General: Add some unit tests for Shared & Element (100%!) - @Progi1984 ## 0.9.1 - 27 Mar 2014 diff --git a/src/PhpWord/Shared/ZipArchive.php b/src/PhpWord/Shared/ZipArchive.php index d8519aca..21d13cfe 100644 --- a/src/PhpWord/Shared/ZipArchive.php +++ b/src/PhpWord/Shared/ZipArchive.php @@ -218,8 +218,7 @@ class ZipArchive public function getNameIndex($index) { $list = $this->zip->listContent(); - $listCount = count($list); - if ($index <= $listCount) { + if (isset($list[$index])) { return $list[$index]['filename']; } else { return false; diff --git a/tests/PhpWord/Tests/Element/AbstractElementTest.php b/tests/PhpWord/Tests/Element/AbstractElementTest.php new file mode 100644 index 00000000..786248d5 --- /dev/null +++ b/tests/PhpWord/Tests/Element/AbstractElementTest.php @@ -0,0 +1,30 @@ +getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); + $ival = rand(0, 100); + $stub->setElementIndex($ival); + $this->assertEquals($stub->getElementIndex(), $ival); + } + public function testElementId(){ + $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); + $stub->setElementId(); + $this->assertEquals(strlen($stub->getElementId()), 6); + } +} diff --git a/tests/PhpWord/Tests/Element/ImageTest.php b/tests/PhpWord/Tests/Element/ImageTest.php index 5b9aaa45..3520c376 100644 --- a/tests/PhpWord/Tests/Element/ImageTest.php +++ b/tests/PhpWord/Tests/Element/ImageTest.php @@ -94,6 +94,11 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Image', $oImage->getStyle()); } + public function testStyleWrappingStyle() + { + + } + /** * Get relation Id */ @@ -202,4 +207,14 @@ class ImageTest extends \PHPUnit_Framework_TestCase { $object = new Image('test.php'); } + + /** + * Test PCX Image and Memory + * + * @expectedException \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException + */ + public function testPcxImage() + { + $object = new Image('http://samples.libav.org/image-samples/RACECAR.BMP'); + } } diff --git a/tests/PhpWord/Tests/Element/TableTest.php b/tests/PhpWord/Tests/Element/TableTest.php index 0d3a74b9..53ec54be 100644 --- a/tests/PhpWord/Tests/Element/TableTest.php +++ b/tests/PhpWord/Tests/Element/TableTest.php @@ -84,9 +84,23 @@ class TableTest extends \PHPUnit_Framework_TestCase */ public function testCell() { - $oTable = new Table('section', 1); - $oTable->addRow(); - $element = $oTable->addCell(); - $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element); + $oTable = new Table('section', 1); + $oTable->addRow(); + $element = $oTable->addCell(); + $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element); + } + + /** + * Add cell + */ + public function testCountColumns() + { + $oTable = new Table('section', 1); + $oTable->addRow(); + $element = $oTable->addCell(); + $this->assertEquals($oTable->countColumns(), 1); + $element = $oTable->addCell(); + $element = $oTable->addCell(); + $this->assertEquals($oTable->countColumns(), 3); } } diff --git a/tests/PhpWord/Tests/Shared/ZipArchiveTest.php b/tests/PhpWord/Tests/Shared/ZipArchiveTest.php index ba47ade1..5094d5a1 100644 --- a/tests/PhpWord/Tests/Shared/ZipArchiveTest.php +++ b/tests/PhpWord/Tests/Shared/ZipArchiveTest.php @@ -32,7 +32,38 @@ class ZipArchiveTest extends \PHPUnit_Framework_TestCase $this->assertTrue($object->locateName('xls/new.xls')); $this->assertEquals('Test', $object->getFromName('content/string.txt')); + $this->assertEquals('Test', $object->getFromName('/content/string.txt')); unlink($zipFile); } + + public function testLocate() + { + $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; + $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; + $object = new ZipArchive(); + $object->open($zipFile); + $object->addFile($existingFile, 'xls/new.xls'); + $object->addFromString('content/string.txt', 'Test'); + + $this->assertEquals(1, $object->locateName('content/string.txt')); + $this->assertFalse($object->locateName('blablabla')); + + unlink($zipFile); + } + + public function testNameIndex() + { + $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; + $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; + $object = new ZipArchive(); + $object->open($zipFile); + $object->addFile($existingFile, 'xls/new.xls'); + $object->addFromString('content/string.txt', 'Test'); + + $this->assertFalse($object->getNameIndex(-1)); + $this->assertEquals('content/string.txt', $object->getNameIndex(1)); + + unlink($zipFile); + } } From 47956b019cb6d13bf9d78d7f1d7c7f0ad414d002 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sat, 12 Apr 2014 10:23:31 +0700 Subject: [PATCH 12/29] Code formatting and some more tests --- src/PhpWord/Reader/Word2007.php | 2 +- src/PhpWord/Style/ListItem.php | 2 + .../Tests/Element/AbstractElementTest.php | 26 ++++++--- tests/PhpWord/Tests/Element/ImageTest.php | 5 +- tests/PhpWord/Tests/Element/TableTest.php | 36 ++++++------ tests/PhpWord/Tests/Shared/XMLReaderTest.php | 54 ++++++++++++++++++ tests/PhpWord/Tests/Shared/ZipArchiveTest.php | 46 ++++++++------- tests/PhpWord/Tests/Style/ImageTest.php | 4 +- .../Tests/_files/documents/reader.docx | Bin 69796 -> 74101 bytes 9 files changed, 124 insertions(+), 51 deletions(-) create mode 100644 tests/PhpWord/Tests/Shared/XMLReaderTest.php diff --git a/src/PhpWord/Reader/Word2007.php b/src/PhpWord/Reader/Word2007.php index 5901046c..9d74e540 100644 --- a/src/PhpWord/Reader/Word2007.php +++ b/src/PhpWord/Reader/Word2007.php @@ -128,7 +128,7 @@ class Word2007 extends AbstractReader implements ReaderInterface if ($zip->open($filename) === true) { for ($i = 0; $i < $zip->numFiles; $i++) { $xmlFile = $zip->getNameIndex($i); - if ((substr($xmlFile, 0, strlen($wordRelsPath))) == $wordRelsPath) { + if ((substr($xmlFile, 0, strlen($wordRelsPath))) == $wordRelsPath && (substr($xmlFile, -1)) != '/') { $docPart = str_replace('.xml.rels', '', str_replace($wordRelsPath, '', $xmlFile)); $this->rels[$docPart] = $this->getRels($filename, $xmlFile, 'word/'); } diff --git a/src/PhpWord/Style/ListItem.php b/src/PhpWord/Style/ListItem.php index 3c762920..a4f4933d 100644 --- a/src/PhpWord/Style/ListItem.php +++ b/src/PhpWord/Style/ListItem.php @@ -100,6 +100,8 @@ class ListItem extends AbstractStyle /** * Set numbering style name + * + * @param string $value */ public function setNumStyle($value) { diff --git a/tests/PhpWord/Tests/Element/AbstractElementTest.php b/tests/PhpWord/Tests/Element/AbstractElementTest.php index 786248d5..81080232 100644 --- a/tests/PhpWord/Tests/Element/AbstractElementTest.php +++ b/tests/PhpWord/Tests/Element/AbstractElementTest.php @@ -16,15 +16,23 @@ namespace PhpOffice\PhpWord\Tests\Element; */ class AbstractElementTest extends \PHPUnit_Framework_TestCase { - public function testElementIndex(){ - $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); - $ival = rand(0, 100); - $stub->setElementIndex($ival); - $this->assertEquals($stub->getElementIndex(), $ival); + /** + * Test set/get element index + */ + public function testElementIndex() + { + $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); + $ival = rand(0, 100); + $stub->setElementIndex($ival); + $this->assertEquals($stub->getElementIndex(), $ival); } - public function testElementId(){ - $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); - $stub->setElementId(); - $this->assertEquals(strlen($stub->getElementId()), 6); + /** + * Test set/get element unique Id + */ + public function testElementId() + { + $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Element\AbstractElement'); + $stub->setElementId(); + $this->assertEquals(strlen($stub->getElementId()), 6); } } diff --git a/tests/PhpWord/Tests/Element/ImageTest.php b/tests/PhpWord/Tests/Element/ImageTest.php index 3520c376..6ec6743a 100644 --- a/tests/PhpWord/Tests/Element/ImageTest.php +++ b/tests/PhpWord/Tests/Element/ImageTest.php @@ -94,6 +94,9 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Image', $oImage->getStyle()); } + /** + * Test set wrapping style + */ public function testStyleWrappingStyle() { @@ -215,6 +218,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase */ public function testPcxImage() { - $object = new Image('http://samples.libav.org/image-samples/RACECAR.BMP'); + $object = new Image('http://samples.libav.org/image-samples/RACECAR.BMP'); } } diff --git a/tests/PhpWord/Tests/Element/TableTest.php b/tests/PhpWord/Tests/Element/TableTest.php index 53ec54be..3fc51f98 100644 --- a/tests/PhpWord/Tests/Element/TableTest.php +++ b/tests/PhpWord/Tests/Element/TableTest.php @@ -48,11 +48,11 @@ class TableTest extends \PHPUnit_Framework_TestCase */ public function testStyleArray() { - $oTable = new Table( - 'section', - 1, - array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80) - ); + $oTable = new Table('section', 1, array( + 'borderSize' => 6, + 'borderColor' => '006699', + 'cellMargin' => 80 + )); $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Table', $oTable->getStyle()); } @@ -63,7 +63,7 @@ class TableTest extends \PHPUnit_Framework_TestCase public function testWidth() { $oTable = new Table('section', 1); - $iVal = rand(1, 1000); + $iVal = rand(1, 1000); $oTable->setWidth($iVal); $this->assertEquals($oTable->getWidth(), $iVal); } @@ -73,7 +73,7 @@ class TableTest extends \PHPUnit_Framework_TestCase */ public function testRow() { - $oTable = new Table('section', 1); + $oTable = new Table('section', 1); $element = $oTable->addRow(); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Row', $element); $this->assertCount(1, $oTable->getRows()); @@ -84,10 +84,10 @@ class TableTest extends \PHPUnit_Framework_TestCase */ public function testCell() { - $oTable = new Table('section', 1); - $oTable->addRow(); - $element = $oTable->addCell(); - $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element); + $oTable = new Table('section', 1); + $oTable->addRow(); + $element = $oTable->addCell(); + $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element); } /** @@ -95,12 +95,12 @@ class TableTest extends \PHPUnit_Framework_TestCase */ public function testCountColumns() { - $oTable = new Table('section', 1); - $oTable->addRow(); - $element = $oTable->addCell(); - $this->assertEquals($oTable->countColumns(), 1); - $element = $oTable->addCell(); - $element = $oTable->addCell(); - $this->assertEquals($oTable->countColumns(), 3); + $oTable = new Table('section', 1); + $oTable->addRow(); + $element = $oTable->addCell(); + $this->assertEquals($oTable->countColumns(), 1); + $element = $oTable->addCell(); + $element = $oTable->addCell(); + $this->assertEquals($oTable->countColumns(), 3); } } diff --git a/tests/PhpWord/Tests/Shared/XMLReaderTest.php b/tests/PhpWord/Tests/Shared/XMLReaderTest.php new file mode 100644 index 00000000..759bf580 --- /dev/null +++ b/tests/PhpWord/Tests/Shared/XMLReaderTest.php @@ -0,0 +1,54 @@ +assertFalse($object->getDomFromZip($filename, 'yadayadaya')); + } + + /** + * Test get elements returns empty + */ + public function testGetElementsReturnsEmpty() + { + $object = new XMLReader(); + $this->assertEquals(array(), $object->getElements('w:document')); + } + + /** + * Test get element returns null + */ + public function testGetElementReturnsNull() + { + $filename = __DIR__ . "/../_files/documents/reader.docx.zip"; + + $object = new XMLReader(); + $object->getDomFromZip($filename, '[Content_Types].xml'); + $element = $object->getElements('*')->item(0); + + $this->assertNull($object->getElement('yadayadaya', $element)); + } +} diff --git a/tests/PhpWord/Tests/Shared/ZipArchiveTest.php b/tests/PhpWord/Tests/Shared/ZipArchiveTest.php index 5094d5a1..40bdde68 100644 --- a/tests/PhpWord/Tests/Shared/ZipArchiveTest.php +++ b/tests/PhpWord/Tests/Shared/ZipArchiveTest.php @@ -24,8 +24,8 @@ class ZipArchiveTest extends \PHPUnit_Framework_TestCase public function testAdd() { $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; - $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; - $object = new ZipArchive(); + $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; + $object = new ZipArchive(); $object->open($zipFile); $object->addFile($existingFile, 'xls/new.xls'); $object->addFromString('content/string.txt', 'Test'); @@ -37,33 +37,39 @@ class ZipArchiveTest extends \PHPUnit_Framework_TestCase unlink($zipFile); } + /** + * Test find if a given name exists in the archive + */ public function testLocate() { - $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; - $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; - $object = new ZipArchive(); - $object->open($zipFile); - $object->addFile($existingFile, 'xls/new.xls'); - $object->addFromString('content/string.txt', 'Test'); + $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; + $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; + $object = new ZipArchive(); + $object->open($zipFile); + $object->addFile($existingFile, 'xls/new.xls'); + $object->addFromString('content/string.txt', 'Test'); - $this->assertEquals(1, $object->locateName('content/string.txt')); - $this->assertFalse($object->locateName('blablabla')); + $this->assertEquals(1, $object->locateName('content/string.txt')); + $this->assertFalse($object->locateName('blablabla')); - unlink($zipFile); + unlink($zipFile); } + /** + * Test returns the name of an entry using its index + */ public function testNameIndex() { - $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; - $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; - $object = new ZipArchive(); - $object->open($zipFile); - $object->addFile($existingFile, 'xls/new.xls'); - $object->addFromString('content/string.txt', 'Test'); + $existingFile = __DIR__ . "/../_files/documents/sheet.xls"; + $zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; + $object = new ZipArchive(); + $object->open($zipFile); + $object->addFile($existingFile, 'xls/new.xls'); + $object->addFromString('content/string.txt', 'Test'); - $this->assertFalse($object->getNameIndex(-1)); - $this->assertEquals('content/string.txt', $object->getNameIndex(1)); + $this->assertFalse($object->getNameIndex(-1)); + $this->assertEquals('content/string.txt', $object->getNameIndex(1)); - unlink($zipFile); + unlink($zipFile); } } diff --git a/tests/PhpWord/Tests/Style/ImageTest.php b/tests/PhpWord/Tests/Style/ImageTest.php index b35c8cb2..fd74d73c 100644 --- a/tests/PhpWord/Tests/Style/ImageTest.php +++ b/tests/PhpWord/Tests/Style/ImageTest.php @@ -32,7 +32,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'align' => 'left', 'marginTop' => 240, 'marginLeft' => 240, - 'wrappingStyle' => 'inline', + 'wrappingStyle' => 'inline' ); foreach ($properties as $key => $value) { $set = "set{$key}"; @@ -54,7 +54,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'height' => 200, 'align' => 'left', 'marginTop' => 240, - 'marginLeft' => 240, + 'marginLeft' => 240 ); foreach ($properties as $key => $value) { $get = "get{$key}"; diff --git a/tests/PhpWord/Tests/_files/documents/reader.docx b/tests/PhpWord/Tests/_files/documents/reader.docx index 2143c628c5132f5948c339538bef2c2fabdab545..5f37ef4b17d05dc992c92922b5591eb978a429a8 100644 GIT binary patch delta 62792 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 eR8Tm&inr4xu3N`bSu9)up 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 From 9bb56552927e30594ee4394cc19c1386fa8f62c8 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sat, 12 Apr 2014 12:57:51 +0700 Subject: [PATCH 13/29] Unit test for AbstractStyle --- src/PhpWord/Style/AbstractStyle.php | 4 +- .../Tests/Element/AbstractElementTest.php | 3 +- .../PhpWord/Tests/Style/AbstractStyleTest.php | 66 +++++++++++++++++++ tests/PhpWord/Tests/Style/ListItemTest.php | 12 ++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/PhpWord/Tests/Style/AbstractStyleTest.php diff --git a/src/PhpWord/Style/AbstractStyle.php b/src/PhpWord/Style/AbstractStyle.php index 45ba17a7..ea77dc70 100644 --- a/src/PhpWord/Style/AbstractStyle.php +++ b/src/PhpWord/Style/AbstractStyle.php @@ -105,13 +105,12 @@ abstract class AbstractStyle /** * Set integer value * - * @param integer|null $value + * @param mixed $value * @param integer|null $default * @return integer|null */ protected function setIntVal($value, $default = null) { - $value = intval($value); if (!is_int($value)) { $value = $default; } @@ -128,7 +127,6 @@ abstract class AbstractStyle */ protected function setFloatVal($value, $default = null) { - $value = floatval($value); if (!is_float($value)) { $value = $default; } diff --git a/tests/PhpWord/Tests/Element/AbstractElementTest.php b/tests/PhpWord/Tests/Element/AbstractElementTest.php index 81080232..8dbfb5b3 100644 --- a/tests/PhpWord/Tests/Element/AbstractElementTest.php +++ b/tests/PhpWord/Tests/Element/AbstractElementTest.php @@ -10,7 +10,7 @@ namespace PhpOffice\PhpWord\Tests\Element; /** - * Test class for PhpOffice\PhpWord\Element\Cell + * Test class for PhpOffice\PhpWord\Element\AbstractElement * * @runTestsInSeparateProcesses */ @@ -26,6 +26,7 @@ class AbstractElementTest extends \PHPUnit_Framework_TestCase $stub->setElementIndex($ival); $this->assertEquals($stub->getElementIndex(), $ival); } + /** * Test set/get element unique Id */ diff --git a/tests/PhpWord/Tests/Style/AbstractStyleTest.php b/tests/PhpWord/Tests/Style/AbstractStyleTest.php new file mode 100644 index 00000000..a9eace9d --- /dev/null +++ b/tests/PhpWord/Tests/Style/AbstractStyleTest.php @@ -0,0 +1,66 @@ +getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle'); + $stub->setStyleByArray(array('index' => 1)); + + $this->assertEquals(1, $stub->getIndex()); + } + + /** + * Test setBoolVal, setIntVal, setFloatVal, setEnumVal with normal value + */ + public function testSetValNormal() + { + $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle'); + + $this->assertEquals(true, self::callProtectedMethod($stub, 'setBoolVal', array(true, false))); + $this->assertEquals(12, self::callProtectedMethod($stub, 'setIntVal', array(12, 200))); + $this->assertEquals(871.1, self::callProtectedMethod($stub, 'setFloatVal', array(871.1, 2.1))); + $this->assertEquals('a', self::callProtectedMethod($stub, 'setEnumVal', array('a', array('a', 'b'), 'b'))); + } + + /** + * Test setBoolVal, setIntVal, setFloatVal, setEnumVal with default value + */ + public function testSetValDefault() + { + $stub = $this->getMockForAbstractClass('\PhpOffice\PhpWord\Style\AbstractStyle'); + + $this->assertEquals(false, self::callProtectedMethod($stub, 'setBoolVal', array('a', false))); + $this->assertEquals(200, self::callProtectedMethod($stub, 'setIntVal', array('foo', 200))); + $this->assertEquals(2.1, self::callProtectedMethod($stub, 'setFloatVal', array('foo', 2.1))); + $this->assertEquals('b', self::callProtectedMethod($stub, 'setEnumVal', array('z', array('a', 'b'), 'b'))); + } + + /** + * Helper function to call protected method + */ + public static function callProtectedMethod($object, $method, array $args = array()) + { + $class = new \ReflectionClass(get_class($object)); + $method = $class->getMethod($method); + $method->setAccessible(true); + return $method->invokeArgs($object, $args); + } +} diff --git a/tests/PhpWord/Tests/Style/ListItemTest.php b/tests/PhpWord/Tests/Style/ListItemTest.php index 0fb67da3..6eef720c 100644 --- a/tests/PhpWord/Tests/Style/ListItemTest.php +++ b/tests/PhpWord/Tests/Style/ListItemTest.php @@ -53,4 +53,16 @@ class ListItemTest extends \PHPUnit_Framework_TestCase $object->setListType($value); $this->assertEquals($value, $object->getListType()); } + + /** + * Test set/get numbering style name + */ + public function testSetGetNumStyle() + { + $expected = 'List Name'; + + $object = new ListItem(); + $object->setNumStyle($expected); + $this->assertEquals($expected, $object->getNumStyle()); + } } From a5b5e0cff015ebcedae807892fd4b7476dc0a4de Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sun, 13 Apr 2014 17:43:03 +0700 Subject: [PATCH 14/29] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a932eda..937930e8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ This release marked heavy refactorings on internal code structure with the creat - Writer: New 'ODText\Base` class - @ivanlanin GH-187 - General: Rename `Footnote` to `Footnotes` to reflect the nature of collection - @ivanlanin - General: Add some unit tests for Shared & Element (100%!) - @Progi1984 +- Test: Add some samples and tests for image wrapping style - @brunocasado GH-59 ## 0.9.1 - 27 Mar 2014 From e78489b36e5d06055c3c18091f362fc7d4a1077f Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sun, 13 Apr 2014 18:03:59 +0700 Subject: [PATCH 15/29] Update unit test and changelog --- CHANGELOG.md | 1 + src/PhpWord/Element/Image.php | 11 ++++++----- tests/PhpWord/Tests/Element/ImageTest.php | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 937930e8..70f53abf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ This release marked heavy refactorings on internal code structure with the creat - Endnote: Ability to add endnotes - @ivanlanin - ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 - ODT Writer: Basic table writing support - @ivanlanin +- Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194 ### Bugfixes diff --git a/src/PhpWord/Element/Image.php b/src/PhpWord/Element/Image.php index 139c578f..ce4b1609 100755 --- a/src/PhpWord/Element/Image.php +++ b/src/PhpWord/Element/Image.php @@ -133,14 +133,15 @@ class Image extends AbstractElement $this->style = $this->setStyle(new ImageStyle(), $style, true); $styleWidth = $this->style->getWidth(); $styleHeight = $this->style->getHeight(); + list($actualWidth, $actualHeight) = $imgData; if (!($styleWidth && $styleHeight)) { if ($styleWidth == null && $styleHeight == null) { - $this->style->setWidth($imgData[0]); - $this->style->setHeight($imgData[1]); - } else if ($styleWidth) { - $this->style->setHeight($imgData[1] * ($styleWidth / $imgData[0])); + $this->style->setWidth($actualWidth); + $this->style->setHeight($actualHeight); + } elseif ($styleWidth) { + $this->style->setHeight($actualHeight * ($styleWidth / $actualWidth)); } else { - $this->style->setWidth($imgData[0] * ($styleHeight / $imgData[1])); + $this->style->setWidth($actualWidth * ($styleHeight / $actualHeight)); } } $this->setImageFunctions(); diff --git a/tests/PhpWord/Tests/Element/ImageTest.php b/tests/PhpWord/Tests/Element/ImageTest.php index 6ec6743a..eae9fc5f 100644 --- a/tests/PhpWord/Tests/Element/ImageTest.php +++ b/tests/PhpWord/Tests/Element/ImageTest.php @@ -129,7 +129,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase public function testPNG() { $src = __DIR__ . "/../_files/images/firefox.png"; - $oImage = new Image($src); + $oImage = new Image($src, array('width' => 100)); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage); $this->assertEquals($oImage->getSource(), $src); @@ -146,7 +146,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase public function testGIF() { $src = __DIR__ . "/../_files/images/mario.gif"; - $oImage = new Image($src); + $oImage = new Image($src, array('height' => 100)); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $oImage); $this->assertEquals($oImage->getSource(), $src); From 19a69e2c39d91f56eefaf2e6cb0ec1888c972b04 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sat, 12 Apr 2014 10:12:24 +0700 Subject: [PATCH 16/29] Basic HTML writer --- CHANGELOG.md | 3 +- samples/Sample_01_SimpleText.php | 12 +- samples/Sample_02_TabStops.php | 12 +- samples/Sample_03_Sections.php | 12 +- samples/Sample_04_Textrun.php | 12 +- samples/Sample_05_Multicolumn.php | 12 +- samples/Sample_06_Footnote.php | 12 +- samples/Sample_08_ParagraphPagination.php | 12 +- samples/Sample_09_Tables.php | 12 +- samples/Sample_10_EastAsianFontStyle.php | 12 +- samples/Sample_11_ReadWord2007.php | 13 +- samples/Sample_12_HeaderFooter.php | 13 +- samples/Sample_13_Images.php | 13 +- samples/Sample_14_ListItem.php | 13 +- samples/Sample_15_Link.php | 14 +- samples/Sample_16_Object.php | 14 +- samples/Sample_17_TitleTOC.php | 13 +- samples/Sample_18_Watermark.php | 14 +- samples/Sample_19_TextBreak.php | 14 +- samples/Sample_20_BGColor.php | 12 +- samples/Sample_21_TableRowRules.php | 12 +- samples/Sample_22_CheckBox.php | 12 +- samples/Sample_Footer.php | 23 - samples/Sample_Header.php | 50 ++ samples/index.php | 6 +- src/PhpWord/Element/Title.php | 10 + src/PhpWord/IOFactory.php | 4 +- src/PhpWord/Writer/HTML.php | 589 ++++++++++++++++++++++ tests/PhpWord/Tests/Writer/HTMLTest.php | 105 ++++ 29 files changed, 826 insertions(+), 229 deletions(-) create mode 100644 src/PhpWord/Writer/HTML.php create mode 100644 tests/PhpWord/Tests/Writer/HTMLTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 03400d46..f9bcdd19 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers ## 0.10.0 - Not yet released -This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. +This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML writer is initiated. ### Features @@ -31,6 +31,7 @@ This release marked heavy refactorings on internal code structure with the creat - Endnote: Ability to add endnotes - @ivanlanin - ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 - ODT Writer: Basic table writing support - @ivanlanin +- HTML Writer: Basic HTML writer initiated - @ivanlanin ### Bugfixes diff --git a/samples/Sample_01_SimpleText.php b/samples/Sample_01_SimpleText.php index 02b78bd7..659686d3 100755 --- a/samples/Sample_01_SimpleText.php +++ b/samples/Sample_01_SimpleText.php @@ -45,13 +45,7 @@ $section->addTextBreak(); $section->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18)); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_02_TabStops.php b/samples/Sample_02_TabStops.php index dbed59a3..d6e4cdbc 100755 --- a/samples/Sample_02_TabStops.php +++ b/samples/Sample_02_TabStops.php @@ -33,13 +33,7 @@ $section->addText("Left Aligned\tRight Aligned", null, 'rightTab'); $section->addText("\tCenter Aligned", null, 'centerTab'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_03_Sections.php b/samples/Sample_03_Sections.php index 4953b6a6..bfbc84af 100755 --- a/samples/Sample_03_Sections.php +++ b/samples/Sample_03_Sections.php @@ -26,13 +26,7 @@ $section->addHeader()->addText('Header'); $section->addFooter()->addText('Footer'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_04_Textrun.php b/samples/Sample_04_Textrun.php index 354eadfd..f415ca17 100644 --- a/samples/Sample_04_Textrun.php +++ b/samples/Sample_04_Textrun.php @@ -34,13 +34,7 @@ $textrun->addObject('resources/_sheet.xls'); $textrun->addText(' Here is some more text. '); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_05_Multicolumn.php b/samples/Sample_05_Multicolumn.php index 478a8dd0..a3083824 100644 --- a/samples/Sample_05_Multicolumn.php +++ b/samples/Sample_05_Multicolumn.php @@ -36,13 +36,7 @@ $section = $phpWord->addSection(array('breakType' => 'continuous')); $section->addText('Normal paragraph again.'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_06_Footnote.php b/samples/Sample_06_Footnote.php index 75120088..1bec44e4 100755 --- a/samples/Sample_06_Footnote.php +++ b/samples/Sample_06_Footnote.php @@ -38,13 +38,7 @@ $footnote = $section->addFootnote(); $footnote->addText('The reference for this is wrapped in its own line'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_08_ParagraphPagination.php b/samples/Sample_08_ParagraphPagination.php index bf1400a0..57fbab09 100644 --- a/samples/Sample_08_ParagraphPagination.php +++ b/samples/Sample_08_ParagraphPagination.php @@ -46,13 +46,7 @@ $section->addText('Paragraph with pageBreakBefore = true (default: false). ' . null, array('pageBreakBefore' => true)); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_09_Tables.php b/samples/Sample_09_Tables.php index 5af73fb6..fd930b2b 100644 --- a/samples/Sample_09_Tables.php +++ b/samples/Sample_09_Tables.php @@ -85,13 +85,7 @@ $table->addCell(2000, $cellVCentered)->addText('D', null, $cellHCentered); $table->addCell(null, $cellRowContinue); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_10_EastAsianFontStyle.php b/samples/Sample_10_EastAsianFontStyle.php index 39f449c3..44bca8a6 100644 --- a/samples/Sample_10_EastAsianFontStyle.php +++ b/samples/Sample_10_EastAsianFontStyle.php @@ -10,13 +10,7 @@ $header = array('size' => 16, 'bold' => true); $section->addText('中文楷体样式测试',array('name' => '楷体', 'size' => 16, 'color' => '1B2232')); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_11_ReadWord2007.php b/samples/Sample_11_ReadWord2007.php index e5112e2e..09d9cab0 100644 --- a/samples/Sample_11_ReadWord2007.php +++ b/samples/Sample_11_ReadWord2007.php @@ -7,13 +7,8 @@ $source = "resources/{$name}.docx"; echo date('H:i:s'), " Reading contents from `{$source}`", EOL; $phpWord = \PhpOffice\PhpWord\IOFactory::load($source); -// (Re)write contents -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +// Save file +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_12_HeaderFooter.php b/samples/Sample_12_HeaderFooter.php index 15309041..8e053286 100644 --- a/samples/Sample_12_HeaderFooter.php +++ b/samples/Sample_12_HeaderFooter.php @@ -59,15 +59,8 @@ $sec2Header->addText("All pages in Section 2 will Have this!"); $section2->addTextBreak(); $section2->addText('Some text...'); - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_13_Images.php b/samples/Sample_13_Images.php index 4ef325b8..c8199cce 100644 --- a/samples/Sample_13_Images.php +++ b/samples/Sample_13_Images.php @@ -18,16 +18,9 @@ $section->addTextBreak(2); $source = 'http://php.net/images/logos/php-med-trans-light.gif'; $section->addText("Remote image from: {$source}"); $section->addImage($source); -// End code // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_14_ListItem.php b/samples/Sample_14_ListItem.php index 45d9c1a7..cd22df8e 100644 --- a/samples/Sample_14_ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -54,15 +54,8 @@ $section->addListItem('List Item 6', 1, 'myOwnStyle', $predefinedMultilevel, 'P- $section->addListItem('List Item 7', 0, 'myOwnStyle', $predefinedMultilevel, 'P-Style'); $section->addTextBreak(2); - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_15_Link.php b/samples/Sample_15_Link.php index c4435ac0..1bd61e79 100644 --- a/samples/Sample_15_Link.php +++ b/samples/Sample_15_Link.php @@ -16,16 +16,8 @@ $phpWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000')) $section->addLink('http://www.bing.com', null, 'myOwnLinkStyle'); $section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_16_Object.php b/samples/Sample_16_Object.php index cb8de6db..af23a00f 100644 --- a/samples/Sample_16_Object.php +++ b/samples/Sample_16_Object.php @@ -11,16 +11,8 @@ $section->addText('You can open this OLE object by double clicking on the icon:' $section->addTextBreak(2); $section->addObject('resources/_sheet.xls'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_17_TitleTOC.php b/samples/Sample_17_TitleTOC.php index 15de531b..b18b1bc9 100644 --- a/samples/Sample_17_TitleTOC.php +++ b/samples/Sample_17_TitleTOC.php @@ -67,16 +67,9 @@ $section->addTitle('Subtitle 3.1.2', 3); $section->addText('Text'); echo date('H:i:s'), " Note: Please refresh TOC manually.", EOL; -// End code // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_18_Watermark.php b/samples/Sample_18_Watermark.php index d0ea786a..313cfbed 100644 --- a/samples/Sample_18_Watermark.php +++ b/samples/Sample_18_Watermark.php @@ -12,16 +12,8 @@ $header = $section->addHeader(); $header->addWatermark('resources/_earth.jpg', array('marginTop' => 200, 'marginLeft' => 55)); $section->addText('The header reference to the current section includes a watermark image.'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_19_TextBreak.php b/samples/Sample_19_TextBreak.php index d7e11ea4..a209ce39 100644 --- a/samples/Sample_19_TextBreak.php +++ b/samples/Sample_19_TextBreak.php @@ -25,16 +25,8 @@ $section->addText('Text break with inline paragraph style:'); $section->addTextBreak(1, null, $paragraphStyle); $section->addText('Done.'); -// End code - // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_20_BGColor.php b/samples/Sample_20_BGColor.php index fec40859..892cd8b2 100644 --- a/samples/Sample_20_BGColor.php +++ b/samples/Sample_20_BGColor.php @@ -11,13 +11,7 @@ $section->addText("This one uses bgColor and is using hex value (0xfbbb10)", arr $section->addText("Compatible with font colors", array("color"=>"0000ff", "bgColor" => "fbbb10")); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_21_TableRowRules.php b/samples/Sample_21_TableRowRules.php index 10ad156d..b600ec00 100644 --- a/samples/Sample_21_TableRowRules.php +++ b/samples/Sample_21_TableRowRules.php @@ -28,13 +28,7 @@ $section->addText("In this example, image is 250px height. Rows are calculated i $section->addText("So: $"."table2->addRow(3750, array('exactHeight'=>true));"); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_22_CheckBox.php b/samples/Sample_22_CheckBox.php index 89827388..e7aae5ba 100644 --- a/samples/Sample_22_CheckBox.php +++ b/samples/Sample_22_CheckBox.php @@ -15,13 +15,7 @@ $cell = $table->addCell(); $cell->addCheckBox('chkBox2', 'Checkbox 2'); // Save file -$name = basename(__FILE__, '.php'); -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); -foreach ($writers as $writer => $extension) { - echo date('H:i:s'), " Write to {$writer} format", EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$name}.{$extension}"); - rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; } - -include_once 'Sample_Footer.php'; diff --git a/samples/Sample_Footer.php b/samples/Sample_Footer.php index 4d5777c2..f7e2305f 100644 --- a/samples/Sample_Footer.php +++ b/samples/Sample_Footer.php @@ -2,33 +2,10 @@ /** * Footer file */ -// Do not show execution time for index -if (!IS_INDEX) { - echo date('H:i:s'), " Done writing file(s)", EOL; - echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; -} -// Show message when executed with CLI, show links when using browsers -if (CLI) { - echo 'The results are stored in the "results" subdirectory.', EOL; -} else { - if (!IS_INDEX) { - $types = array('docx', 'odt', 'rtf'); - echo '

 

'; - echo '
'; - } ?> -{$pageHeading}"; + +// Set writers +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html'); + // Populate samples $files = ''; if ($handle = opendir('.')) { @@ -32,6 +36,52 @@ if ($handle = opendir('.')) { } closedir($handle); } + +/** + * Get results + * + * @param array $writers + * @param string $filename + * @return string + */ +function write($phpWord, $filename, $writers) +{ + $result = ''; + + // Write + foreach ($writers as $writer => $extension) { + $result .= date('H:i:s') . " Write to {$writer} format" . EOL; + $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); + $xmlWriter->save("{$filename}.{$extension}"); + rename("{$filename}.{$extension}", "results/{$filename}.{$extension}"); + } + + // Do not show execution time for index + if (!IS_INDEX) { + $result .= date('H:i:s') . " Done writing file(s)" . EOL; + $result .= date('H:i:s') . " Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB" . EOL; + } + + // Return + if (CLI) { + $result .= 'The results are stored in the "results" subdirectory.' . EOL; + } else { + if (!IS_INDEX) { + $types = array_values($writers); + $result .= '

 

'; + $result .= '

Results: '; + foreach ($types as $type) { + $resultFile = 'results/' . SCRIPT_FILENAME . '.' . $type; + if (file_exists($resultFile)) { + $result .= "{$type} "; + } + } + $result .= '

'; + } + } + + return $result; +} ?> <?php echo $pageTitle; ?> diff --git a/samples/index.php b/samples/index.php index 451cf381..8c742729 100644 --- a/samples/index.php +++ b/samples/index.php @@ -24,5 +24,7 @@ foreach ($requirements as $key => $value) { echo "
  • {$value[0]} ... {$status}
  • "; } echo ""; -} // if (!CLI) -include_once 'Sample_Footer.php'; +} +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/src/PhpWord/Element/Title.php b/src/PhpWord/Element/Title.php index 5ed1bfbc..93b48d62 100644 --- a/src/PhpWord/Element/Title.php +++ b/src/PhpWord/Element/Title.php @@ -119,6 +119,16 @@ class Title extends AbstractElement return $this->text; } + /** + * Get depth + * + * @return integer + */ + public function getDepth() + { + return $this->depth; + } + /** * Get Title style * diff --git a/src/PhpWord/IOFactory.php b/src/PhpWord/IOFactory.php index ade4398e..c15ec821 100644 --- a/src/PhpWord/IOFactory.php +++ b/src/PhpWord/IOFactory.php @@ -28,7 +28,7 @@ abstract class IOFactory */ public static function createWriter(PhpWord $phpWord, $name = 'Word2007') { - if ($name !== 'WriterInterface' && $name !== 'ODText' && $name !== 'RTF' && $name !== 'Word2007') { + if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) { throw new Exception("\"{$name}\" is not a valid writer."); } @@ -45,7 +45,7 @@ abstract class IOFactory */ public static function createReader($name = 'Word2007') { - if ($name !== 'ReaderInterface' && $name !== 'Word2007') { + if (!in_array($name, array('ReaderInterface', 'Word2007'))) { throw new Exception("\"{$name}\" is not a valid reader."); } diff --git a/src/PhpWord/Writer/HTML.php b/src/PhpWord/Writer/HTML.php new file mode 100644 index 00000000..797dd9dc --- /dev/null +++ b/src/PhpWord/Writer/HTML.php @@ -0,0 +1,589 @@ +setPhpWord($phpWord); + } + + /** + * Save PhpWord to file + * + * @param string $filename + * @throws Exception + */ + public function save($filename = null) + { + if (!is_null($this->getPhpWord())) { + $hFile = fopen($filename, 'w') or die("can't open file"); + fwrite($hFile, $this->writeDocument()); + fclose($hFile); + } else { + throw new Exception("No PHPWord assigned."); + } + } + + /** + * Get phpWord data + * + * @return string + */ + private function writeDocument() + { + $html = ''; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= $this->writeHTMLHead(); + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= $this->writeHTMLBody(); + $html .= '' . PHP_EOL; + $html .= '' . PHP_EOL; + + return $html; + } + + /** + * Generate HTML header + * + * @return string + */ + public function writeHTMLHead() + { + $properties = $this->getPhpWord()->getDocumentProperties(); + $propertiesMapping = array( + 'creator' => 'author', + 'title' => '', + 'description' => '', + 'subject' => '', + 'keywords' => '', + 'category' => '', + 'company' => '', + 'manager' => '' + ); + $title = $properties->getTitle(); + $title = ($title != '') ? $title : 'PHPWord'; + + $html = ''; + $html .= '' . PHP_EOL; + $html .= '' . htmlspecialchars($title) . '' . PHP_EOL; + foreach ($propertiesMapping as $key => $value) { + $value = ($value == '') ? $key : $value; + $method = "get" . $key; + if ($properties->$method() != '') { + $html .= '' . PHP_EOL; + } + } + $html .= $this->writeStyles(); + + return $html; + } + + /** + * Get content + * + * @return string + */ + public function writeHTMLBody() + { + $phpWord = $this->getPhpWord(); + $html = ''; + + $sections = $phpWord->getSections(); + $countSections = count($sections); + $pSection = 0; + + if ($countSections > 0) { + foreach ($sections as $section) { + $pSection++; + $cellContents = $section->getElements(); + foreach ($cellContents as $element) { + if ($element instanceof Text) { + $html .= $this->writeText($element); + } elseif ($element instanceof TextRun) { + $html .= $this->writeTextRun($element); + } elseif ($element instanceof Link) { + $html .= $this->writeLink($element); + } elseif ($element instanceof Title) { + $html .= $this->writeTitle($element); + } elseif ($element instanceof PreserveText) { + $html .= $this->writePreserveText($element); + } elseif ($element instanceof TextBreak) { + $html .= $this->writeTextBreak($element); + } elseif ($element instanceof PageBreak) { + $html .= $this->writePageBreak($element); + } elseif ($element instanceof Table) { + $html .= $this->writeTable($element); + } elseif ($element instanceof ListItem) { + $html .= $this->writeListItem($element); + } elseif ($element instanceof Image) { + $html .= $this->writeImage($element); + } elseif ($element instanceof Object) { + $html .= $this->writeObject($element); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + } + } + + return $html; + } + + /** + * Get text + * + * @param Text $text + * @param boolean $withoutP + * @return string + */ + private function writeText($text, $withoutP = false) + { + $html = ''; + $paragraphStyle = $text->getParagraphStyle(); + $spIsObject = ($paragraphStyle instanceof Paragraph); + $fontStyle = $text->getFontStyle(); + $sfIsObject = ($fontStyle instanceof Font); + + if ($paragraphStyle && !$withoutP) { + $html .= 'writeParagraphStyle($paragraphStyle) . '"'; + } + $html .= '>'; + } + if ($fontStyle) { + $html .= 'writeFontStyle($fontStyle) . '"'; + } + $html .= '>'; + } + $html .= htmlspecialchars($text->getText()); + if ($fontStyle) { + $html .= ''; + } + if ($paragraphStyle && !$withoutP) { + $html .= '

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Get text run content + * + * @param TextRun $textrun + * @return string + */ + private function writeTextRun($textrun) + { + $html = ''; + $elements = $textrun->getElements(); + if (count($elements) > 0) { + $paragraphStyle = $textrun->getParagraphStyle(); + $spIsObject = ($paragraphStyle instanceof Paragraph); + $html .= 'writeParagraphStyle($paragraphStyle) . '"'; + } + } + $html .= '>'; + foreach ($elements as $element) { + if ($element instanceof Text) { + $html .= $this->writeText($element, true); + } elseif ($element instanceof Link) { + $html .= $this->writeLink($element, true); + } elseif ($element instanceof TextBreak) { + $html .= $this->writeTextBreak($element, true); + } elseif ($element instanceof Image) { + $html .= $this->writeImage($element, true); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + $html .= '

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Write link + * + * @param Link $element + * @return string + */ + private function writeLink($element, $withoutP = false) + { + $url = $element->getLinkSrc(); + $text = $element->getLinkName(); + $html = ''; + if (!$withoutP) { + $html .= "

    " . PHP_EOL; + } + $html .= "{$text}" . PHP_EOL; + if (!$withoutP) { + $html .= "

    " . PHP_EOL; + } + + return $html; + } + + /** + * Write heading + * + * @param Title $element + * @return string + */ + private function writeTitle($element) + { + $tag = 'h' . $element->getDepth(); + $text = htmlspecialchars($element->getText()); + $html = "<{$tag}>{$text}" . PHP_EOL; + + return $html; + } + + /** + * Write preserve text + * + * @param PreserveText $element + * @return string + */ + private function writePreserveText($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Get text break + * + * @param TextBreak $element + * @param boolean $withoutP + * @return string + */ + private function writeTextBreak($element, $withoutP = false) + { + if ($withoutP) { + $html = '
    ' . PHP_EOL; + } else { + $html = '

     

    ' . PHP_EOL; + } + + return $html; + } + + /** + * Write page break + * + * @param PageBreak $element + * @return string + */ + private function writePageBreak($element) + { + return $this->writeUnsupportedElement($element, false); + } + + /** + * Write list item + * + * @param ListItem $element + * @return string + */ + private function writeListItem($element) + { + return $this->writeUnsupportedElement($element, false); + } + + /** + * Write table + * + * @param Title $element + * @return string + */ + private function writeTable($element) + { + $html = ''; + $rows = $element->getRows(); + $cRows = count($rows); + if ($cRows > 0) { + $html .= "" . PHP_EOL; + foreach ($rows as $row) { + $height = $row->getHeight(); + $rowStyle = $row->getStyle(); + $tblHeader = $rowStyle->getTblHeader(); + $html .= "" . PHP_EOL; + foreach ($row->getCells() as $cell) { + $cellTag = $tblHeader ? 'th' : 'td'; + $cellContents = $cell->getElements(); + $html .= "<{$cellTag}>" . PHP_EOL; + if (count($cellContents) > 0) { + foreach ($cellContents as $content) { + if ($content instanceof Text) { + $html .= $this->writeText($content); + } elseif ($content instanceof TextRun) { + $html .= $this->writeTextRun($content); + } elseif ($content instanceof Link) { + $html .= $this->writeLink($content); + } elseif ($content instanceof PreserveText) { + $html .= $this->writePreserveText($content); + } elseif ($content instanceof TextBreak) { + $html .= $this->writeTextBreak($content); + } elseif ($content instanceof ListItem) { + $html .= $this->writeListItem($content); + } elseif ($content instanceof Image) { + $html .= $this->writeImage($content); + } elseif ($content instanceof Object) { + $html .= $this->writeObject($content); + } elseif ($element instanceof Footnote) { + $html .= $this->writeFootnote($element, true); + } elseif ($element instanceof Endnote) { + $html .= $this->writeEndnote($element, true); + } + } + } else { + $this->writeTextBreak($content); + } + $html .= "" . PHP_EOL; + } + $html .= "" . PHP_EOL; + } + $html .= "
    " . PHP_EOL; + } + + return $html; + } + + /** + * Write image + * + * @param Image $element + * @return string + */ + private function writeImage($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Write object + * + * @param Object $element + * @return string + */ + private function writeObject($element, $withoutP = false) + { + return $this->writeUnsupportedElement($element, $withoutP); + } + + /** + * Write footnote + * + * @param Footnote $element + * @return string + */ + private function writeFootnote($element) + { + return $this->writeUnsupportedElement($element, true); + } + + /** + * Write endnote + * + * @param Endnote $element + * @return string + */ + private function writeEndnote($element) + { + return $this->writeUnsupportedElement($element, true); + } + + /** + * Write unsupported element + * + * @param mixed $element + * @param boolean $withoutP + * @return string + */ + private function writeUnsupportedElement($element, $withoutP = false) + { + $elementClass = get_class($element); + $elementMark = str_replace('PhpOffice\\PhpWord\\Element\\', '', $elementClass); + $elementMark = htmlentities("<{$elementMark}>"); + if ($withoutP) { + $html = "{$elementMark}" . PHP_EOL; + } else { + $html = "

    {$elementMark}

    " . PHP_EOL; + } + + return $html; + } + + /** + * Get styles + * + * @return string + */ + private function writeStyles() + { + $css = '' . PHP_EOL; + + return $css; + } + + /** + * Get font style + * + * @param Font $style + * @param boolean $curlyBracket + * @return string + */ + private function writeFontStyle($style, $curlyBracket = false) + { + $css = array(); + if (PHPWord::DEFAULT_FONT_NAME != $style->getName()) { + $css['font-family'] = "'" . $style->getName() . "'"; + } + if (PHPWord::DEFAULT_FONT_SIZE != $style->getSize()) { + $css['font-size'] = $style->getSize() . 'pt'; + } + if (PHPWord::DEFAULT_FONT_COLOR != $style->getColor()) { + $css['color'] = '#' . $style->getColor(); + } + $css['background'] = $style->getFgColor(); + if ($style->getBold()) { + $css['font-weight'] = 'bold'; + } + if ($style->getItalic()) { + $css['font-style'] = 'italic'; + } + if ($style->getSuperScript()) { + $css['vertical-align'] = 'super'; + } elseif ($style->getSubScript()) { + $css['vertical-align'] = 'sub'; + } + $css['text-decoration'] = ''; + if ($style->getUnderline() != Font::UNDERLINE_NONE) { + $css['text-decoration'] .= 'underline '; + } + if ($style->getStrikethrough()) { + $css['text-decoration'] .= 'line-through '; + } + + return $this->assembleCss($css, $curlyBracket); + } + + /** + * Get paragraph style + * + * @param Paragraph $style + * @param boolean $curlyBracket + * @return string + */ + private function writeParagraphStyle($style, $curlyBracket = false) + { + $css = array(); + if ($style->getAlign()) { + $css['text-align'] = $style->getAlign(); + } + + return $this->assembleCss($css, $curlyBracket); + } + + /** + * Takes array where of CSS properties / values and converts to CSS string + * + * @param array $css + * @param boolean $curlyBracket + * @return string + */ + private function assembleCss($css, $curlyBracket = false) + { + $pairs = array(); + foreach ($css as $key => $value) { + if ($value != '') { + $pairs[] = $key . ': ' . $value; + } + } + $string = implode('; ', $pairs); + if ($curlyBracket) { + $string = '{ ' . $string . ' }'; + } + + return $string; + } +} diff --git a/tests/PhpWord/Tests/Writer/HTMLTest.php b/tests/PhpWord/Tests/Writer/HTMLTest.php new file mode 100644 index 00000000..40ea88b0 --- /dev/null +++ b/tests/PhpWord/Tests/Writer/HTMLTest.php @@ -0,0 +1,105 @@ +assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object->getPhpWord()); + } + + /** + * Construct with null + * + * @expectedException \PhpOffice\PhpWord\Exception\Exception + * @expectedExceptionMessage No PhpWord assigned. + */ + public function testConstructWithNull() + { + $object = new HTML(); + $object->getPhpWord(); + } + + /** + * Save + */ + public function testSave() + { + $imageSrc = __DIR__ . "/../_files/images/PhpWord.png"; + $objectSrc = __DIR__ . "/../_files/documents/sheet.xls"; + $file = __DIR__ . "/../_files/temp.html"; + + $phpWord = new PhpWord(); + + $docProps = $phpWord->getDocumentProperties(); + $docProps->setTitle('HTML Test'); + + $phpWord->addFontStyle('Font', array('name' => 'Verdana', 'size' => 11, 'color' => 'FF0000', 'fgColor' => 'FF0000')); + $phpWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $phpWord->addSection(); + $section->addText('Test 1', 'Font', 'Paragraph'); + $section->addTextBreak(); + $section->addText('Test 2', array('name' => 'Tahoma', 'bold' => true, 'italic' => true)); + $section->addLink('http://test.com'); + $section->addTitle('Test', 1); + $section->addPageBreak(); + $section->addListItem('Test'); + $section->addImage($imageSrc); + $section->addObject($objectSrc); + $section->addFootnote(); + $section->addEndnote(); + + $section = $phpWord->addSection(); + + $textrun = $section->addTextRun(array('align' => 'center')); + $textrun->addText('Test 3'); + $textrun->addTextBreak(); + + $textrun = $section->addTextRun('Paragraph'); + $textrun->addLink('http://test.com'); + $textrun->addImage($imageSrc); + $textrun->addFootnote(); + $textrun->addEndnote(); + + $section = $phpWord->addSection(); + + $table = $section->addTable(); + $cell = $table->addRow()->addCell(); + $cell->addText('Test 1', array('superscript' => true, 'underline' => 'dash', 'strikethrough' => true)); + $cell->addTextRun(); + $cell->addLink('http://test.com'); + $cell->addTextBreak(); + $cell->addListItem('Test'); + $cell->addImage($imageSrc); + $cell->addObject($objectSrc); + $cell->addFootnote(); + $cell->addEndnote(); + + $writer = new HTML($phpWord); + $writer->save($file); + + $this->assertTrue(file_exists($file)); + + unlink($file); + } +} From 5a01927b1622b3e3a1cb34cb76fb77dc04a9dd38 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sun, 13 Apr 2014 22:25:42 +0700 Subject: [PATCH 17/29] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 806c9c1c..d6b7bfb5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,7 @@ This release marked heavy refactorings on internal code structure with the creat - ListItem: Ability to create custom list and reset list number - @ivanlanin GH-10 GH-198 - ODT Writer: Basic table writing support - @ivanlanin - Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194 -- HTML Writer: Basic HTML writer initiated - @ivanlanin +- HTML Writer: Basic HTML writer initiated - @ivanlanin GH-203 GH-67 GH-147 ### Bugfixes From 580a61a832929312cb7bc7fe6aba72fd00ab147f Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sun, 13 Apr 2014 23:17:39 +0700 Subject: [PATCH 18/29] Basic PDF Writer #68 --- CHANGELOG.md | 3 +- samples/Sample_Header.php | 26 ++- src/PhpWord/IOFactory.php | 2 +- src/PhpWord/Settings.php | 98 ++++++++- src/PhpWord/Writer/HTML.php | 36 ++-- src/PhpWord/Writer/PDF.php | 66 ++++++ src/PhpWord/Writer/PDF/Core.php | 194 ++++++++++++++++++ src/PhpWord/Writer/PDF/DomPDF.php | 72 +++++++ .../PhpWord/Tests/Style/AbstractStyleTest.php | 4 + 9 files changed, 473 insertions(+), 28 deletions(-) create mode 100644 src/PhpWord/Writer/PDF.php create mode 100644 src/PhpWord/Writer/PDF/Core.php create mode 100644 src/PhpWord/Writer/PDF/DomPDF.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d6b7bfb5..d8268a73 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers ## 0.10.0 - Not yet released -This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML support is enabled. +This release marked heavy refactorings on internal code structure with the creation of some abstract classes to reduce code duplication. `Element` subnamespace is introduced in this release to replace `Section`. Word2007 reader capability is greatly enhanced. Endnote is introduced. List numbering is now customizable. Basic HTML and PDF writing support is enabled. ### Features @@ -33,6 +33,7 @@ This release marked heavy refactorings on internal code structure with the creat - ODT Writer: Basic table writing support - @ivanlanin - Image: Keep image aspect ratio if only 1 dimension styled - @japonicus GH-194 - HTML Writer: Basic HTML writer initiated - @ivanlanin GH-203 GH-67 GH-147 +- PDF Writer: Basic PDF writer initiated using DomPDF - @ivanlanin GH-68 ### Bugfixes diff --git a/samples/Sample_Header.php b/samples/Sample_Header.php index e3057db7..04fd8a40 100644 --- a/samples/Sample_Header.php +++ b/samples/Sample_Header.php @@ -11,6 +11,16 @@ define('IS_INDEX', SCRIPT_FILENAME == 'index'); require_once '../src/PhpWord/Autoloader.php'; \PhpOffice\PhpWord\Autoloader::register(); +// Set writers +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html', 'PDF' => 'pdf'); + +// Set PDF renderer +$rendererName = \PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF; +$rendererLibraryPath = ""; // Put dompdf library path +if (!\PhpOffice\PhpWord\Settings::setPdfRenderer($rendererName, $rendererLibraryPath)) { + $writers['PDF'] = null; +} + // Return to the caller script when runs by CLI if (CLI) { return; @@ -22,9 +32,6 @@ $pageTitle = IS_INDEX ? 'Welcome to ' : "{$pageHeading} - "; $pageTitle .= 'PHPWord'; $pageHeading = IS_INDEX ? '' : "

    {$pageHeading}

    "; -// Set writers -$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf', 'HTML' => 'html'); - // Populate samples $files = ''; if ($handle = opendir('.')) { @@ -51,10 +58,15 @@ function write($phpWord, $filename, $writers) // Write foreach ($writers as $writer => $extension) { - $result .= date('H:i:s') . " Write to {$writer} format" . EOL; - $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$filename}.{$extension}"); - rename("{$filename}.{$extension}", "results/{$filename}.{$extension}"); + $result .= date('H:i:s') . " Write to {$writer} format"; + if (!is_null($extension)) { + $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $writer); + $xmlWriter->save("{$filename}.{$extension}"); + rename("{$filename}.{$extension}", "results/{$filename}.{$extension}"); + } else { + $result .= ' ... NOT DONE!'; + } + $result .= EOL; } // Do not show execution time for index diff --git a/src/PhpWord/IOFactory.php b/src/PhpWord/IOFactory.php index c15ec821..9f7c8162 100644 --- a/src/PhpWord/IOFactory.php +++ b/src/PhpWord/IOFactory.php @@ -28,7 +28,7 @@ abstract class IOFactory */ public static function createWriter(PhpWord $phpWord, $name = 'Word2007') { - if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML'))) { + if (!in_array($name, array('WriterInterface', 'Word2007', 'ODText', 'RTF', 'HTML', 'PDF'))) { throw new Exception("\"{$name}\" is not a valid writer."); } diff --git a/src/PhpWord/Settings.php b/src/PhpWord/Settings.php index 0af6cf72..4558736b 100644 --- a/src/PhpWord/Settings.php +++ b/src/PhpWord/Settings.php @@ -14,10 +14,13 @@ namespace PhpOffice\PhpWord; */ class Settings { - /** Available Zip library classes */ + /** Available Zip library classes */ const PCLZIP = 'PhpOffice\\PhpWord\\Shared\\ZipArchive'; const ZIPARCHIVE = 'ZipArchive'; + /** Optional PDF Rendering libraries */ + const PDF_RENDERER_DOMPDF = 'DomPDF'; + /** * Compatibility option for XMLWriter * @@ -27,13 +30,32 @@ class Settings /** * Name of the class used for Zip file management - * e.g. - * ZipArchive * * @var string */ private static $zipClass = self::ZIPARCHIVE; + /** + * Name of the classes used for PDF renderer + * + * @var array + */ + private static $pdfRenderers = array(self::PDF_RENDERER_DOMPDF); + + /** + * Name of the external Library used for rendering PDF files + * + * @var string + */ + private static $pdfRendererName = null; + + /** + * Directory Path to the external Library used for rendering PDF files + * + * @var string + */ + private static $pdfRendererPath = null; + /** * Set the compatibility option used by the XMLWriter * @@ -74,7 +96,7 @@ class Settings return true; } return false; - } // function setZipClass() + } /** * Return the name of the Zip handler Class that PHPWord is configured to use (PCLZip or ZipArchive) @@ -87,5 +109,71 @@ class Settings public static function getZipClass() { return self::$zipClass; - } // function getZipClass() + } + + /** + * Set details of the external library for rendering PDF files + * + * @param string $libraryName + * @param string $libraryBaseDir + * @return boolean Success or failure + */ + public static function setPdfRenderer($libraryName, $libraryBaseDir) + { + if (!self::setPdfRendererName($libraryName)) { + return false; + } + + return self::setPdfRendererPath($libraryBaseDir); + } + + /** + * Return the PDF Rendering Library + */ + public static function getPdfRendererName() + { + return self::$pdfRendererName; + } + + /** + * Identify the external library to use for rendering PDF files + * + * @param string $libraryName + * @return boolean Success or failure + */ + public static function setPdfRendererName($libraryName) + { + if (!in_array($libraryName, self::$pdfRenderers)) { + return false; + } + + self::$pdfRendererName = $libraryName; + + return true; + } + + + /** + * Return the directory path to the PDF Rendering Library + */ + public static function getPdfRendererPath() + { + return self::$pdfRendererPath; + } + + /** + * Location of external library to use for rendering PDF files + * + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure + */ + public static function setPdfRendererPath($libraryBaseDir) + { + if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { + return false; + } + self::$pdfRendererPath = $libraryBaseDir; + + return true; + } } diff --git a/src/PhpWord/Writer/HTML.php b/src/PhpWord/Writer/HTML.php index 797dd9dc..f0879332 100644 --- a/src/PhpWord/Writer/HTML.php +++ b/src/PhpWord/Writer/HTML.php @@ -16,6 +16,7 @@ use PhpOffice\PhpWord\Element\Link; use PhpOffice\PhpWord\Element\ListItem; use PhpOffice\PhpWord\Element\Object; use PhpOffice\PhpWord\Element\PageBreak; +use PhpOffice\PhpWord\Element\PreserveText; use PhpOffice\PhpWord\Element\Table; use PhpOffice\PhpWord\Element\Text; use PhpOffice\PhpWord\Element\TextBreak; @@ -65,7 +66,7 @@ class HTML extends AbstractWriter implements WriterInterface * * @return string */ - private function writeDocument() + public function writeDocument() { $html = ''; $html .= '' . PHP_EOL; @@ -87,7 +88,7 @@ class HTML extends AbstractWriter implements WriterInterface * * @return string */ - public function writeHTMLHead() + private function writeHTMLHead() { $properties = $this->getPhpWord()->getDocumentProperties(); $propertiesMapping = array( @@ -124,7 +125,7 @@ class HTML extends AbstractWriter implements WriterInterface * * @return string */ - public function writeHTMLBody() + private function writeHTMLBody() { $phpWord = $this->getPhpWord(); $html = ''; @@ -136,8 +137,8 @@ class HTML extends AbstractWriter implements WriterInterface if ($countSections > 0) { foreach ($sections as $section) { $pSection++; - $cellContents = $section->getElements(); - foreach ($cellContents as $element) { + $contents = $section->getElements(); + foreach ($contents as $element) { if ($element instanceof Text) { $html .= $this->writeText($element); } elseif ($element instanceof TextRun) { @@ -161,9 +162,9 @@ class HTML extends AbstractWriter implements WriterInterface } elseif ($element instanceof Object) { $html .= $this->writeObject($element); } elseif ($element instanceof Footnote) { - $html .= $this->writeFootnote($element, true); + $html .= $this->writeFootnote($element); } elseif ($element instanceof Endnote) { - $html .= $this->writeEndnote($element, true); + $html .= $this->writeEndnote($element); } } } @@ -248,9 +249,9 @@ class HTML extends AbstractWriter implements WriterInterface } elseif ($element instanceof Image) { $html .= $this->writeImage($element, true); } elseif ($element instanceof Footnote) { - $html .= $this->writeFootnote($element, true); + $html .= $this->writeFootnote($element); } elseif ($element instanceof Endnote) { - $html .= $this->writeEndnote($element, true); + $html .= $this->writeEndnote($element); } } $html .= '

    ' . PHP_EOL; @@ -263,6 +264,7 @@ class HTML extends AbstractWriter implements WriterInterface * Write link * * @param Link $element + * @param boolean $withoutP * @return string */ private function writeLink($element, $withoutP = false) @@ -300,6 +302,7 @@ class HTML extends AbstractWriter implements WriterInterface * Write preserve text * * @param PreserveText $element + * @param boolean $withoutP * @return string */ private function writePreserveText($element, $withoutP = false) @@ -350,7 +353,7 @@ class HTML extends AbstractWriter implements WriterInterface /** * Write table * - * @param Title $element + * @param Table $element * @return string */ private function writeTable($element) @@ -361,7 +364,7 @@ class HTML extends AbstractWriter implements WriterInterface if ($cRows > 0) { $html .= "" . PHP_EOL; foreach ($rows as $row) { - $height = $row->getHeight(); + // $height = $row->getHeight(); $rowStyle = $row->getStyle(); $tblHeader = $rowStyle->getTblHeader(); $html .= "" . PHP_EOL; @@ -388,13 +391,13 @@ class HTML extends AbstractWriter implements WriterInterface } elseif ($content instanceof Object) { $html .= $this->writeObject($content); } elseif ($element instanceof Footnote) { - $html .= $this->writeFootnote($element, true); + $html .= $this->writeFootnote($element); } elseif ($element instanceof Endnote) { - $html .= $this->writeEndnote($element, true); + $html .= $this->writeEndnote($element); } } } else { - $this->writeTextBreak($content); + $html .= $this->writeTextBreak(new TextBreak()); } $html .= "" . PHP_EOL; } @@ -410,6 +413,7 @@ class HTML extends AbstractWriter implements WriterInterface * Write image * * @param Image $element + * @param boolean $withoutP * @return string */ private function writeImage($element, $withoutP = false) @@ -421,6 +425,7 @@ class HTML extends AbstractWriter implements WriterInterface * Write object * * @param Object $element + * @param boolean $withoutP * @return string */ private function writeObject($element, $withoutP = false) @@ -478,11 +483,14 @@ class HTML extends AbstractWriter implements WriterInterface */ private function writeStyles() { + $bodyCss = array(); $css = '

    Results: '; - foreach ($types as $type) { - $result = 'results/' . SCRIPT_FILENAME . '.' . $type; - if (file_exists($result)) { - echo "{$type} "; - } - } - echo '