diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index c8fe57cf..291a6d60 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -1,3 +1,8 @@
+build:
+ nodes:
+ analysis:
+ tests:
+ override: [php-scrutinizer-run]
filter:
excluded_paths: [ 'vendor/*', 'tests/*', 'samples/*', 'src/PhpWord/Shared/PCLZip/*' ]
diff --git a/.travis.yml b/.travis.yml
index d63b7bb2..281c2630 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,12 +15,9 @@ matrix:
include:
- php: 5.6
env: COVERAGE=1
- allow_failures:
- - php: 7.2
cache:
directories:
- - vendor
- $HOME/.composer/cache
- .php-cs.cache
@@ -38,7 +35,7 @@ before_script:
- if [ -z "$COVERAGE" ]; then phpenv config-rm xdebug.ini ; fi
## Composer
- composer self-update
- - composer install --prefer-source
+ - travis_wait composer install --prefer-source
## PHPDocumentor
- mkdir -p build/docs
- mkdir -p build/coverage
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c684a37d..7f527746 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ v0.15.0 (?? ??? 2018)
- Fix parsing of `` tag. @troosan #1274
- Bookmark are not writton as internal link in html writer @troosan #1263
- It should be possible to add a Footnote in a ListItemRun @troosan #1287 #1287
+- Fix parsing of Heading and Title formating @troosan @gthomas2 #465
### Changed
- Remove zend-stdlib dependency @Trainmaster #1284
diff --git a/docs/elements.rst b/docs/elements.rst
index d13abc56..4d1b9383 100644
--- a/docs/elements.rst
+++ b/docs/elements.rst
@@ -89,6 +89,7 @@ Titles
If you want to structure your document or build table of contents, you need titles or headings.
To add a title to the document, use the ``addTitleStyle`` and ``addTitle`` method.
+If `depth` is 0, a Title will be inserted, otherwise a Heading1, Heading2, ...
.. code-block:: php
@@ -98,7 +99,7 @@ To add a title to the document, use the ``addTitleStyle`` and ``addTitle`` metho
- ``depth``.
- ``$fontStyle``. See :ref:`font-style`.
- ``$paragraphStyle``. See :ref:`paragraph-style`.
-- ``$text``. Text to be displayed in the document.
+- ``$text``. Text to be displayed in the document. This can be `string` or a `\PhpOffice\PhpWord\Element\TextRun`
It's necessary to add a title style to your document because otherwise the title won't be detected as a real title.
diff --git a/samples/Sample_17_TitleTOC.php b/samples/Sample_17_TitleTOC.php
index f99b73ea..86e8e28c 100644
--- a/samples/Sample_17_TitleTOC.php
+++ b/samples/Sample_17_TitleTOC.php
@@ -12,13 +12,14 @@ $section = $phpWord->addSection();
// Define styles
$fontStyle12 = array('spaceAfter' => 60, 'size' => 12);
$fontStyle10 = array('size' => 10);
+$phpWord->addTitleStyle(null, array('size' => 22, 'bold' => true));
$phpWord->addTitleStyle(1, array('size' => 20, 'color' => '333333', 'bold' => true));
$phpWord->addTitleStyle(2, array('size' => 16, 'color' => '666666'));
$phpWord->addTitleStyle(3, array('size' => 14, 'italic' => true));
$phpWord->addTitleStyle(4, array('size' => 12));
// Add text elements
-$section->addText('Table of contents 1');
+$section->addTitle('Table of contents 1', 0);
$section->addTextBreak(2);
// Add TOC #1
diff --git a/src/PhpWord/Collection/AbstractCollection.php b/src/PhpWord/Collection/AbstractCollection.php
index 61709a50..d49967ca 100644
--- a/src/PhpWord/Collection/AbstractCollection.php
+++ b/src/PhpWord/Collection/AbstractCollection.php
@@ -27,14 +27,14 @@ abstract class AbstractCollection
/**
* Items
*
- * @var array
+ * @var \PhpOffice\PhpWord\Element\AbstractContainer[]
*/
private $items = array();
/**
* Get items
*
- * @return array
+ * @return \PhpOffice\PhpWord\Element\AbstractContainer[]
*/
public function getItems()
{
@@ -45,7 +45,7 @@ abstract class AbstractCollection
* Get item by index
*
* @param int $index
- * @return mixed
+ * @return \PhpOffice\PhpWord\Element\AbstractContainer
*/
public function getItem($index)
{
@@ -60,7 +60,7 @@ abstract class AbstractCollection
* Set item.
*
* @param int $index
- * @param mixed $item
+ * @param \PhpOffice\PhpWord\Element\AbstractContainer $item
*/
public function setItem($index, $item)
{
@@ -72,7 +72,7 @@ abstract class AbstractCollection
/**
* Add new item
*
- * @param mixed $item
+ * @param \PhpOffice\PhpWord\Element\AbstractContainer $item
* @return int
*/
public function addItem($item)
diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php
index 507ff143..1cedbef0 100644
--- a/src/PhpWord/Element/AbstractContainer.php
+++ b/src/PhpWord/Element/AbstractContainer.php
@@ -54,7 +54,7 @@ abstract class AbstractContainer extends AbstractElement
/**
* Elements collection
*
- * @var array
+ * @var \PhpOffice\PhpWord\Element\AbstractElement[]
*/
protected $elements = array();
@@ -164,6 +164,41 @@ abstract class AbstractContainer extends AbstractElement
return $this->elements;
}
+ /**
+ * Returns the element at the requested position
+ *
+ * @param int $index
+ * @return \PhpOffice\PhpWord\Element\AbstractElement|null
+ */
+ public function getElement($index)
+ {
+ if (array_key_exists($index, $this->elements)) {
+ return $this->elements[$index];
+ }
+
+ return null;
+ }
+
+ /**
+ * Removes the element at requested index
+ *
+ * @param int|\PhpOffice\PhpWord\Element\AbstractElement $toRemove
+ */
+ public function removeElement($toRemove)
+ {
+ if (is_int($toRemove) && array_key_exists($toRemove, $this->elements)) {
+ unset($this->elements[$toRemove]);
+ } elseif ($toRemove instanceof \PhpOffice\PhpWord\Element\AbstractElement) {
+ foreach ($this->elements as $key => $element) {
+ if ($element->getElementId() === $toRemove->getElementId()) {
+ unset($this->elements[$key]);
+
+ return;
+ }
+ }
+ }
+ }
+
/**
* Count elements
*
diff --git a/src/PhpWord/Element/Bookmark.php b/src/PhpWord/Element/Bookmark.php
index 2eceb5ed..8d4e0af5 100644
--- a/src/PhpWord/Element/Bookmark.php
+++ b/src/PhpWord/Element/Bookmark.php
@@ -43,7 +43,7 @@ class Bookmark extends AbstractElement
*
* @param string $name
*/
- public function __construct($name)
+ public function __construct($name = '')
{
$this->name = CommonText::toUTF8($name);
}
diff --git a/src/PhpWord/Element/ListItem.php b/src/PhpWord/Element/ListItem.php
index 7f665b1b..cb55c5ae 100644
--- a/src/PhpWord/Element/ListItem.php
+++ b/src/PhpWord/Element/ListItem.php
@@ -62,7 +62,7 @@ class ListItem extends AbstractElement
// 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);
+ $this->style = new ListItemStyle($listStyle); // @codeCoverageIgnore
} else {
$this->style = $this->setNewStyle(new ListItemStyle(), $listStyle, true);
}
diff --git a/src/PhpWord/Element/Title.php b/src/PhpWord/Element/Title.php
index 808af55e..ed06fa13 100644
--- a/src/PhpWord/Element/Title.php
+++ b/src/PhpWord/Element/Title.php
@@ -28,7 +28,7 @@ class Title extends AbstractElement
/**
* Title Text content
*
- * @var string
+ * @var string|TextRun
*/
private $text;
@@ -56,15 +56,25 @@ class Title extends AbstractElement
/**
* Create a new Title Element
*
- * @param string $text
+ * @param string|TextRun $text
* @param int $depth
*/
public function __construct($text, $depth = 1)
{
- $this->text = CommonText::toUTF8($text);
+ if (isset($text)) {
+ if (is_string($text)) {
+ $this->text = CommonText::toUTF8($text);
+ } elseif ($text instanceof TextRun) {
+ $this->text = $text;
+ } else {
+ throw new \InvalidArgumentException('Invalid text, should be a string or a TextRun');
+ }
+ }
+
$this->depth = $depth;
- if (array_key_exists("Heading_{$this->depth}", Style::getStyles())) {
- $this->style = "Heading{$this->depth}";
+ $styleName = $depth === 0 ? 'Title' : "Heading_{$this->depth}";
+ if (array_key_exists($styleName, Style::getStyles())) {
+ $this->style = str_replace('_', '', $styleName);
}
return $this;
diff --git a/src/PhpWord/PhpWord.php b/src/PhpWord/PhpWord.php
index d7c2348a..54ef65ac 100644
--- a/src/PhpWord/PhpWord.php
+++ b/src/PhpWord/PhpWord.php
@@ -212,6 +212,21 @@ class PhpWord
return $this->sections;
}
+ /**
+ * Returns the section at the requested position
+ *
+ * @param int $index
+ * @return \PhpOffice\PhpWord\Element\Section|null
+ */
+ public function getSection($index)
+ {
+ if (array_key_exists($index, $this->sections)) {
+ return $this->sections[$index];
+ }
+
+ return null;
+ }
+
/**
* Create new section
*
diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php
index 1d610516..f8a26ddb 100644
--- a/src/PhpWord/Reader/Word2007/AbstractPart.php
+++ b/src/PhpWord/Reader/Word2007/AbstractPart.php
@@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Reader\Word2007;
use PhpOffice\Common\XMLReader;
+use PhpOffice\PhpWord\Element\TextRun;
use PhpOffice\PhpWord\Element\TrackChange;
use PhpOffice\PhpWord\PhpWord;
@@ -103,12 +104,10 @@ abstract class AbstractPart
{
// Paragraph style
$paragraphStyle = null;
- $headingMatches = array();
+ $headingDepth = null;
if ($xmlReader->elementExists('w:pPr', $domNode)) {
$paragraphStyle = $this->readParagraphStyle($xmlReader, $domNode);
- if (is_array($paragraphStyle) && isset($paragraphStyle['styleName'])) {
- preg_match('/Heading(\d)/', $paragraphStyle['styleName'], $headingMatches);
- }
+ $headingDepth = $this->getHeadingDepth($paragraphStyle);
}
// PreserveText
@@ -147,14 +146,19 @@ abstract class AbstractPart
foreach ($nodes as $node) {
$this->readRun($xmlReader, $node, $listItemRun, $docPart, $paragraphStyle);
}
- } elseif (!empty($headingMatches)) {
- // Heading
- $textContent = '';
+ } elseif ($headingDepth !== null) {
+ // Heading or Title
+ $textContent = null;
$nodes = $xmlReader->getElements('w:r', $domNode);
- foreach ($nodes as $node) {
- $textContent .= $xmlReader->getValue('w:t', $node);
+ if ($nodes->length === 1) {
+ $textContent = $xmlReader->getValue('w:t', $nodes->item(0));
+ } else {
+ $textContent = new TextRun($paragraphStyle);
+ foreach ($nodes as $node) {
+ $this->readRun($xmlReader, $node, $textContent, $docPart, $paragraphStyle);
+ }
}
- $parent->addTitle($textContent, $headingMatches[1]);
+ $parent->addTitle($textContent, $headingDepth);
} else {
// Text and TextRun
$runCount = $xmlReader->countElements('w:r', $domNode);
@@ -176,6 +180,29 @@ abstract class AbstractPart
}
}
+ /**
+ * Returns the depth of the Heading, returns 0 for a Title
+ *
+ * @param array $paragraphStyle
+ * @return number|null
+ */
+ private function getHeadingDepth(array $paragraphStyle = null)
+ {
+ if (is_array($paragraphStyle) && isset($paragraphStyle['styleName'])) {
+ if ('Title' === $paragraphStyle['styleName']) {
+ return 0;
+ }
+
+ $headingMatches = array();
+ preg_match('/Heading(\d)/', $paragraphStyle['styleName'], $headingMatches);
+ if (!empty($headingMatches)) {
+ return $headingMatches[1];
+ }
+ }
+
+ return null;
+ }
+
/**
* Read w:r.
*
@@ -212,10 +239,14 @@ abstract class AbstractPart
} else {
if ($xmlReader->elementExists('w:footnoteReference', $domNode)) {
// Footnote
- $parent->addFootnote();
+ $wId = $xmlReader->getAttribute('w:id', $domNode, 'w:footnoteReference');
+ $footnote = $parent->addFootnote();
+ $footnote->setRelationId($wId);
} elseif ($xmlReader->elementExists('w:endnoteReference', $domNode)) {
// Endnote
- $parent->addEndnote();
+ $wId = $xmlReader->getAttribute('w:id', $domNode, 'w:endnoteReference');
+ $endnote = $parent->addEndnote();
+ $endnote->setRelationId($wId);
} elseif ($xmlReader->elementExists('w:pict', $domNode)) {
// Image
$rId = $xmlReader->getAttribute('r:id', $domNode, 'w:pict/v:shape/v:imagedata');
@@ -496,11 +527,9 @@ abstract class AbstractPart
return $possibleAttribute;
}
}
- } else {
- return $attributes;
}
- return null;
+ return $attributes;
}
/**
@@ -578,7 +607,7 @@ abstract class AbstractPart
*/
private function isOn($value = null)
{
- return $value == null || $value == '1' || $value == 'true' || $value == 'on';
+ return $value === null || $value === '1' || $value === 'true' || $value === 'on';
}
/**
diff --git a/src/PhpWord/Reader/Word2007/Footnotes.php b/src/PhpWord/Reader/Word2007/Footnotes.php
index 61988723..b69b2606 100644
--- a/src/PhpWord/Reader/Word2007/Footnotes.php
+++ b/src/PhpWord/Reader/Word2007/Footnotes.php
@@ -48,9 +48,6 @@ class Footnotes extends AbstractPart
*/
public function read(PhpWord $phpWord)
{
- $getMethod = "get{$this->collection}";
- $collection = $phpWord->$getMethod()->getItems();
-
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($this->docFile, $this->xmlFile);
$nodes = $xmlReader->getElements('*');
@@ -60,17 +57,41 @@ class Footnotes extends AbstractPart
$type = $xmlReader->getAttribute('w:type', $node);
// Avoid w:type "separator" and "continuationSeparator"
- // Only look for or without w:type attribute
- if (is_null($type) && isset($collection[$id])) {
- $element = $collection[$id];
- $pNodes = $xmlReader->getElements('w:p/*', $node);
- foreach ($pNodes as $pNode) {
- $this->readRun($xmlReader, $pNode, $element, $this->collection);
+ // Only look for or without w:type attribute, or with w:type = normal
+ if ((is_null($type) || $type === 'normal')) {
+ $element = $this->getElement($phpWord, $id);
+ if ($element !== null) {
+ $pNodes = $xmlReader->getElements('w:p/*', $node);
+ foreach ($pNodes as $pNode) {
+ $this->readRun($xmlReader, $pNode, $element, $this->collection);
+ }
+ $addMethod = "add{$this->element}";
+ $phpWord->$addMethod($element);
}
- $addMethod = "add{$this->element}";
- $phpWord->$addMethod($element);
}
}
}
}
+
+ /**
+ * Searches for the element with the given relationId
+ *
+ * @param PhpWord $phpWord
+ * @param int $relationId
+ * @return \PhpOffice\PhpWord\Element\AbstractContainer|null
+ */
+ private function getElement(PhpWord $phpWord, $relationId)
+ {
+ $getMethod = "get{$this->collection}";
+ $collection = $phpWord->$getMethod()->getItems();
+
+ //not found by key, looping to search by relationId
+ foreach ($collection as $collectionElement) {
+ if ($collectionElement->getRelationId() == $relationId) {
+ return $collectionElement;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/PhpWord/Style.php b/src/PhpWord/Style.php
index 1939aaba..017b3290 100644
--- a/src/PhpWord/Style.php
+++ b/src/PhpWord/Style.php
@@ -95,7 +95,13 @@ class Style
*/
public static function addTitleStyle($depth, $fontStyle, $paragraphStyle = null)
{
- return self::setStyleValues("Heading_{$depth}", new Font('title', $paragraphStyle), $fontStyle);
+ if ($depth == null) {
+ $styleName = 'Title';
+ } else {
+ $styleName = "Heading_{$depth}";
+ }
+
+ return self::setStyleValues($styleName, new Font('title', $paragraphStyle), $fontStyle);
}
/**
diff --git a/src/PhpWord/Writer/Word2007/Element/Title.php b/src/PhpWord/Writer/Word2007/Element/Title.php
index f204ab16..80c0904d 100644
--- a/src/PhpWord/Writer/Word2007/Element/Title.php
+++ b/src/PhpWord/Writer/Word2007/Element/Title.php
@@ -47,27 +47,36 @@ class Title extends AbstractElement
$xmlWriter->endElement();
}
- $rId = $element->getRelationId();
- $bookmarkRId = $element->getPhpWord()->addBookmark();
+ if ($element->getDepth() !== 0) {
+ $rId = $element->getRelationId();
+ $bookmarkRId = $element->getPhpWord()->addBookmark();
- // Bookmark start for TOC
- $xmlWriter->startElement('w:bookmarkStart');
- $xmlWriter->writeAttribute('w:id', $bookmarkRId);
- $xmlWriter->writeAttribute('w:name', "_Toc{$rId}");
- $xmlWriter->endElement();
+ // Bookmark start for TOC
+ $xmlWriter->startElement('w:bookmarkStart');
+ $xmlWriter->writeAttribute('w:id', $bookmarkRId);
+ $xmlWriter->writeAttribute('w:name', "_Toc{$rId}");
+ $xmlWriter->endElement(); //w:bookmarkStart
+ }
// Actual text
- $xmlWriter->startElement('w:r');
- $xmlWriter->startElement('w:t');
- $this->writeText($this->getText($element->getText()));
- $xmlWriter->endElement(); // w:t
- $xmlWriter->endElement(); // w:r
+ $text = $element->getText();
+ if (is_string($text)) {
+ $xmlWriter->startElement('w:r');
+ $xmlWriter->startElement('w:t');
+ $this->writeText($text);
+ $xmlWriter->endElement(); // w:t
+ $xmlWriter->endElement(); // w:r
+ } elseif ($text instanceof \PhpOffice\PhpWord\Element\AbstractContainer) {
+ $containerWriter = new Container($xmlWriter, $text);
+ $containerWriter->write();
+ }
- // Bookmark end
- $xmlWriter->startElement('w:bookmarkEnd');
- $xmlWriter->writeAttribute('w:id', $bookmarkRId);
- $xmlWriter->endElement();
-
- $xmlWriter->endElement();
+ if ($element->getDepth() !== 0) {
+ // Bookmark end
+ $xmlWriter->startElement('w:bookmarkEnd');
+ $xmlWriter->writeAttribute('w:id', $bookmarkRId);
+ $xmlWriter->endElement(); //w:bookmarkEnd
+ }
+ $xmlWriter->endElement(); //w:p
}
}
diff --git a/src/PhpWord/Writer/Word2007/Part/Styles.php b/src/PhpWord/Writer/Word2007/Part/Styles.php
index 1cc94806..03855f03 100644
--- a/src/PhpWord/Writer/Word2007/Part/Styles.php
+++ b/src/PhpWord/Writer/Word2007/Part/Styles.php
@@ -180,9 +180,15 @@ class Styles extends AbstractPart
// Heading style
if ($styleType == 'title') {
$arrStyle = explode('_', $styleName);
- $styleId = 'Heading' . $arrStyle[1];
- $styleName = 'heading ' . $arrStyle[1];
- $styleLink = 'Heading' . $arrStyle[1] . 'Char';
+ if (count($arrStyle) > 1) {
+ $styleId = 'Heading' . $arrStyle[1];
+ $styleName = 'heading ' . $arrStyle[1];
+ $styleLink = 'Heading' . $arrStyle[1] . 'Char';
+ } else {
+ $styleId = $styleName;
+ $styleName = strtolower($styleName);
+ $styleLink = $styleName . 'Char';
+ }
$xmlWriter->writeAttribute('w:styleId', $styleId);
$xmlWriter->startElement('w:link');
diff --git a/tests/PhpWord/Element/SectionTest.php b/tests/PhpWord/Element/SectionTest.php
index 20f0f0f7..867f680a 100644
--- a/tests/PhpWord/Element/SectionTest.php
+++ b/tests/PhpWord/Element/SectionTest.php
@@ -162,4 +162,35 @@ class SectionTest extends \PHPUnit\Framework\TestCase
$object = new Section(1);
$object->addHeader('ODD');
}
+
+ /**
+ * @covers \PhpOffice\PhpWord\Element\AbstractContainer::removeElement
+ */
+ public function testRemoveElementByIndex()
+ {
+ $section = new Section(1);
+ $section->addText('firstText');
+ $section->addText('secondText');
+
+ $this->assertEquals(2, $section->countElements());
+ $section->removeElement(1);
+
+ $this->assertEquals(1, $section->countElements());
+ }
+
+ /**
+ * @covers \PhpOffice\PhpWord\Element\AbstractContainer::removeElement
+ */
+ public function testRemoveElementByElement()
+ {
+ $section = new Section(1);
+ $fistText = $section->addText('firstText');
+ $secondText = $section->addText('secondText');
+
+ $this->assertEquals(2, $section->countElements());
+ $section->removeElement($fistText);
+
+ $this->assertEquals(1, $section->countElements());
+ $this->assertEquals($secondText->getElementId(), $section->getElement(1)->getElementId());
+ }
}
diff --git a/tests/PhpWord/Element/TitleTest.php b/tests/PhpWord/Element/TitleTest.php
index 3ea6242f..e99a80a6 100644
--- a/tests/PhpWord/Element/TitleTest.php
+++ b/tests/PhpWord/Element/TitleTest.php
@@ -45,4 +45,25 @@ class TitleTest extends \PHPUnit\Framework\TestCase
$this->assertNull($oTitle->getStyle());
}
+
+ /**
+ * Create new instance with TextRun
+ */
+ public function testConstructWithTextRun()
+ {
+ $oTextRun = new TextRun();
+ $oTextRun->addText('text');
+ $oTitle = new Title($oTextRun);
+
+ $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\TextRun', $oTitle->getText());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructWithInvalidArgument()
+ {
+ $oPageBreak = new PageBreak();
+ new Title($oPageBreak);
+ }
}
diff --git a/tests/PhpWord/Reader/Word2007/ElementTest.php b/tests/PhpWord/Reader/Word2007/ElementTest.php
index c2648b68..10c1ec9a 100644
--- a/tests/PhpWord/Reader/Word2007/ElementTest.php
+++ b/tests/PhpWord/Reader/Word2007/ElementTest.php
@@ -36,9 +36,9 @@ class ElementTest extends AbstractTestReader
';
- $phpWord = $this->getDocumentFromString($documentXml);
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml));
- $elements = $this->get($phpWord->getSections(), 0)->getElements();
+ $elements = $phpWord->getSection(0)->getElements();
$this->assertInstanceOf('PhpOffice\PhpWord\Element\TextBreak', $elements[0]);
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $elements[1]);
$this->assertEquals('test string', $elements[1]->getText());
@@ -70,17 +70,73 @@ class ElementTest extends AbstractTestReader
';
- $phpWord = $this->getDocumentFromString($documentXml);
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml));
- $elements = $this->get($phpWord->getSections(), 0)->getElements();
- $this->assertInstanceOf('PhpOffice\PhpWord\Element\ListItemRun', $elements[0]);
- $this->assertEquals(0, $elements[0]->getDepth());
+ $sections = $phpWord->getSection(0);
+ $this->assertNull($sections->getElement(999));
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\ListItemRun', $sections->getElement(0));
+ $this->assertEquals(0, $sections->getElement(0)->getDepth());
- $listElements = $this->get($elements, 0)->getElements();
+ $listElements = $sections->getElement(0)->getElements();
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $listElements[0]);
$this->assertEquals('Two', $listElements[0]->getText());
$this->assertEquals(' with ', $listElements[1]->getText());
$this->assertEquals('bold', $listElements[2]->getText());
$this->assertTrue($listElements[2]->getFontStyle()->getBold());
}
+
+ /**
+ * Test reading Title style
+ */
+ public function testReadTitleStyle()
+ {
+ $documentXml = '
+
+
+
+
+ This is a non formatted title
+
+
+
+
+
+
+
+ This is a
+
+
+
+
+
+ bold
+
+
+ title
+
+ ';
+
+ $stylesXml = '
+
+
+
+
+
+ ';
+
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml, 'styles' => $stylesXml));
+
+ $elements = $phpWord->getSection(0)->getElements();
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Title', $elements[0]);
+ /** @var \PhpOffice\PhpWord\Element\Title $title */
+ $title = $elements[0];
+ $this->assertEquals('Title', $title->getStyle());
+ $this->assertEquals('This is a non formatted title', $title->getText());
+
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Title', $elements[1]);
+ /** @var \PhpOffice\PhpWord\Element\Title $formattedTitle */
+ $formattedTitle = $elements[1];
+ $this->assertEquals('Title', $formattedTitle->getStyle());
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $formattedTitle->getText());
+ }
}
diff --git a/tests/PhpWord/Reader/Word2007/PartTest.php b/tests/PhpWord/Reader/Word2007/PartTest.php
new file mode 100644
index 00000000..0f7ecc7c
--- /dev/null
+++ b/tests/PhpWord/Reader/Word2007/PartTest.php
@@ -0,0 +1,163 @@
+
+
+ This is a test
+
+
+
+
+
+
+
+
+
+
+ And another one
+
+
+
+
+
+
+
+ ';
+
+ $footnotesXml = '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ footnote text
+
+
+ ';
+
+ $endnotesXml = '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This is an endnote
+
+
+ ';
+
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml, 'footnotes' => $footnotesXml, 'endnotes' => $endnotesXml));
+
+ $elements = $phpWord->getSection(0)->getElements();
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\TextRun', $elements[0]);
+ /** @var \PhpOffice\PhpWord\Element\TextRun $textRun */
+ $textRun = $elements[0];
+
+ //test the text in the first paragraph
+ /** @var \PhpOffice\PhpWord\Element\Text $text */
+ $text = $elements[0]->getElement(0);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $text);
+ $this->assertEquals('This is a test', $text->getText());
+
+ //test the presence of the footnote in the document.xml
+ /** @var \PhpOffice\PhpWord\Element\Footnote $footnote */
+ $documentFootnote = $textRun->getElement(1);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Footnote', $documentFootnote);
+ $this->assertEquals(1, $documentFootnote->getRelationId());
+
+ //test the presence of the footnote in the footnote.xml
+ /** @var \PhpOffice\PhpWord\Element\Footnote $footnote */
+ $footnote = $phpWord->getFootnotes()->getItem(1);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Footnote', $footnote);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $footnote->getElement(0));
+ $this->assertEquals('footnote text', $footnote->getElement(0)->getText());
+ $this->assertEquals(1, $footnote->getRelationId());
+
+ //test the text in the second paragraph
+ /** @var \PhpOffice\PhpWord\Element\Text $text */
+ $text = $elements[1]->getElement(0);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $text);
+ $this->assertEquals('And another one', $text->getText());
+
+ //test the presence of the endnote in the document.xml
+ /** @var \PhpOffice\PhpWord\Element\Endnote $endnote */
+ $documentEndnote = $elements[1]->getElement(1);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Endnote', $documentEndnote);
+ $this->assertEquals(2, $documentEndnote->getRelationId());
+
+ //test the presence of the endnote in the endnote.xml
+ /** @var \PhpOffice\PhpWord\Element\Endnote $endnote */
+ $endnote = $phpWord->getEndnotes()->getItem(1);
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Endnote', $endnote);
+ $this->assertEquals(2, $endnote->getRelationId());
+ $this->assertInstanceOf('PhpOffice\PhpWord\Element\Text', $endnote->getElement(0));
+ $this->assertEquals('This is an endnote', $endnote->getElement(0)->getText());
+ }
+}
diff --git a/tests/PhpWord/Reader/Word2007/StyleTest.php b/tests/PhpWord/Reader/Word2007/StyleTest.php
index 4375df47..c0d5d864 100644
--- a/tests/PhpWord/Reader/Word2007/StyleTest.php
+++ b/tests/PhpWord/Reader/Word2007/StyleTest.php
@@ -37,9 +37,9 @@ class StyleTest extends AbstractTestReader
';
- $phpWord = $this->getDocumentFromString($documentXml);
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml));
- $elements = $this->get($phpWord->getSections(), 0)->getElements();
+ $elements = $phpWord->getSection(0)->getElements();
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]);
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
$this->assertEquals(Table::LAYOUT_FIXED, $elements[0]->getStyle()->getLayout());
@@ -56,9 +56,9 @@ class StyleTest extends AbstractTestReader
';
- $phpWord = $this->getDocumentFromString($documentXml);
+ $phpWord = $this->getDocumentFromString(array('document' => $documentXml));
- $elements = $this->get($phpWord->getSections(), 0)->getElements();
+ $elements = $phpWord->getSection(0)->getElements();
$this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]);
$this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle());
$this->assertEquals(TblWidth::AUTO, $elements[0]->getStyle()->getUnit());
diff --git a/tests/PhpWord/Writer/Word2007/ElementTest.php b/tests/PhpWord/Writer/Word2007/ElementTest.php
index 887e8e58..b59e369f 100644
--- a/tests/PhpWord/Writer/Word2007/ElementTest.php
+++ b/tests/PhpWord/Writer/Word2007/ElementTest.php
@@ -447,6 +447,9 @@ class ElementTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:commentReference'));
}
+ /**
+ * Test Track changes
+ */
public function testTrackChange()
{
$phpWord = new PhpWord();
@@ -462,4 +465,30 @@ class ElementTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('author name', $doc->getElementAttribute('/w:document/w:body/w:p/w:ins', 'w:author'));
$this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:del/w:r/w:delText'));
}
+
+ /**
+ * Test Title and Headings
+ */
+ public function testTitleAndHeading()
+ {
+ $phpWord = new PhpWord();
+ $phpWord->addTitleStyle(0, array('size' => 14, 'italic' => true));
+ $phpWord->addTitleStyle(1, array('size' => 20, 'color' => '333333', 'bold' => true));
+
+ $section = $phpWord->addSection();
+ $section->addTitle('This is a title', 0);
+ $section->addTitle('Heading 1', 1);
+
+ $doc = TestHelperDOCX::getDocument($phpWord);
+
+ $this->assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
+ $this->assertEquals('This is a title', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
+ $this->assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:pStyle'));
+ $this->assertEquals('Title', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:pStyle', 'w:val'));
+
+ $this->assertTrue($doc->elementExists('/w:document/w:body/w:p[2]/w:r/w:t'));
+ $this->assertEquals('Heading 1', $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:t')->textContent);
+ $this->assertTrue($doc->elementExists('/w:document/w:body/w:p[2]/w:pPr/w:pStyle'));
+ $this->assertEquals('Heading1', $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:pPr/w:pStyle', 'w:val'));
+ }
}
diff --git a/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php b/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php
index 6998e717..39db6028 100644
--- a/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php
+++ b/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php
@@ -24,7 +24,6 @@ use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\SimpleType\NumberFormat;
use PhpOffice\PhpWord\Style\Cell;
use PhpOffice\PhpWord\Style\Font;
-use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\TestHelperDOCX;
/**
diff --git a/tests/PhpWord/_includes/AbstractTestReader.php b/tests/PhpWord/_includes/AbstractTestReader.php
index f138ac76..348cab98 100644
--- a/tests/PhpWord/_includes/AbstractTestReader.php
+++ b/tests/PhpWord/_includes/AbstractTestReader.php
@@ -17,43 +17,48 @@
namespace PhpOffice\PhpWord;
-use PhpOffice\PhpWord\Reader\Word2007\Document;
-
/**
* Base class for Word2007 reader tests
*/
abstract class AbstractTestReader extends \PHPUnit\Framework\TestCase
{
+ private $parts = array(
+ 'styles' => array('class' => 'PhpOffice\PhpWord\Reader\Word2007\Styles', 'xml' => '{toReplace}'),
+ 'document' => array('class' => 'PhpOffice\PhpWord\Reader\Word2007\Document', 'xml' => '{toReplace}'),
+ 'footnotes' => array('class' => 'PhpOffice\PhpWord\Reader\Word2007\Footnotes', 'xml' => '{toReplace}'),
+ 'endnotes' => array('class' => 'PhpOffice\PhpWord\Reader\Word2007\Endnotes', 'xml' => '{toReplace}'),
+ 'settings' => array('class' => 'PhpOffice\PhpWord\Reader\Word2007\Settings', 'xml' => '{toReplace}'),
+ );
+
/**
* Builds a PhpWord instance based on the xml passed
*
* @param string $documentXml
+ * @param null|string $stylesXml
* @return \PhpOffice\PhpWord\PhpWord
*/
- protected function getDocumentFromString($documentXml)
+ protected function getDocumentFromString(array $partXmls = array())
{
- $phpWord = new PhpWord();
$file = __DIR__ . '/../_files/temp.docx';
$zip = new \ZipArchive();
$zip->open($file, \ZipArchive::CREATE);
- $zip->addFromString('document.xml', '' . $documentXml . '');
+ foreach ($this->parts as $partName => $part) {
+ if (array_key_exists($partName, $partXmls)) {
+ $zip->addFromString("{$partName}.xml", str_replace('{toReplace}', $partXmls[$partName], $this->parts[$partName]['xml']));
+ }
+ }
$zip->close();
- $documentReader = new Document($file, 'document.xml');
- $documentReader->read($phpWord);
+
+ $phpWord = new PhpWord();
+ foreach ($this->parts as $partName => $part) {
+ if (array_key_exists($partName, $partXmls)) {
+ $className = $this->parts[$partName]['class'];
+ $reader = new $className($file, "{$partName}.xml");
+ $reader->read($phpWord);
+ }
+ }
unlink($file);
return $phpWord;
}
-
- /**
- * Returns the element at position $index in the array
- *
- * @param array $array
- * @param number $index
- * @return mixed
- */
- protected function get(array $array, $index = 0)
- {
- return $array[$index];
- }
}