From 39d4e8ee54f046a48e8a9ee098400be81489de11 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Sun, 18 May 2014 22:23:28 +0700 Subject: [PATCH] Bugfix #150: Page break adds new line in the beginning of the new page --- CHANGELOG.md | 1 + .../Word2007/Element/AbstractElement.php | 27 +++++++++++++++++++ .../Writer/Word2007/Element/Container.php | 25 +++++++++++++---- .../Writer/Word2007/Element/PageBreak.php | 12 ++++++--- src/PhpWord/Writer/Word2007/Element/Text.php | 10 ++++++- src/PhpWord/Writer/Word2007/Part/Settings.php | 2 ++ 6 files changed, 67 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0614611..7949017f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3; new r - Header: All images added to the second header were assigned to the first header - @basjan GH-222 - Conversion: Fix conversion from cm to pixel, pixel to cm, and pixel to point - @basjan GH-233 GH-234 +- PageBreak: Page break adds new line in the beginning of the new page - @ivanlanin GH-150 ### Deprecated diff --git a/src/PhpWord/Writer/Word2007/Element/AbstractElement.php b/src/PhpWord/Writer/Word2007/Element/AbstractElement.php index 82465afe..52b4c62e 100644 --- a/src/PhpWord/Writer/Word2007/Element/AbstractElement.php +++ b/src/PhpWord/Writer/Word2007/Element/AbstractElement.php @@ -49,6 +49,13 @@ abstract class AbstractElement */ protected $withoutP = false; + /** + * Has page break before + * + * @var bool + */ + private $pageBreakBefore = false; + /** * Write element */ @@ -88,6 +95,26 @@ abstract class AbstractElement return $this->element; } + /** + * Has page break before + * + * @return bool + */ + public function hasPageBreakBefore() + { + return $this->pageBreakBefore; + } + + /** + * Set page break before + * + * @param bool $value + */ + public function setPageBreakBefore($value = true) + { + $this->pageBreakBefore = (bool)$value; + } + /** * Convert text to valid format * diff --git a/src/PhpWord/Writer/Word2007/Element/Container.php b/src/PhpWord/Writer/Word2007/Element/Container.php index e16a0e6d..7d1c8104 100644 --- a/src/PhpWord/Writer/Word2007/Element/Container.php +++ b/src/PhpWord/Writer/Word2007/Element/Container.php @@ -51,18 +51,33 @@ class Container extends AbstractElement $elements = $container->getElements(); $elementClass = ''; foreach ($elements as $element) { - $elementClass = get_class($element); - $writerClass = str_replace('PhpOffice\\PhpWord\\Element', $this->namespace, $elementClass); + $elementClass = substr(get_class($element), strrpos(get_class($element), '\\') + 1); + $writerClass = $this->namespace . '\\' . $elementClass; + + // Check it's a page break. No need to write it, instead, flag containers' pageBreakBefore + // to be assigned to the next element + if ($elementClass == 'PageBreak') { + $this->setPageBreakBefore(true); + continue; + } if (class_exists($writerClass)) { + // Get container's page break before and reset it + $pageBreakBefore = $this->hasPageBreakBefore(); + $this->setPageBreakBefore(false); + + /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */ $writer = new $writerClass($xmlWriter, $element, $withoutP); + $writer->setPageBreakBefore($pageBreakBefore); $writer->write(); } } - // Special case for Cell: They have to contain a w:p element at the end + // Special case for Cell: They have to contain a w:p element at the end. The $elementClass contains + // the last element name. If it's empty string or Table, the last element is not w:p if ($containerClass == 'Cell') { - if ($elementClass == '' || $elementClass == 'PhpOffice\\PhpWord\\Element\\Table') { - $writerClass = "{$this->namespace}\\TextBreak"; + if ($elementClass == '' || $elementClass == 'Table') { + $writerClass = $this->namespace . '\\TextBreak'; + /** @var \PhpOffice\PhpWord\Writer\Word2007\Element\AbstractElement $writer Type hint */ $writer = new $writerClass($xmlWriter, new TextBreakElement(), $withoutP); $writer->write(); } diff --git a/src/PhpWord/Writer/Word2007/Element/PageBreak.php b/src/PhpWord/Writer/Word2007/Element/PageBreak.php index fb285ac6..6974777a 100644 --- a/src/PhpWord/Writer/Word2007/Element/PageBreak.php +++ b/src/PhpWord/Writer/Word2007/Element/PageBreak.php @@ -20,23 +20,27 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Element; /** * PageBreak element writer * + * Originally, page break is rendered as a `w:p`, but this turns out to produce bug #150. + * As of 0.11.0, page break is rendered as a `w:r` with `w:br` type "page" and `w:lastRenderedPageBreak` + * * @since 0.10.0 */ class PageBreak extends AbstractElement { /** * Write element + * + * @usedby \PhpOffice\PhpWord\Writer\Word2007\Element\Text::writeOpeningWP() */ public function write() { $xmlWriter = $this->getXmlWriter(); - $xmlWriter->startElement('w:p'); $xmlWriter->startElement('w:r'); $xmlWriter->startElement('w:br'); $xmlWriter->writeAttribute('w:type', 'page'); - $xmlWriter->endElement(); - $xmlWriter->endElement(); - $xmlWriter->endElement(); + $xmlWriter->endElement(); // w:br + $xmlWriter->writeElement('w:lastRenderedPageBreak'); + $xmlWriter->endElement(); // w:r } } diff --git a/src/PhpWord/Writer/Word2007/Element/Text.php b/src/PhpWord/Writer/Word2007/Element/Text.php index 87a56dd2..64c4b766 100644 --- a/src/PhpWord/Writer/Word2007/Element/Text.php +++ b/src/PhpWord/Writer/Word2007/Element/Text.php @@ -17,6 +17,7 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Element; +use PhpOffice\PhpWord\Element\PageBreak as PageBreakElement; use PhpOffice\PhpWord\Writer\Word2007\Style\Font as FontStyleWriter; use PhpOffice\PhpWord\Writer\Word2007\Style\Paragraph as ParagraphStyleWriter; @@ -55,6 +56,8 @@ class Text extends AbstractElement /** * Write opening + * + * @uses \PhpOffice\PhpWord\Writer\Word2007\Element\PageBreak::write() */ protected function writeOpeningWP() { @@ -63,10 +66,15 @@ class Text extends AbstractElement if (!$this->withoutP) { $xmlWriter->startElement('w:p'); - + // Paragraph style if (method_exists($element, 'getParagraphStyle')) { $this->writeParagraphStyle(); } + // PageBreak + if ($this->hasPageBreakBefore()) { + $elementWriter = new PageBreak($xmlWriter, new PageBreakElement()); + $elementWriter->write(); + } } } diff --git a/src/PhpWord/Writer/Word2007/Part/Settings.php b/src/PhpWord/Writer/Word2007/Part/Settings.php index 80a1b427..784a5d1e 100644 --- a/src/PhpWord/Writer/Word2007/Part/Settings.php +++ b/src/PhpWord/Writer/Word2007/Part/Settings.php @@ -19,6 +19,8 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Part; /** * Word2007 settings part writer: word/settings.xml + * + * @link http://www.schemacentral.com/sc/ooxml/t-w_CT_Settings.html */ class Settings extends AbstractPart {