diff --git a/.travis.yml b/.travis.yml index 7593379c..50587e49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ script: ## PHP Copy/Paste Detector - php phpcpd.phar src/ tests/ --verbose ## PHP Mess Detector - - phpmd src/,tests/ text unusedcode,naming,design,controversial --exclude pclzip.lib.php + #- phpmd src/,tests/ text unusedcode,naming,design,controversial --exclude pclzip.lib.php ## PHPLOC #- php phploc.phar src/ ## PHPUnit diff --git a/CHANGELOG.md b/CHANGELOG.md index c34fbc22..b309236f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This release changed PHPWord license from LGPL 2.1 to LGPL 3. - Image: Ability to define relative and absolute positioning - @basjan GH-217 - Footer: Conform footer with header by adding firstPage, evenPage and by inheritance - @basjan @ivanlanin GH-219 +- TextBox: Ability to add textbox in section, header, and footer - @basjan @ivanlanin GH-228 ### Bugfixes diff --git a/samples/Sample_25_TextBox.php b/samples/Sample_25_TextBox.php new file mode 100644 index 00000000..575a1df5 --- /dev/null +++ b/samples/Sample_25_TextBox.php @@ -0,0 +1,22 @@ +addSection(); +$textbox = $section->addTextBox(array('align' => 'left', 'width' => 300, 'borderSize' => 1, 'borderColor' => '#FF0000')); +$textbox->addText('Text box content '); +$textbox->addText('with bold text', array('bold' => true)); +$textbox->addText(', '); +$textbox->addLink('http://www.google.com', 'link'); +$textbox->addText(', and image '); +$textbox->addImage('resources/_earth.jpg', array('width' => 18, 'height' => 18)); +$textbox->addText('.'); + +// Save file +echo write($phpWord, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index 920843b7..6e8a0241 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -295,6 +295,23 @@ abstract class AbstractContainer extends AbstractElement return $element; } + /** + * Add textbox element + * + * @param mixed $style + * @return \PhpOffice\PhpWord\Element\TextBox + */ + public function addTextBox($style = null) + { + $this->checkValidity('TextBox'); + + $textbox = new TextBox($style); + $textbox->setDocPart($this->getDocPart(), $this->getDocPartId()); + $this->addElement($textbox); + + return $textbox; + } + /** * Check if a method is allowed for the current container * @@ -314,6 +331,7 @@ abstract class AbstractContainer extends AbstractElement 'TextRun' => array('section', 'header', 'footer', 'cell'), 'ListItem' => array('section', 'header', 'footer', 'cell'), 'CheckBox' => array('section', 'header', 'footer', 'cell'), + 'TextBox' => array('section', 'header', 'footer'), 'Footnote' => array('section', 'textrun', 'cell'), 'Endnote' => array('section', 'textrun', 'cell'), 'PreserveText' => array('header', 'footer', 'cell'), @@ -352,7 +370,7 @@ abstract class AbstractContainer extends AbstractElement */ private function checkElementDocPart() { - $isCellTextrun = in_array($this->container, array('cell', 'textrun')); + $isCellTextrun = in_array($this->container, array('cell', 'textrun', 'textbox')); $docPart = $isCellTextrun ? $this->getDocPart() : $this->container; $docPartId = $isCellTextrun ? $this->getDocPartId() : $this->sectionId; $inHeaderFooter = ($docPart == 'header' || $docPart == 'footer'); diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index 5ed5209f..a3987b58 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -27,7 +27,11 @@ use PhpOffice\PhpWord\Style; */ abstract class AbstractElement { - + /** + * PhpWord object + * + * @var \PhpOffice\PhpWord\PhpWord + */ protected $phpWord; /** diff --git a/src/PhpWord/Element/Footer.php b/src/PhpWord/Element/Footer.php index 0e5a1975..2f23a3d3 100644 --- a/src/PhpWord/Element/Footer.php +++ b/src/PhpWord/Element/Footer.php @@ -115,21 +115,6 @@ class Footer extends AbstractContainer return $this->type = self::EVEN; } - /** - * Add textbox element - * - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\TextBox - * @todo Merge with the same function on Section - */ - public function addTextBox($style = null) - { - $textbox = new TextBox($this->getDocPart(), $this->getDocPartId(), $style); - $this->addElement($textbox); - - return $textbox; - } - /** * Add table element * diff --git a/src/PhpWord/Element/Section.php b/src/PhpWord/Element/Section.php index 3183a6cb..1ccdccc8 100644 --- a/src/PhpWord/Element/Section.php +++ b/src/PhpWord/Element/Section.php @@ -117,21 +117,6 @@ class Section extends AbstractContainer $this->addElement(new PageBreak()); } - /** - * Add textbox element - * - * @param mixed $style - * @return \PhpOffice\PhpWord\Element\TextBox - * @todo Merge with the same function on Footer - */ - public function addTextBox($style = null) - { - $textbox = new TextBox($this->getDocPart(), $this->getDocPartId(), $style); - $this->addElement($textbox); - - return $textbox; - } - /** * Add table element * diff --git a/src/PhpWord/Element/TextBox.php b/src/PhpWord/Element/TextBox.php index 4cf7b906..1de74649 100644 --- a/src/PhpWord/Element/TextBox.php +++ b/src/PhpWord/Element/TextBox.php @@ -30,7 +30,7 @@ class TextBox extends AbstractContainer * @var \PhpOffice\PhpWord\Style\TextBox */ private $style; - + /** * Create a new textbox * @@ -38,10 +38,9 @@ class TextBox extends AbstractContainer * @param integer $docPartId * @param mixed $style */ - public function __construct($docPart, $docPartId, $style = null) + public function __construct($style = null) { $this->container = 'textbox'; - $this->setDocPart($docPart, $docPartId); $this->style = $this->setStyle(new TextBoxStyle(), $style); } @@ -54,4 +53,4 @@ class TextBox extends AbstractContainer { return $this->style; } -} \ No newline at end of file +} diff --git a/src/PhpWord/Style/TextBox.php b/src/PhpWord/Style/TextBox.php index 7e83da6a..0411e5d9 100644 --- a/src/PhpWord/Style/TextBox.php +++ b/src/PhpWord/Style/TextBox.php @@ -20,163 +20,29 @@ namespace PhpOffice\PhpWord\Style; /** * TextBox style */ -class TextBox extends AbstractStyle +class TextBox extends Image { - - /** - * Wrapping styles - * - * @const string - */ - const WRAPPING_STYLE_INLINE = 'inline'; - const WRAPPING_STYLE_SQUARE = 'square'; - const WRAPPING_STYLE_TIGHT = 'tight'; - const WRAPPING_STYLE_BEHIND = 'behind'; - const WRAPPING_STYLE_INFRONT = 'infront'; - - /** - * Horizontal alignment - * - * @const string - */ - const POSITION_HORIZONTAL_LEFT = 'left'; - const POSITION_HORIZONTAL_CENTER = 'center'; - const POSITION_HORIZONTAL_RIGHT = 'right'; - - /** - * Vertical alignment - * - * @const string - */ - const POSITION_VERTICAL_TOP = 'top'; - const POSITION_VERTICAL_CENTER = 'center'; - const POSITION_VERTICAL_BOTTOM = 'bottom'; - const POSITION_VERTICAL_INSIDE = 'inside'; - const POSITION_VERTICAL_OUTSIDE = 'outside'; - - /** - * Position relative to - * - * @const string - */ - const POSITION_RELATIVE_TO_MARGIN = 'margin'; - const POSITION_RELATIVE_TO_PAGE = 'page'; - const POSITION_RELATIVE_TO_COLUMN = 'column'; - const POSITION_RELATIVE_TO_CHAR = 'char'; - const POSITION_RELATIVE_TO_LMARGIN = 'left-margin-area'; - const POSITION_RELATIVE_TO_RMARGIN = 'right-margin-area'; - const POSITION_RELATIVE_TO_IMARGIN = 'inner-margin-area'; - const POSITION_RELATIVE_TO_OMARGIN = 'outer-margin-area'; - const POSITION_RELATIVE_TO_LINE = 'line'; - const POSITION_RELATIVE_TO_TMARGIN = 'top-margin-area'; - const POSITION_RELATIVE_TO_BMARGIN = 'bottom-margin-area'; - - /** - * Position type, relative/absolute - * - * @const string - */ - const POSITION_RELATIVE = 'relative'; - const POSITION_ABSOLUTE = 'absolute'; - - /** - * TextBox width - * - * @var int - */ - private $width; - - /** - * TextBox height - * - * @var int - */ - private $height; - - /** - * Alignment - * - * @var string - */ - private $align; - - /** - * Margin Top - * - * @var int - */ - private $marginTop; - - /** - * Margin Left - * - * @var int - */ - private $marginLeft; - - /** - * Wrapping style - * - * @var string - */ - private $wrappingStyle; - - /** - * Positioning type (relative or absolute) - * - * @var string - */ - private $positioning; - - /** - * Horizontal alignment - * - * @var string - */ - private $posHorizontal; - - /** - * Horizontal Relation - * - * @var string - */ - private $posHorizontalRel; - - /** - * Vertical alignment - * - * @var string - */ - private $posVertical; - - /** - * Vertical Relation - * - * @var string - */ - private $posVerticalRel; - /** * margin top * * @var int */ private $innerMarginTop = null; - + /** * margin left * * @var int */ private $innerMarginLeft = null; - + /** * margin right * * @var int */ private $innerMarginRight = null; - + /** * Cell margin bottom * @@ -186,7 +52,7 @@ class TextBox extends AbstractStyle /** * border size - * + * * @var int */ private $borderSize = null; @@ -197,305 +63,7 @@ class TextBox extends AbstractStyle * @var string */ private $borderColor; - - /** - * Create new textbox style - */ - public function __construct() - { - $this->setWrappingStyle(self::WRAPPING_STYLE_INLINE); - $this->setPosHorizontal(self::POSITION_HORIZONTAL_LEFT); - $this->setPosHorizontalRel(self::POSITION_RELATIVE_TO_CHAR); - $this->setPosVertical(self::POSITION_VERTICAL_TOP); - $this->setPosVerticalRel(self::POSITION_RELATIVE_TO_LINE); - } - /** - * Get width - */ - public function getWidth() - { - return $this->width; - } - - /** - * Set width - * - * @param int $value - */ - public function setWidth($value = null) - { - $this->width = $value; - } - - /** - * Get height - */ - public function getHeight() - { - return $this->height; - } - - /** - * Set height - * - * @param int $value - */ - public function setHeight($value = null) - { - $this->height = $value; - } - - /** - * Get alignment - */ - public function getAlign() - { - return $this->align; - } - - /** - * Set alignment - * - * @param string $value - */ - public function setAlign($value = null) - { - $this->align = $value; - } - - /** - * Get Margin Top - * - * @return int - */ - public function getMarginTop() - { - return $this->marginTop; - } - - /** - * Set Margin Top - * - * @param int $value - * @return self - */ - public function setMarginTop($value = null) - { - $this->marginTop = $value; - return $this; - } - - /** - * Get Margin Left - * - * @return int - */ - public function getMarginLeft() - { - return $this->marginLeft; - } - - /** - * Set Margin Left - * - * @param int $value - * @return self - */ - public function setMarginLeft($value = null) - { - $this->marginLeft = $value; - return $this; - } - - /** - * Get wrapping style - * - * @return string - */ - public function getWrappingStyle() - { - return $this->wrappingStyle; - } - - /** - * Set wrapping style - * - * @param string $wrappingStyle - * @throws \InvalidArgumentException - * @return self - */ - public function setWrappingStyle($wrappingStyle) - { - $enum = array(self::WRAPPING_STYLE_INLINE, self::WRAPPING_STYLE_INFRONT, self::WRAPPING_STYLE_BEHIND, - self::WRAPPING_STYLE_SQUARE, self::WRAPPING_STYLE_TIGHT); - - if (in_array($wrappingStyle, $enum)) { - $this->wrappingStyle = $wrappingStyle; - } else { - throw new \InvalidArgumentException('Invalid wrapping style.'); - } - - return $this; - } - - /** - * Get positioning type - * - * @return string - */ - public function getPositioning() - { - return $this->positioning; - } - - /** - * Set positioning type - * - * @param string $positioning - * @throws \InvalidArgumentException - * @return self - */ - public function setPositioning($positioning) - { - $enum = array(self::POSITION_RELATIVE, self::POSITION_ABSOLUTE); - - if (in_array($positioning, $enum)) { - $this->positioning = $positioning; - } else { - throw new \InvalidArgumentException('Invalid positioning.'); - } - - return $this; - } - - /** - * Get horizontal alignment - * - * @return string - */ - public function getPosHorizontal() - { - return $this->posHorizontal; - } - - /** - * Set horizontal alignment - * - * @param string $alignment - * @throws \InvalidArgumentException - * @return self - */ - public function setPosHorizontal($alignment) - { - $enum = array(self::POSITION_HORIZONTAL_LEFT, self::POSITION_HORIZONTAL_CENTER, - self::POSITION_HORIZONTAL_RIGHT); - - if (in_array($alignment, $enum)) { - $this->posHorizontal = $alignment; - } else { - throw new \InvalidArgumentException('Invalid horizontal alignment.'); - } - - return $this; - } - - /** - * Get vertical alignment - * - * @return string - */ - public function getPosVertical() - { - return $this->posVertical; - } - - /** - * Set vertical alignment - * - * @param string $alignment - * @throws \InvalidArgumentException - * @return self - */ - public function setPosVertical($alignment) - { - $enum = array(self::POSITION_VERTICAL_TOP, self::POSITION_VERTICAL_CENTER, - self::POSITION_VERTICAL_BOTTOM, self::POSITION_VERTICAL_INSIDE, self::POSITION_VERTICAL_OUTSIDE); - - if (in_array($alignment, $enum)) { - $this->posVertical = $alignment; - } else { - throw new \InvalidArgumentException('Invalid vertical alignment.'); - } - - return $this; - } - - /** - * Get horizontal relation - * - * @return string - */ - public function getPosHorizontalRel() - { - return $this->posHorizontalRel; - } - - /** - * Set horizontal relation - * - * @param string $relto - * @throws \InvalidArgumentException - * @return self - */ - public function setPosHorizontalRel($relto) - { - $enum = array(self::POSITION_RELATIVE_TO_MARGIN, self::POSITION_RELATIVE_TO_PAGE, - self::POSITION_RELATIVE_TO_COLUMN, self::POSITION_RELATIVE_TO_CHAR, - self::POSITION_RELATIVE_TO_LMARGIN, self::POSITION_RELATIVE_TO_RMARGIN, - self::POSITION_RELATIVE_TO_IMARGIN, self::POSITION_RELATIVE_TO_OMARGIN); - - if (in_array($relto, $enum)) { - $this->posHorizontalRel = $relto; - } else { - throw new \InvalidArgumentException('Invalid relative horizontal alignment.'); - } - - return $this; - } - - /** - * Get vertical relation - * - * @return string - */ - public function getPosVerticalRel() - { - return $this->posVerticalRel; - } - - /** - * Set vertical relation - * - * @param string $relto - * @throws \InvalidArgumentException - * @return self - */ - public function setPosVerticalRel($relto) - { - $enum = array(self::POSITION_RELATIVE_TO_MARGIN, self::POSITION_RELATIVE_TO_PAGE, - self::POSITION_RELATIVE_TO_LINE, - self::POSITION_RELATIVE_TO_TMARGIN, self::POSITION_RELATIVE_TO_BMARGIN, - self::POSITION_RELATIVE_TO_IMARGIN, self::POSITION_RELATIVE_TO_OMARGIN); - - if (in_array($relto, $enum)) { - $this->posVerticalRel = $relto; - } else { - throw new \InvalidArgumentException('Invalid relative vertical alignment.'); - } - - return $this; - } /** * Set margin top * @@ -505,7 +73,7 @@ class TextBox extends AbstractStyle { $this->innerMarginTop = $value; } - + /** * Get margin top * @@ -515,7 +83,7 @@ class TextBox extends AbstractStyle { return $this->innerMarginTop; } - + /** * Set margin left * @@ -525,7 +93,7 @@ class TextBox extends AbstractStyle { $this->innerMarginLeft = $value; } - + /** * Get margin left * @@ -535,7 +103,7 @@ class TextBox extends AbstractStyle { return $this->innerMarginLeft; } - + /** * Set margin right * @@ -545,7 +113,7 @@ class TextBox extends AbstractStyle { $this->innerMarginRight = $value; } - + /** * Get margin right * @@ -555,7 +123,7 @@ class TextBox extends AbstractStyle { return $this->innerMarginRight; } - + /** * Set margin bottom * @@ -565,7 +133,7 @@ class TextBox extends AbstractStyle { $this->innerMarginBottom = $value; } - + /** * Get margin bottom * @@ -575,7 +143,7 @@ class TextBox extends AbstractStyle { return $this->innerMarginBottom; } - + /** * Set TLRB cell margin * @@ -588,7 +156,7 @@ class TextBox extends AbstractStyle $this->setInnerMarginRight($value); $this->setInnerMarginBottom($value); } - + /** * Get cell margin * @@ -598,20 +166,20 @@ class TextBox extends AbstractStyle { return array($this->innerMarginLeft, $this->innerMarginTop, $this->innerMarginRight, $this->innerMarginBottom); } - + /** * Set border size - * + * * @param int $value Size in points */ public function setBorderSize($value = null) { $this->borderSize = $value; } - + /** * Get border size - * + * * @return int */ public function getBorderSize() @@ -621,21 +189,21 @@ class TextBox extends AbstractStyle /** * Set border color - * + * * @param string $value */ public function setBorderColor($value = null) { $this->borderColor = $value; } - + /** * Get border color - * + * * @return string */ public function getBorderColor() { return $this->borderColor; } -} \ No newline at end of file +} diff --git a/src/PhpWord/Writer/Word2007/Element/TextBox.php b/src/PhpWord/Writer/Word2007/Element/TextBox.php index 812d2218..fd1683ae 100644 --- a/src/PhpWord/Writer/Word2007/Element/TextBox.php +++ b/src/PhpWord/Writer/Word2007/Element/TextBox.php @@ -47,26 +47,28 @@ class TextBox extends Element $this->xmlWriter->endElement(); // w:pPr } } - + $this->xmlWriter->startElement('w:r'); $this->xmlWriter->startElement('w:pict'); $this->xmlWriter->startElement('v:shape'); $this->xmlWriter->writeAttribute('type', '#_x0000_t0202'); $styleWriter->write(); $this->xmlWriter->startElement('v:textbox'); - $margins=implode(', ',$tbxStyle->getInnerMargin()); + $margins = implode(', ', $tbxStyle->getInnerMargin()); $this->xmlWriter->writeAttribute('inset', $margins); $this->xmlWriter->startElement('w:txbxContent'); + $this->xmlWriter->startElement('w:p'); $this->parentWriter->writeContainerElements($this->xmlWriter, $this->element); + $this->xmlWriter->endElement(); // w:p $this->xmlWriter->endElement(); // w:txbxContent $this->xmlWriter->endElement(); // v: textbox $styleWriter->writeW10Wrap(); $this->xmlWriter->endElement(); // v:shape $this->xmlWriter->endElement(); // w:pict $this->xmlWriter->endElement(); // w:r - + if (!$this->withoutP) { $this->xmlWriter->endElement(); // w:p } } -} \ No newline at end of file +} diff --git a/src/PhpWord/Writer/Word2007/Part/AbstractPart.php b/src/PhpWord/Writer/Word2007/Part/AbstractPart.php index 84310752..d1717e9b 100644 --- a/src/PhpWord/Writer/Word2007/Part/AbstractPart.php +++ b/src/PhpWord/Writer/Word2007/Part/AbstractPart.php @@ -97,7 +97,7 @@ abstract class AbstractPart 'Header' => array_merge($elmMainCell, array('Table', 'PreserveText', 'TextBox')), 'Footer' => array_merge($elmMainCell, array('Table', 'PreserveText', 'TextBox')), 'Cell' => array_merge($elmMainCell, array('PreserveText', 'Footnote', 'Endnote')), - 'TextBox' => array_merge($elmMainCell, array('PreserveText', 'Footnote', 'Endnote')), + 'TextBox' => array_merge($elmMainCell, array('PreserveText', 'Footnote', 'Endnote')), 'TextRun' => array_merge($elmCommon, array('Footnote', 'Endnote')), 'Footnote' => $elmCommon, 'Endnote' => $elmCommon, @@ -110,7 +110,7 @@ abstract class AbstractPart // Loop through elements $elements = $container->getElements(); - $withoutP = in_array($containerName, array('TextRun', 'Footnote', 'Endnote')) ? true : false; + $withoutP = in_array($containerName, array('TextRun', 'Footnote', 'Endnote', 'TextBox')) ? true : false; if (count($elements) > 0) { foreach ($elements as $element) { if ($element instanceof AbstractElement) { diff --git a/src/PhpWord/Writer/Word2007/Style/TextBox.php b/src/PhpWord/Writer/Word2007/Style/TextBox.php index 6720279e..18c8a60f 100644 --- a/src/PhpWord/Writer/Word2007/Style/TextBox.php +++ b/src/PhpWord/Writer/Word2007/Style/TextBox.php @@ -93,7 +93,7 @@ class TextBox extends AbstractStyle if ($borderSize !== null) { $this->xmlWriter->writeAttribute('strokeweight', $this->style->getBorderSize().'pt'); } - + $borderColor = $this->style->getBorderColor(); if (empty($borderColor)) { $this->xmlWriter->writeAttribute('stroked', 'f'); @@ -101,7 +101,7 @@ class TextBox extends AbstractStyle $this->xmlWriter->writeAttribute('strokecolor', $borderColor); } //@todo - + } /** @@ -114,7 +114,7 @@ class TextBox extends AbstractStyle if (!is_null($this->w10wrap)) { $this->xmlWriter->startElement('w10:wrap'); $this->xmlWriter->writeAttribute('type', $this->w10wrap); - + switch ($this->style->getPositioning()) { case TextBoxStyle::POSITION_ABSOLUTE: $this->xmlWriter->writeAttribute('anchorx', "page"); @@ -150,7 +150,7 @@ class TextBox extends AbstractStyle break; } } - + $this->xmlWriter->endElement(); // w10:wrap } } diff --git a/tests/PhpWord/Tests/Element/TextBoxTest.php b/tests/PhpWord/Tests/Element/TextBoxTest.php index a706c5a2..c3c89ed4 100644 --- a/tests/PhpWord/Tests/Element/TextBoxTest.php +++ b/tests/PhpWord/Tests/Element/TextBoxTest.php @@ -32,8 +32,8 @@ class TextBoxTest extends \PHPUnit_Framework_TestCase */ public function testConstruct() { - $oTextBox = new TextBox('section', 1); - + $oTextBox = new TextBox(); + $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\TextBox', $oTextBox); $this->assertEquals($oTextBox->getStyle(), null); } @@ -43,19 +43,17 @@ class TextBoxTest extends \PHPUnit_Framework_TestCase */ public function testStyleText() { - $oTextBox = new TextBox('section', 1, 'textBoxStyle'); - + $oTextBox = new TextBox('textBoxStyle'); + $this->assertEquals($oTextBox->getStyle(), 'textBoxStyle'); } - + /** * Get style array */ public function testStyleArray() { $oTextBox = new TextBox( - 'section', - 1, array( 'width' => \PhpOffice\PhpWord\Shared\Drawing::centimetersToPixels(4.5), 'height' => \PhpOffice\PhpWord\Shared\Drawing::centimetersToPixels(17.5), @@ -68,7 +66,7 @@ class TextBoxTest extends \PHPUnit_Framework_TestCase 'borderColor' => '' ) ); - + $this->assertInstanceOf('PhpOffice\\PhpWord\\Style\\TextBox', $oTextBox->getStyle()); } }