diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f4cd810..af3ca786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This release changed PHPWord license from LGPL 2.1 to LGPL 3. - Static classes `Footnotes`, `Endnotes`, and `TOC` - `Writer\Word2007\Part`: `Numbering::writeNumbering()`, `Settings::writeSettings()`, `WebSettings::writeWebSettings()`, `ContentTypes::writeContentTypes()`, `Styles::writeStyles()`, `Document::writeDocument()` all changed into `write()` - `Writer\Word2007\Part\DocProps`: Split into `Writer\Word2007\Part\DocPropsCore` and `Writer\Word2007\Part\DocPropsApp` +- `Element\Title::getBookmarkId()` replaced by `Element\Title::getRelationId()` ### Miscellaneous diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index 86b604f4..39193031 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -35,15 +35,78 @@ abstract class AbstractContainer extends AbstractElement protected $elements = array(); /** - * Set element index and unique id, and add element into elements collection + * Container type section|header|footer|footnote|endnote|cell|textrun|textbox + * + * @var string */ - protected function addElement(AbstractElement $element) + protected $container; + + /** + * Add element + * + * Each element has different number of parameters passed + * + * @param string $elementName + * @return \PhpOffice\PhpWord\Element\AbstractElement + */ + protected function addElement($elementName) { - // $type = str_replace('PhpOffice\\PhpWord\\Element\\', '', get_class($element))); + $elementClass = __NAMESPACE__ . '\\' . $elementName; + $this->checkValidity($elementName); + + // Get arguments + $args = func_get_args(); + $argsCount = func_num_args(); + $withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun')); + if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) { + $args[3] = null; + } + + // Create element + if ($argsCount == 1) { // Page Break + $element = new $elementClass(); + } elseif ($argsCount == 2) { // TextRun, TextBox, Table, Footnote, Endnote + $element = new $elementClass($args[1]); + } elseif ($argsCount == 3) { // Object, TextBreak, Title + $element = new $elementClass($args[1], $args[2]); + } elseif ($argsCount == 4) { // PreserveText, Text, Image + $element = new $elementClass($args[1], $args[2], $args[3]); + } elseif ($argsCount == 5) { // CheckBox, Link, ListItemRun, TOC + $element = new $elementClass($args[1], $args[2], $args[3], $args[4]); + } elseif ($argsCount == 6) { // ListItem + $element = new $elementClass($args[1], $args[2], $args[3], $args[4], $args[5]); + } + + // Set relation Id for media collection + if (in_array($elementName, array('Link', 'Image', 'Object'))) { + $mediaContainer = $this->getMediaContainer(); + if ($elementName == 'Image') { + $rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1], $element); + } else { + $rId = Media::addElement($mediaContainer, strtolower($elementName), $args[1]); + } + $element->setRelationId($rId); + } + if ($elementName == 'Object') { + $rIdIcon = Media::addElement($mediaContainer, 'image', $element->getIcon(), new Image($element->getIcon())); + $element->setImageRelationId($rIdIcon); + } + + // Set relation Id for other collection + if (in_array($elementName, array('Footnote', 'Endnote', 'Title')) && $this->phpWord instanceof PhpWord) { + $addMethod = "add{$elementName}"; + $rId = $this->phpWord->$addMethod($element); + $element->setRelationId($rId); + } + + // Set other properties and add element into collection + $element->setDocPart($this->getDocPart(), $this->getDocPartId()); $element->setElementIndex($this->countElements() + 1); $element->setElementId(); $element->setPhpWord($this->phpWord); $this->elements[] = $element; + + return $element; } /** @@ -59,62 +122,24 @@ abstract class AbstractContainer extends AbstractElement /** * Count elements * - * @return integer + * @return int */ public function countElements() { return count($this->elements); } - /** - * Add generic element with style - * - * This is how all elements should be added with dependency injection: with - * just one simple $style. Currently this function supports TextRun, Table, - * and TextBox since all other elements have different arguments - * - * @todo Change the function name into something better? - * - * @param string $elementName - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\AbstractElement - */ - private function addGenericElement($elementName, $style) - { - $elementClass = __NAMESPACE__ . '\\' . $elementName; - - $this->checkValidity($elementName); - $element = new $elementClass($style); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); - - return $element; - } - /** * Add text/preservetext element * * @param string $text * @param mixed $fontStyle * @param mixed $paragraphStyle - * @param string $elementName Text|PreserveText * @return \PhpOffice\PhpWord\Element\Text|\PhpOffice\PhpWord\Element\PreserveText */ - public function addText($text, $fontStyle = null, $paragraphStyle = null, $elementName = 'Text') + public function addText($text, $fontStyle = null, $paragraphStyle = null) { - $this->checkValidity($elementName); - $elementClass = substr(get_class($this), 0, strrpos(get_class($this), '\\')) . '\\' . $elementName; - - // Reset paragraph style for footnote and textrun. They have their own - if (in_array($this->container, array('textrun', 'footnote', 'endnote', 'listitemrun'))) { - $paragraphStyle = null; - } - - $element = new $elementClass($text, $fontStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); - - return $element; + return $this->addElement('Text', $text, $fontStyle, $paragraphStyle); } /** @@ -125,7 +150,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addTextRun($paragraphStyle = null) { - return $this->addGenericElement('TextRun', $paragraphStyle); + return $this->addElement('TextRun', $paragraphStyle); } /** @@ -139,18 +164,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addLink($target, $text = null, $fontStyle = null, $paragraphStyle = null) { - $this->checkValidity('Link'); - $elementDocPart = $this->checkElementDocPart(); - - $element = new Link($target, $text, $fontStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - - $rId = Media::addElement($elementDocPart, 'link', $target); - $element->setRelationId($rId); - - $this->addElement($element); - - return $element; + return $this->addElement('Link', $target, $text, $fontStyle, $paragraphStyle); } /** @@ -163,7 +177,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addPreserveText($text, $fontStyle = null, $paragraphStyle = null) { - return $this->addText($text, $fontStyle, $paragraphStyle, 'PreserveText'); + return $this->addElement('PreserveText', $text, $fontStyle, $paragraphStyle); } /** @@ -175,12 +189,8 @@ abstract class AbstractContainer extends AbstractElement */ public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) { - $this->checkValidity('TextBreak'); - for ($i = 1; $i <= $count; $i++) { - $element = new TextBreak($fontStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); + $this->addElement('TextBreak', $fontStyle, $paragraphStyle); } } @@ -196,13 +206,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addListItem($text, $depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null) { - $this->checkValidity('ListItem'); - - $element = new ListItem($text, $depth, $fontStyle, $listStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); - - return $element; + return $this->addElement('ListItem', $text, $depth, $fontStyle, $listStyle, $paragraphStyle); } /** @@ -216,13 +220,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addListItemRun($depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null) { - $this->checkValidity('ListItemRun'); - - $element = new ListItemRun($depth, $fontStyle, $listStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); - - return $element; + return $this->addElement('ListItemRun', $depth, $fontStyle, $listStyle, $paragraphStyle); } /** @@ -234,7 +232,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addTable($style = null) { - return $this->addGenericElement('Table', $style); + return $this->addElement('Table', $style); } /** @@ -242,23 +240,12 @@ abstract class AbstractContainer extends AbstractElement * * @param string $source * @param mixed $style Image style - * @param boolean $isWatermark + * @param bool $isWatermark * @return \PhpOffice\PhpWord\Element\Image */ public function addImage($source, $style = null, $isWatermark = false) { - $this->checkValidity('Image'); - $elementDocPart = $this->checkElementDocPart(); - - $element = new Image($source, $style, $isWatermark); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - - $rId = Media::addElement($elementDocPart, 'image', $source, $element); - $element->setRelationId($rId); - - $this->addElement($element); - - return $element; + return $this->addElement('Image', $source, $style, $isWatermark); } /** @@ -269,49 +256,21 @@ abstract class AbstractContainer extends AbstractElement * @param string $source * @param mixed $style * @return \PhpOffice\PhpWord\Element\Object - * @throws \PhpOffice\PhpWord\Exception\Exception */ public function addObject($source, $style = null) { - $this->checkValidity('Object'); - $elementDocPart = $this->checkElementDocPart(); - - $element = new Object($source, $style); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - - $rId = Media::addElement($elementDocPart, 'object', $source); - $element->setRelationId($rId); - $rIdIcon = Media::addElement($elementDocPart, 'image', $element->getIcon(), new Image($element->getIcon())); - $element->setImageRelationId($rIdIcon); - - $this->addElement($element); - - return $element; + return $this->addElement('Object', $source, $style); } /** * Add footnote element * * @param mixed $paragraphStyle - * @param string $elementName * @return \PhpOffice\PhpWord\Element\Footnote */ - public function addFootnote($paragraphStyle = null, $elementName = 'Footnote') + public function addFootnote($paragraphStyle = null) { - $this->checkValidity($elementName); - $elementClass = substr(get_class($this), 0, strrpos(get_class($this), '\\')) . '\\' . $elementName; - $docPart = strtolower($elementName); - $addMethod = "add{$elementName}"; - - $element = new $elementClass($paragraphStyle); - $element->setDocPart($docPart, $this->getDocPartId()); - if ($this->phpWord instanceof PhpWord) { - $rId = $this->phpWord->$addMethod($element); - $element->setRelationId($rId); - } - $this->addElement($element); - - return $element; + return $this->addElement('Footnote', $paragraphStyle); } /** @@ -322,7 +281,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addEndnote($paragraphStyle = null) { - return $this->addFootnote($paragraphStyle, 'Endnote'); + return $this->addElement('Endnote', $paragraphStyle); } /** @@ -336,13 +295,7 @@ abstract class AbstractContainer extends AbstractElement */ public function addCheckBox($name, $text, $fontStyle = null, $paragraphStyle = null) { - $this->checkValidity('CheckBox'); - - $element = new CheckBox($name, $text, $fontStyle, $paragraphStyle); - $element->setDocPart($this->getDocPart(), $this->getDocPartId()); - $this->addElement($element); - - return $element; + return $this->addElement('CheckBox', $name, $text, $fontStyle, $paragraphStyle); } /** @@ -353,47 +306,50 @@ abstract class AbstractContainer extends AbstractElement */ public function addTextBox($style = null) { - return $this->addGenericElement('TextBox', $style); + return $this->addElement('TextBox', $style); } /** * Check if a method is allowed for the current container * * @param string $method - * @return boolean + * @return bool */ private function checkValidity($method) { // Valid containers for each element - $allContainers = array('section', 'header', 'footer', 'cell', 'textrun', 'footnote', 'endnote', 'textbox', 'listitemrun'); + $allContainers = array( + 'Section', 'Header', 'Footer', 'Footnote', 'Endnote', + 'Cell', 'TextRun', 'TextBox', 'ListItemRun', + ); $validContainers = array( 'Text' => $allContainers, 'Link' => $allContainers, 'TextBreak' => $allContainers, 'Image' => $allContainers, 'Object' => $allContainers, - 'TextRun' => array('section', 'header', 'footer', 'cell', 'textbox'), - 'ListItem' => array('section', 'header', 'footer', 'cell', 'textbox'), - 'ListItemRun' => array('section', 'header', 'footer', 'cell', 'textbox'), - 'Table' => array('section', 'header', 'footer', 'cell', 'textbox'), - 'CheckBox' => array('section', 'header', 'footer', 'cell'), - 'TextBox' => array('section', 'header', 'footer', 'cell'), - 'Footnote' => array('section', 'textrun', 'cell'), - 'Endnote' => array('section', 'textrun', 'cell'), - 'PreserveText' => array('header', 'footer', 'cell'), + 'TextRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), + 'ListItem' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), + 'ListItemRun' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), + 'Table' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), + 'CheckBox' => array('Section', 'Header', 'Footer', 'Cell'), + 'TextBox' => array('Section', 'Header', 'Footer', 'Cell'), + 'Footnote' => array('Section', 'TextRun', 'Cell'), + 'Endnote' => array('Section', 'TextRun', 'Cell'), + 'PreserveText' => array('Header', 'Footer', 'Cell'), ); // Special condition, e.g. preservetext can only exists in cell when // the cell is located in header or footer $validSubcontainers = array( - 'PreserveText' => array(array('cell'), array('header', 'footer')), - 'Footnote' => array(array('cell', 'textrun'), array('section')), - 'Endnote' => array(array('cell', 'textrun'), array('section')), + 'PreserveText' => array(array('Cell'), array('Header', 'Footer')), + 'Footnote' => array(array('Cell', 'TextRun'), array('Section')), + 'Endnote' => array(array('Cell', 'TextRun'), array('Section')), ); // Check if a method is valid for current container if (array_key_exists($method, $validContainers)) { if (!in_array($this->container, $validContainers[$method])) { - throw new \BadMethodCallException("Cannot put $method in $this->container."); + throw new \BadMethodCallException("Cannot add $method in $this->container."); } } // Check if a method is valid for current container, located in other container @@ -403,7 +359,7 @@ abstract class AbstractContainer extends AbstractElement $allowedDocParts = $rules[1]; foreach ($containers as $container) { if ($this->container == $container && !in_array($this->getDocPart(), $allowedDocParts)) { - throw new \BadMethodCallException("Cannot put $method in $this->container."); + throw new \BadMethodCallException("Cannot add $method in $this->container."); } } } @@ -412,17 +368,21 @@ abstract class AbstractContainer extends AbstractElement } /** - * Return element location in document: section, headerx, or footerx + * Return media element (image, object, link) container name + * + * @return string section|headerx|footerx|footnote|endnote */ - private function checkElementDocPart() + private function getMediaContainer() { - $inOtherPart = in_array($this->container, array('cell', 'textrun', 'textbox', 'listitemrun')); - $docPart = $inOtherPart ? $this->getDocPart() : $this->container; - $docPartId = $inOtherPart ? $this->getDocPartId() : $this->sectionId; - $inHeaderFooter = ($docPart == 'header' || $docPart == 'footer'); - $docPartId = $inHeaderFooter ? $this->getDocPartId() : $docPartId; + $partName = $this->container; + if (in_array($partName, array('Cell', 'TextRun', 'TextBox', 'ListItemRun'))) { + $partName = $this->getDocPart(); + } + if ($partName == 'Header' || $partName == 'Footer') { + $partName .= $this->getDocPartId(); + } - return $inHeaderFooter ? $docPart . $docPartId : $docPart; + return strtolower($partName); } /** diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index 7e3151e2..40e65c12 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -34,13 +34,6 @@ abstract class AbstractElement */ protected $phpWord; - /** - * Container type section|header|footer|cell|textrun|footnote|endnote|textbox - * - * @var string - */ - protected $container; - /** * Section Id * @@ -57,7 +50,7 @@ abstract class AbstractElement * * @var string */ - protected $docPart = 'section'; + protected $docPart = 'Section'; /** * Document part Id @@ -66,21 +59,21 @@ abstract class AbstractElement * because the max number of header/footer in every page is 3, i.e. * AUTO, FIRST, and EVEN (AUTO = ODD) * - * @var integer + * @var int */ protected $docPartId = 1; /** * Index of element in the elements collection (start with 1) * - * @var integer + * @var int */ protected $elementIndex = 1; /** * Unique Id for element * - * @var integer + * @var int */ protected $elementId; @@ -114,7 +107,7 @@ abstract class AbstractElement /** * Get section number * - * @return integer + * @return int */ public function getSectionId() { @@ -125,7 +118,7 @@ abstract class AbstractElement * Set doc part * * @param string $docPart - * @param integer $docPartId + * @param int $docPartId */ public function setDocPart($docPart, $docPartId = 1) { @@ -146,7 +139,7 @@ abstract class AbstractElement /** * Get doc part Id * - * @return integer + * @return int */ public function getDocPartId() { @@ -212,13 +205,13 @@ abstract class AbstractElement } /** - * Check if element is located in section doc part (as opposed to header/footer) + * Check if element is located in Section doc part (as opposed to Header/Footer) * - * @return boolean + * @return bool */ public function isInSection() { - return ($this->docPart == 'section'); + return ($this->docPart == 'Section'); } /** @@ -226,7 +219,7 @@ abstract class AbstractElement * * @param mixed $styleObject Style object * @param mixed $styleValue Style value - * @param boolean $returnObject Always return object + * @param bool $returnObject Always return object */ protected function setStyle($styleObject, $styleValue = null, $returnObject = false) { diff --git a/src/PhpWord/Element/Cell.php b/src/PhpWord/Element/Cell.php index bc9b47b4..ea49bc7b 100644 --- a/src/PhpWord/Element/Cell.php +++ b/src/PhpWord/Element/Cell.php @@ -24,6 +24,11 @@ use PhpOffice\PhpWord\Style\Cell as CellStyle; */ class Cell extends AbstractContainer { + /** + * @var string Container type + */ + protected $container = 'Cell'; + /** * Cell width * @@ -36,22 +41,18 @@ class Cell extends AbstractContainer * * @var \PhpOffice\PhpWord\Style\Cell */ - private $cellStyle; + private $style; /** * Create new instance * - * @param string $docPart section|header|footer - * @param int $docPartId * @param int $width * @param array|\PhpOffice\PhpWord\Style\Cell $style */ - public function __construct($docPart, $docPartId, $width = null, $style = null) + public function __construct($width = null, $style = null) { - $this->container = 'cell'; - $this->setDocPart($docPart, $docPartId); $this->width = $width; - $this->cellStyle = $this->setStyle(new CellStyle(), $style, true); + $this->style = $this->setStyle(new CellStyle(), $style, true); } /** @@ -61,7 +62,7 @@ class Cell extends AbstractContainer */ public function getStyle() { - return $this->cellStyle; + return $this->style; } /** diff --git a/src/PhpWord/Element/Endnote.php b/src/PhpWord/Element/Endnote.php index 03ef3b68..20278898 100644 --- a/src/PhpWord/Element/Endnote.php +++ b/src/PhpWord/Element/Endnote.php @@ -26,6 +26,11 @@ use PhpOffice\PhpWord\Style\Paragraph; */ class Endnote extends Footnote { + /** + * @var string Container type + */ + protected $container = 'Endnote'; + /** * Create new instance * @@ -33,7 +38,6 @@ class Endnote extends Footnote */ public function __construct($paragraphStyle = null) { - $this->container = 'endnote'; $this->paragraphStyle = $this->setStyle(new Paragraph(), $paragraphStyle); } } diff --git a/src/PhpWord/Element/Footer.php b/src/PhpWord/Element/Footer.php index 265c2c4c..142ccfda 100644 --- a/src/PhpWord/Element/Footer.php +++ b/src/PhpWord/Element/Footer.php @@ -33,11 +33,9 @@ class Footer extends AbstractContainer const EVEN = 'even'; /** - * Container type - * - * @var string + * @var string Container type */ - protected $container = 'footer'; + protected $container = 'Footer'; /** * Header type diff --git a/src/PhpWord/Element/Footnote.php b/src/PhpWord/Element/Footnote.php index d59a10a5..76311c6b 100644 --- a/src/PhpWord/Element/Footnote.php +++ b/src/PhpWord/Element/Footnote.php @@ -24,6 +24,11 @@ use PhpOffice\PhpWord\Style\Paragraph; */ class Footnote extends AbstractContainer { + /** + * @var string Container type + */ + protected $container = 'Footnote'; + /** * Paragraph style * @@ -38,7 +43,6 @@ class Footnote extends AbstractContainer */ public function __construct($paragraphStyle = null) { - $this->container = 'footnote'; $this->paragraphStyle = $this->setStyle(new Paragraph(), $paragraphStyle); } diff --git a/src/PhpWord/Element/Header.php b/src/PhpWord/Element/Header.php index be95936c..feaa86e8 100644 --- a/src/PhpWord/Element/Header.php +++ b/src/PhpWord/Element/Header.php @@ -22,13 +22,10 @@ namespace PhpOffice\PhpWord\Element; */ class Header extends Footer { - /** - * Container type - * - * @var string + * @var string Container type */ - protected $container = 'header'; + protected $container = 'Header'; /** * Add a Watermark Element diff --git a/src/PhpWord/Element/ListItemRun.php b/src/PhpWord/Element/ListItemRun.php index a6dbd932..2a2a51af 100644 --- a/src/PhpWord/Element/ListItemRun.php +++ b/src/PhpWord/Element/ListItemRun.php @@ -25,6 +25,11 @@ use PhpOffice\PhpWord\Style\Paragraph; */ class ListItemRun extends TextRun { + /** + * @var string Container type + */ + protected $container = 'ListItemRun'; + /** * ListItem Style * @@ -49,7 +54,6 @@ class ListItemRun extends TextRun */ public function __construct($depth = 0, $fontStyle = null, $listStyle = null, $paragraphStyle = null) { - $this->container = 'listitemrun'; $this->depth = $depth; // Version >= 0.10.0 will pass numbering style name. Older version will use old method diff --git a/src/PhpWord/Element/Row.php b/src/PhpWord/Element/Row.php index 0eb18784..3aef4539 100644 --- a/src/PhpWord/Element/Row.php +++ b/src/PhpWord/Element/Row.php @@ -50,14 +50,11 @@ class Row extends AbstractElement /** * Create a new table row * - * @param string $docPart - * @param int $docPartId * @param int $height * @param mixed $style */ - public function __construct($docPart, $docPartId, $height = null, $style = null) + public function __construct($height = null, $style = null) { - $this->setDocPart($docPart, $docPartId); $this->height = $height; $this->style = $this->setStyle(new RowStyle(), $style, true); } @@ -67,12 +64,15 @@ class Row extends AbstractElement * * @param int $width * @param mixed $style + * @return \PhpOffice\PhpWord\Element\Cell */ public function addCell($width = null, $style = null) { - $cell = new Cell($this->getDocPart(), $this->getDocPartId(), $width, $style); + $cell = new Cell($width, $style); + $cell->setDocPart($this->getDocPart(), $this->getDocPartId()); $cell->setPhpWord($this->phpWord); $this->cells[] = $cell; + return $cell; } diff --git a/src/PhpWord/Element/Section.php b/src/PhpWord/Element/Section.php index 04ff5aa2..8a2b474f 100644 --- a/src/PhpWord/Element/Section.php +++ b/src/PhpWord/Element/Section.php @@ -26,6 +26,11 @@ use PhpOffice\PhpWord\Style\Section as SectionSettings; */ class Section extends AbstractContainer { + /** + * @var string Container type + */ + protected $container = 'Section'; + /** * Section settings * @@ -55,7 +60,6 @@ class Section extends AbstractContainer */ public function __construct($sectionCount, $settings = null) { - $this->container = 'section'; $this->sectionId = $sectionCount; $this->setDocPart($this->container, $this->sectionId); $this->settings = new SectionSettings(); @@ -98,15 +102,7 @@ class Section extends AbstractContainer */ public function addTitle($text, $depth = 1) { - $title = new Title($text, $depth); - $title->setDocPart($this->getDocPart(), $this->getDocPartId()); - if ($this->phpWord instanceof PhpWord) { - $bookmarkId = $this->phpWord->addTitle($title); - $title->setBookmarkId($bookmarkId); - } - $this->addElement($title); - - return $title; + return $this->addElement('Title', $text, $depth); } /** @@ -114,7 +110,7 @@ class Section extends AbstractContainer */ public function addPageBreak() { - $this->addElement(new PageBreak()); + return $this->addElement('PageBreak'); } /** @@ -128,10 +124,7 @@ class Section extends AbstractContainer */ public function addTOC($fontStyle = null, $tocStyle = null, $minDepth = 1, $maxDepth = 9) { - $toc = new TOC($fontStyle, $tocStyle, $minDepth, $maxDepth); - $this->addElement($toc); - - return $toc; + return $this->addElement('TOC', $fontStyle, $tocStyle, $minDepth, $maxDepth); } /** diff --git a/src/PhpWord/Element/Table.php b/src/PhpWord/Element/Table.php index e87c591f..ee45e36f 100644 --- a/src/PhpWord/Element/Table.php +++ b/src/PhpWord/Element/Table.php @@ -41,7 +41,7 @@ class Table extends AbstractElement /** * Table width * - * @var integer + * @var int */ private $width = null; @@ -59,28 +59,32 @@ class Table extends AbstractElement /** * Add a row * - * @param integer $height + * @param int $height * @param mixed $style + * @return \PhpOffice\PhpWord\Element\Row */ public function addRow($height = null, $style = null) { - $row = new Row($this->getDocPart(), $this->getDocPartId(), $height, $style); + $row = new Row($height, $style); + $row->setDocPart($this->getDocPart(), $this->getDocPartId()); $row->setPhpWord($this->phpWord); $this->rows[] = $row; + return $row; } /** * Add a cell * - * @param integer $width + * @param int $width * @param mixed $style - * @return Cell + * @return \PhpOffice\PhpWord\Element\Cell */ public function addCell($width = null, $style = null) { $index = count($this->rows) - 1; $cell = $this->rows[$index]->addCell($width, $style); + return $cell; } @@ -107,7 +111,7 @@ class Table extends AbstractElement /** * Set table width * - * @param integer $width + * @param int $width */ public function setWidth($width) { @@ -117,7 +121,7 @@ class Table extends AbstractElement /** * Get table width * - * @return integer + * @return int */ public function getWidth() { @@ -127,7 +131,7 @@ class Table extends AbstractElement /** * Get column count * - * @return integer + * @return int */ public function countColumns() { diff --git a/src/PhpWord/Element/TextBox.php b/src/PhpWord/Element/TextBox.php index c3c83d81..06c95181 100644 --- a/src/PhpWord/Element/TextBox.php +++ b/src/PhpWord/Element/TextBox.php @@ -26,6 +26,11 @@ use PhpOffice\PhpWord\Style\TextBox as TextBoxStyle; */ class TextBox extends AbstractContainer { + /** + * @var string Container type + */ + protected $container = 'TextBox'; + /** * TextBox style * @@ -40,7 +45,6 @@ class TextBox extends AbstractContainer */ public function __construct($style = null) { - $this->container = 'textbox'; $this->style = $this->setStyle(new TextBoxStyle(), $style); } diff --git a/src/PhpWord/Element/TextRun.php b/src/PhpWord/Element/TextRun.php index 6c8aa010..75837104 100644 --- a/src/PhpWord/Element/TextRun.php +++ b/src/PhpWord/Element/TextRun.php @@ -24,6 +24,11 @@ use PhpOffice\PhpWord\Style\Paragraph; */ class TextRun extends AbstractContainer { + /** + * @var string Container type + */ + protected $container = 'TextRun'; + /** * Paragraph style * @@ -38,7 +43,6 @@ class TextRun extends AbstractContainer */ public function __construct($paragraphStyle = null) { - $this->container = 'textrun'; $this->paragraphStyle = $this->setStyle(new Paragraph(), $paragraphStyle); } diff --git a/src/PhpWord/Element/Title.php b/src/PhpWord/Element/Title.php index 481f061b..3a1b3049 100644 --- a/src/PhpWord/Element/Title.php +++ b/src/PhpWord/Element/Title.php @@ -39,13 +39,6 @@ class Title extends AbstractElement */ private $depth = 1; - /** - * Title Bookmark ID - * - * @var int - */ - private $bookmarkId = 1; - /** * Name of the heading style, e.g. 'Heading1' * @@ -56,7 +49,7 @@ class Title extends AbstractElement /** * Title anchor * - * @var int + * @var string * @deprecated 0.10.0 */ private $anchor; @@ -79,26 +72,6 @@ class Title extends AbstractElement return $this; } - /** - * Set Bookmark ID - * - * @param int $bookmarkId - */ - public function setBookmarkId($bookmarkId) - { - $this->bookmarkId = $bookmarkId; - } - - /** - * Get Anchor - * - * @return int - */ - public function getBookmarkId() - { - return $this->bookmarkId; - } - /** * Get Title Text content * @@ -132,7 +105,7 @@ class Title extends AbstractElement /** * Set Anchor * - * @param int $anchor + * @param string $anchor * @deprecated 0.10.0 * @codeCoverageIgnore */ @@ -144,12 +117,36 @@ class Title extends AbstractElement /** * Get Anchor * - * @return int + * @return string * @deprecated 0.10.0 * @codeCoverageIgnore */ public function getAnchor() { - return '_Toc' . (252634154 + $this->bookmarkId); + return '_Toc' . (252634154 + $this->getRelationId()); + } + + /** + * Set Bookmark ID + * + * @param int $value + * @deprecated 0.11.0 + * @codeCoverageIgnore + */ + public function setBookmarkId($value) + { + $this->setRelationId($value); + } + + /** + * Get bookmark ID + * + * @return int + * @deprecated 0.11.0 + * @codeCoverageIgnore + */ + public function getBookmarkId() + { + return $this->getRelationId(); } } diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 1df56e68..c56e418b 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -207,6 +207,7 @@ class Html case 'li': $cNodes = $node->childNodes; if (count($cNodes) > 0) { + $text = ''; foreach ($cNodes as $cNode) { if ($cNode->nodeName == '#text') { $text = $cNode->nodeValue; diff --git a/src/PhpWord/Writer/HTML/Element/Container.php b/src/PhpWord/Writer/HTML/Element/Container.php index c55a7921..c4bbc2f8 100644 --- a/src/PhpWord/Writer/HTML/Element/Container.php +++ b/src/PhpWord/Writer/HTML/Element/Container.php @@ -32,7 +32,7 @@ class Container extends AbstractElement public function write() { $container = $this->element; - if (!$this->element instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { + if (!$container instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { return; } $containerClass = substr(get_class($container), strrpos(get_class($container), '\\') + 1); diff --git a/src/PhpWord/Writer/ODText/Style/Font.php b/src/PhpWord/Writer/ODText/Style/Font.php index eb96946c..148c8dbc 100644 --- a/src/PhpWord/Writer/ODText/Style/Font.php +++ b/src/PhpWord/Writer/ODText/Style/Font.php @@ -47,18 +47,18 @@ class Font extends AbstractStyle // Name $font = $style->getName(); - $xmlWriter->writeAttributeIf($font, 'style:font-name', $font); - $xmlWriter->writeAttributeIf($font, 'style:font-name-complex', $font); + $xmlWriter->writeAttributeIf($font != '', 'style:font-name', $font); + $xmlWriter->writeAttributeIf($font != '', 'style:font-name-complex', $font); $size = $style->getSize(); // Size - $xmlWriter->writeAttributeIf($size, 'fo:font-size', $size . 'pt'); - $xmlWriter->writeAttributeIf($size, 'style:font-size-asian', $size . 'pt'); - $xmlWriter->writeAttributeIf($size, 'style:font-size-complex', $size . 'pt'); + $xmlWriter->writeAttributeIf(is_numeric($size), 'fo:font-size', $size . 'pt'); + $xmlWriter->writeAttributeIf(is_numeric($size), 'style:font-size-asian', $size . 'pt'); + $xmlWriter->writeAttributeIf(is_numeric($size), 'style:font-size-complex', $size . 'pt'); // Color $color = $style->getColor(); - $xmlWriter->writeAttributeIf($color, 'fo:color', '#' . $color); + $xmlWriter->writeAttributeIf($color != '', 'fo:color', '#' . $color); // Bold & italic $xmlWriter->writeAttributeIf($style->isBold(), 'fo:font-weight', 'bold'); diff --git a/src/PhpWord/Writer/RTF/Element/Container.php b/src/PhpWord/Writer/RTF/Element/Container.php index 4ce4334c..67caba1d 100644 --- a/src/PhpWord/Writer/RTF/Element/Container.php +++ b/src/PhpWord/Writer/RTF/Element/Container.php @@ -32,7 +32,7 @@ class Container extends \PhpOffice\PhpWord\Writer\HTML\Element\Container public function write() { $container = $this->element; - if (!$this->element instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { + if (!$container instanceof \PhpOffice\PhpWord\Element\AbstractContainer) { return; } $containerClass = substr(get_class($container), strrpos(get_class($container), '\\') + 1); diff --git a/src/PhpWord/Writer/Word2007/Element/Image.php b/src/PhpWord/Writer/Word2007/Element/Image.php index 1b4284d2..c41199f8 100644 --- a/src/PhpWord/Writer/Word2007/Element/Image.php +++ b/src/PhpWord/Writer/Word2007/Element/Image.php @@ -51,7 +51,6 @@ class Image extends AbstractElement */ private function writeImage(XMLWriter $xmlWriter, ImageElement $element) { - $rId = $element->getRelationId() + ($element->isInSection() ? 6 : 0); $style = $element->getStyle(); $styleWriter = new ImageStyleWriter($xmlWriter, $style); diff --git a/src/PhpWord/Writer/Word2007/Element/TOC.php b/src/PhpWord/Writer/Word2007/Element/TOC.php index 98486b01..88dd0dbd 100644 --- a/src/PhpWord/Writer/Word2007/Element/TOC.php +++ b/src/PhpWord/Writer/Word2007/Element/TOC.php @@ -17,6 +17,8 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Element; +use PhpOffice\PhpWord\Element\TOC as TOCElement; +use PhpOffice\PhpWord\Shared\XMLWriter; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Writer\Word2007\Style\Font as FontStyleWriter; use PhpOffice\PhpWord\Writer\Word2007\Style\Paragraph as ParagraphStyleWriter; @@ -44,7 +46,7 @@ class TOC extends AbstractElement $writeFieldMark = true; foreach ($titles as $title) { - $this->writeTitle($title, $writeFieldMark); + $this->writeTitle($xmlWriter, $element, $title, $writeFieldMark); if ($writeFieldMark) { $writeFieldMark = false; } @@ -65,23 +67,20 @@ class TOC extends AbstractElement * @param \PhpOffice\PhpWord\Element\Title $title * @param bool $writeFieldMark */ - private function writeTitle($title, $writeFieldMark) + private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $writeFieldMark) { - $xmlWriter = $this->getXmlWriter(); - $element = $this->getElement(); - $tocStyle = $element->getStyleTOC(); $fontStyle = $element->getStyleFont(); $isObject = ($fontStyle instanceof Font) ? true : false; - $anchor = '_Toc' . ($title->getBookmarkId() + 252634154); + $anchor = '_Toc' . ($title->getRelationId() + 252634154); $indent = ($title->getDepth() - 1) * $tocStyle->getIndent(); $xmlWriter->startElement('w:p'); // Write style and field mark - $this->writeStyle($indent); + $this->writeStyle($xmlWriter, $element, $indent); if ($writeFieldMark) { - $this->writeFieldMark(); + $this->writeFieldMark($xmlWriter, $element); } // Hyperlink @@ -133,11 +132,8 @@ class TOC extends AbstractElement * * @param int $indent */ - private function writeStyle($indent) + private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, $indent) { - $xmlWriter = $this->getXmlWriter(); - $element = $this->getElement(); - $tocStyle = $element->getStyleTOC(); $fontStyle = $element->getStyleFont(); $isObject = ($fontStyle instanceof Font) ? true : false; @@ -178,11 +174,8 @@ class TOC extends AbstractElement /** * Write TOC Field */ - private function writeFieldMark() + private function writeFieldMark(XMLWriter $xmlWriter, TOCElement $element) { - $xmlWriter = $this->getXmlWriter(); - $element = $this->getElement(); - $minDepth = $element->getMinDepth(); $maxDepth = $element->getMaxDepth(); diff --git a/src/PhpWord/Writer/Word2007/Element/Title.php b/src/PhpWord/Writer/Word2007/Element/Title.php index 703188ef..6f2bd314 100644 --- a/src/PhpWord/Writer/Word2007/Element/Title.php +++ b/src/PhpWord/Writer/Word2007/Element/Title.php @@ -37,8 +37,8 @@ class Title extends AbstractElement return; } - $bookmarkId = $element->getBookmarkId(); - $anchor = '_Toc' . ($bookmarkId + 252634154); + $rId = $element->getRelationId(); + $anchor = '_Toc' . ($rId + 252634154); $style = $element->getStyle(); $text = htmlspecialchars($element->getText()); @@ -61,7 +61,7 @@ class Title extends AbstractElement $xmlWriter->endElement(); $xmlWriter->startElement('w:bookmarkStart'); - $xmlWriter->writeAttribute('w:id', $bookmarkId); + $xmlWriter->writeAttribute('w:id', $rId); $xmlWriter->writeAttribute('w:name', $anchor); $xmlWriter->endElement(); @@ -72,7 +72,7 @@ class Title extends AbstractElement $xmlWriter->endElement(); $xmlWriter->startElement('w:bookmarkEnd'); - $xmlWriter->writeAttribute('w:id', $bookmarkId); + $xmlWriter->writeAttribute('w:id', $rId); $xmlWriter->endElement(); $xmlWriter->endElement(); diff --git a/tests/PhpWord/Tests/Element/CellTest.php b/tests/PhpWord/Tests/Element/CellTest.php index 466188f6..af924bc8 100644 --- a/tests/PhpWord/Tests/Element/CellTest.php +++ b/tests/PhpWord/Tests/Element/CellTest.php @@ -31,8 +31,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testConstruct() { - $iVal = rand(1, 1000); - $oCell = new Cell('section', $iVal); + $oCell = new Cell(); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $oCell); $this->assertEquals($oCell->getWidth(), null); @@ -43,8 +42,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testConstructWithStyleArray() { - $iVal = rand(1, 1000); - $oCell = new Cell('section', $iVal, null, array('valign' => 'center')); + $oCell = new Cell(null, array('valign' => 'center')); $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Cell', $oCell->getStyle()); $this->assertEquals($oCell->getWidth(), null); @@ -55,7 +53,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddText() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addText('text'); $this->assertCount(1, $oCell->getElements()); @@ -67,7 +65,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddTextNotUTF8() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addText(utf8_decode('ééé')); $this->assertCount(1, $oCell->getElements()); @@ -80,7 +78,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddLink() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addLink(utf8_decode('ééé'), utf8_decode('ééé')); $this->assertCount(1, $oCell->getElements()); @@ -92,7 +90,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddTextBreak() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $oCell->addTextBreak(); $this->assertCount(1, $oCell->getElements()); @@ -103,7 +101,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddListItem() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addListItem('text'); $this->assertCount(1, $oCell->getElements()); @@ -116,7 +114,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddListItemNotUTF8() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addListItem(utf8_decode('ééé')); $this->assertCount(1, $oCell->getElements()); @@ -130,7 +128,7 @@ class CellTest extends \PHPUnit_Framework_TestCase public function testAddImageSection() { $src = __DIR__ . "/../_files/images/earth.jpg"; - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addImage($src); $this->assertCount(1, $oCell->getElements()); @@ -168,35 +166,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddImageSectionByUrl() { - $oCell = new Cell('section', 1); - $element = $oCell->addImage( - 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' - ); - - $this->assertCount(1, $oCell->getElements()); - $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $element); - } - - /** - * Add image header by URL - */ - public function testAddImageHeaderByUrl() - { - $oCell = new Cell('header', 1); - $element = $oCell->addImage( - 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' - ); - - $this->assertCount(1, $oCell->getElements()); - $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $element); - } - - /** - * Add image footer by URL - */ - public function testAddImageFooterByUrl() - { - $oCell = new Cell('footer', 1); + $oCell = new Cell(); $element = $oCell->addImage( 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' ); @@ -211,7 +181,7 @@ class CellTest extends \PHPUnit_Framework_TestCase public function testAddObjectXLS() { $src = __DIR__ . "/../_files/documents/sheet.xls"; - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addObject($src); $this->assertCount(1, $oCell->getElements()); @@ -226,7 +196,7 @@ class CellTest extends \PHPUnit_Framework_TestCase public function testAddObjectException() { $src = __DIR__ . "/../_files/xsl/passthrough.xsl"; - $oCell = new Cell('section', 1); + $oCell = new Cell(); $oCell->addObject($src); } @@ -235,7 +205,8 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddPreserveText() { - $oCell = new Cell('header', 1); + $oCell = new Cell(); + $oCell->setDocPart('Header', 1); $element = $oCell->addPreserveText('text'); $this->assertCount(1, $oCell->getElements()); @@ -247,7 +218,8 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddPreserveTextNotUTF8() { - $oCell = new Cell('header', 1); + $oCell = new Cell(); + $oCell->setDocPart('Header', 1); $element = $oCell->addPreserveText(utf8_decode('ééé')); $this->assertCount(1, $oCell->getElements()); @@ -262,7 +234,8 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddPreserveTextException() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); + $oCell->setDocPart('Section', 1); $oCell->addPreserveText('text'); } @@ -271,7 +244,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testCreateTextRun() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addTextRun(); $this->assertCount(1, $oCell->getElements()); @@ -283,7 +256,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testAddCheckBox() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $element = $oCell->addCheckBox(utf8_decode('ééé'), utf8_decode('ééé')); $this->assertCount(1, $oCell->getElements()); @@ -295,7 +268,7 @@ class CellTest extends \PHPUnit_Framework_TestCase */ public function testGetElements() { - $oCell = new Cell('section', 1); + $oCell = new Cell(); $this->assertInternalType('array', $oCell->getElements()); } diff --git a/tests/PhpWord/Tests/Element/RowTest.php b/tests/PhpWord/Tests/Element/RowTest.php index b0de3910..c377bb7c 100644 --- a/tests/PhpWord/Tests/Element/RowTest.php +++ b/tests/PhpWord/Tests/Element/RowTest.php @@ -32,8 +32,7 @@ class RowTest extends \PHPUnit_Framework_TestCase */ public function testConstruct() { - $iVal = rand(1, 1000); - $oRow = new Row('section', $iVal); + $oRow = new Row(); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Row', $oRow); $this->assertEquals($oRow->getHeight(), null); @@ -48,15 +47,9 @@ class RowTest extends \PHPUnit_Framework_TestCase public function testConstructWithParams() { $iVal = rand(1, 1000); - $iVal2 = rand(1, 1000); - $oRow = new Row( - 'section', - $iVal, - $iVal2, - array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF') - ); + $oRow = new Row($iVal, array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF')); - $this->assertEquals($oRow->getHeight(), $iVal2); + $this->assertEquals($oRow->getHeight(), $iVal); $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\Row', $oRow->getStyle()); } @@ -65,7 +58,7 @@ class RowTest extends \PHPUnit_Framework_TestCase */ public function testAddCell() { - $oRow = new Row('section', 1); + $oRow = new Row(); $element = $oRow->addCell(); $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Cell', $element); diff --git a/tests/PhpWord/Tests/Element/TitleTest.php b/tests/PhpWord/Tests/Element/TitleTest.php index 5b54cce6..301d8bec 100644 --- a/tests/PhpWord/Tests/Element/TitleTest.php +++ b/tests/PhpWord/Tests/Element/TitleTest.php @@ -57,6 +57,6 @@ class TitleTest extends \PHPUnit_Framework_TestCase $iVal = rand(1, 1000); $oTitle->setBookmarkId($iVal); - $this->assertEquals($oTitle->getBookmarkId(), $iVal); + $this->assertEquals($oTitle->getRelationId(), $iVal); } }