diff --git a/.gitignore b/.gitignore index dd858cea..f5f6f7eb 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ phpword.ini /.project /nbproject /.php_cs.cache +/.phpunit.result.cache diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 02534736..ad5aec11 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -107,10 +107,6 @@ class Html foreach ($attributes as $attribute) { $val = $attribute->value; switch (strtolower($attribute->name)) { - case 'style': - $styles = self::parseStyle($attribute, $styles); - - break; case 'align': $styles['alignment'] = self::mapAlign(trim($val)); @@ -152,6 +148,11 @@ class Html break; } } + + $attributeStyle = $attributes->getNamedItem('style'); + if ($attributeStyle) { + $styles = self::parseStyle($attributeStyle, $styles); + } } return $styles; diff --git a/tests/PhpWordTests/Shared/HtmlTest.php b/tests/PhpWordTests/Shared/HtmlTest.php index 69e34ed9..cd2338e1 100644 --- a/tests/PhpWordTests/Shared/HtmlTest.php +++ b/tests/PhpWordTests/Shared/HtmlTest.php @@ -19,6 +19,7 @@ namespace PhpOffice\PhpWordTests\Shared; use Exception; use PhpOffice\PhpWord\Element\Section; +use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\Shared\Html; use PhpOffice\PhpWord\SimpleType\Jc; use PhpOffice\PhpWord\SimpleType\LineSpacingRule; @@ -41,7 +42,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest $content = ''; // Default - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); self::assertCount(0, $section->getElements()); @@ -97,7 +98,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest public function testParseHtmlEntities(): void { \PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true); - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, 'text with entities <my text>'); @@ -112,7 +113,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest public function testParseUnderline(): void { $html = 'test'; - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, $html); @@ -127,7 +128,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest public function testParseTextDecoration(): void { $html = 'test'; - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, $html); @@ -142,7 +143,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest public function testParseFont(): void { $html = 'test'; - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, $html); @@ -156,7 +157,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseLineHeight(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, '

test

'); Html::addHtml($section, '

test

'); @@ -191,7 +192,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseTextIndent(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, '

test

'); @@ -205,7 +206,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseTextAlign(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, '

test

'); Html::addHtml($section, '

test

'); @@ -225,7 +226,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseFontSize(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, 'test'); Html::addHtml($section, 'test'); @@ -241,7 +242,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseTextDirection(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, 'test'); @@ -254,7 +255,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseLang(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, 'test'); @@ -268,7 +269,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseFontFamily(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, 'test'); Html::addHtml($section, 'test'); @@ -284,7 +285,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseParagraphAndSpanStyle(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, '

test

'); @@ -300,7 +301,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseParagraphWithPageBreak(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); Html::addHtml($section, '

'); @@ -314,7 +315,7 @@ class HtmlTest extends AbstractWebServerEmbeddedTest */ public function testParseTable(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); $html = ' @@ -355,366 +356,12 @@ class HtmlTest extends AbstractWebServerEmbeddedTest self::assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:pBdr')); } - /** - * Test parsing table (attribute border). - */ - public function testParseTableAttributeBorder(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '
- - - - - - - - - -
Header
Cell 1
Cell 2
'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders/w:top')); - // 10 pixels = 150 twips - self::assertEquals(150, $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders/w:top', 'w:sz')); - } - - /** - * Tests parsing of ul/li. - */ - public function testParseList(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = ''; - Html::addHtml($section, $html, false, false); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); - self::assertEquals('list item1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); - self::assertEquals('list item2', $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:t')->nodeValue); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:b')); - } - - /** - * Tests parsing of ul/li. - */ - public function testOrderedListNumbering(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '
    -
  1. List 1 item 1
  2. -
  3. List 1 item 2
  4. -
-

Some Text

-
    -
  1. List 2 item 1
  2. -
  3. List 2 item 2
  4. -
'; - Html::addHtml($section, $html, false, false); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); - - self::assertEquals('List 1 item 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); - self::assertEquals('List 2 item 1', $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:t')->nodeValue); - - $firstListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId', 'w:val'); - $secondListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:numPr/w:numId', 'w:val'); - - self::assertNotEquals($firstListnumId, $secondListnumId); - } - - /** - * Tests parsing of nested ul/li. - */ - public function testOrderedNestedListNumbering(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '
    -
  1. List 1 item 1
  2. -
  3. List 1 item 2
  4. -
-

Some Text

-
    -
  1. List 2 item 1
  2. -
  3. -
      -
    1. sub list 1
    2. -
    3. sub list 2
    4. -
    -
  4. -
'; - Html::addHtml($section, $html, false, false); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); - - self::assertEquals('List 1 item 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); - self::assertEquals('List 2 item 1', $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:t')->nodeValue); - - $firstListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId', 'w:val'); - $secondListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:numPr/w:numId', 'w:val'); - - self::assertNotEquals($firstListnumId, $secondListnumId); - } - - /** - * Tests parsing of ul/li. - */ - public function testParseListWithFormat(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = preg_replace('/\s+/', ' ', ''); - Html::addHtml($section, $html, false, false); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); - self::assertEquals('list item2', $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:t')->nodeValue); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r[3]/w:rPr/w:b')); - self::assertEquals('bold', $doc->getElement('/w:document/w:body/w:p[1]/w:r[3]/w:t')->nodeValue); - } - - /** - * Tests parsing of br. - */ - public function testParseLineBreak(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

This is some text
with a linebreak.

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:br')); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); - self::assertEquals('This is some text', $doc->getElement('/w:document/w:body/w:p/w:r[1]/w:t')->nodeValue); - self::assertEquals('with a linebreak.', $doc->getElement('/w:document/w:body/w:p/w:r[2]/w:t')->nodeValue); - } - - /** - * Test parsing of img. - */ - public function testParseImage(): void - { - $src = __DIR__ . '/../_files/images/firefox.png'; - - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - $baseXpath = '/w:document/w:body/w:p/w:r'; - self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); - self::assertStringMatchesFormat('%Swidth:150px%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); - self::assertStringMatchesFormat('%Sheight:200px%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); - self::assertStringMatchesFormat('%Smso-position-horizontal:right%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); - self::assertStringMatchesFormat('%Smso-position-horizontal:left%S', $doc->getElementAttribute($baseXpath . '[2]/w:pict/v:shape', 'style')); - } - - /** - * Test parsing of remote img. - */ - public function testParseRemoteImage(): void - { - $src = self::getRemoteImageUrl(); - - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - $baseXpath = '/w:document/w:body/w:p/w:r'; - self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); - } - - /** - * Test parsing embedded image. - */ - public function testParseEmbeddedImage(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - $baseXpath = '/w:document/w:body/w:p/w:r'; - self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); - } - - /** - * Test parsing of remote img that can be found locally. - */ - public function testParseRemoteLocalImage(): void - { - $src = 'https://fakedomain.io/images/firefox.png'; - $localPath = __DIR__ . '/../_files/images/'; - $options = [ - 'IMG_SRC_SEARCH' => 'https://fakedomain.io/images/', - 'IMG_SRC_REPLACE' => $localPath, - ]; - - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

'; - Html::addHtml($section, $html, false, true, $options); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - $baseXpath = '/w:document/w:body/w:p/w:r'; - self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); - } - - /** - * Test parsing of remote img that can be found locally. - */ - public function testCouldNotLoadImage(): void - { - $this->expectException(Exception::class); - $src = 'https://fakedomain.io/images/firefox.png'; - - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

'; - Html::addHtml($section, $html, false, true); - } - - public function testParseLink(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

link text

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink')); - self::assertEquals('link text', $doc->getElement('/w:document/w:body/w:p/w:hyperlink/w:r/w:t')->nodeValue); - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:u')); - self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:u', 'w:val')); - - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $section->addBookmark('bookmark'); - $html = '

internal link text

'; - Html::addHtml($section, $html); - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink')); - self::assertTrue($doc->getElement('/w:document/w:body/w:p/w:hyperlink')->hasAttribute('w:anchor')); - self::assertEquals('bookmark', $doc->getElement('/w:document/w:body/w:p/w:hyperlink')->getAttribute('w:anchor')); - } - - public function testParseMalformedStyleIsIgnored(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

text

'; - Html::addHtml($section, $html); - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:jc')); - } - - /** - * Tests parsing hidden text. - */ - public function testParseHiddenText(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

This is some hidden text.

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:vanish')); - } - - /** - * Tests parsing letter spacing. - */ - public function testParseLetterSpacing(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = '

This is some text with letter spacing.

'; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:spacing')); - self::assertEquals(150 * 15, $doc->getElement('/w:document/w:body/w:p/w:r/w:rPr/w:spacing')->getAttribute('w:val')); - } - - /** - * Tests checkbox input field. - */ - public function testInputCheckbox(): void - { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); - $section = $phpWord->addSection(); - $html = ''; - Html::addHtml($section, $html); - - $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:fldChar/w:ffData/w:checkBox')); - self::assertEquals(1, $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:fldChar/w:ffData/w:checkBox/w:checked')->getAttribute('w:val')); - - self::assertTrue($doc->elementExists('/w:document/w:body/w:p[2]/w:r/w:fldChar/w:ffData/w:checkBox')); - self::assertEquals(0, $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:fldChar/w:ffData/w:checkBox/w:checked')->getAttribute('w:val')); - } - /** * Parse widths in tables and cells, which also allows for controlling column width. */ public function testParseTableAndCellWidth(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection([ 'orientation' => \PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE, ]); @@ -778,12 +425,41 @@ HTML; self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type')); } + /** + * Test parsing table (attribute border). + */ + public function testParseTableAttributeBorder(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = ' + + + + + + + + + +
Header
Cell 1
Cell 2
'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders/w:top')); + // 10 pixels = 150 twips + self::assertEquals(150, $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tblPr/w:tblBorders/w:top', 'w:sz')); + } + /** * Test parsing background color for table rows and table cellspacing. */ - public function testParseCellspacingRowBgColor(): void + public function testParseTableCellspacingRowBgColor(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection([ 'orientation' => \PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE, ]); @@ -819,12 +495,366 @@ HTML; self::assertEquals('FF0000', $doc->getElement($xpath)->getAttribute('w:fill')); } + /** + * Test parsing background color for table rows and table cellspacing. + */ + public function testParseTableStyleAttributeInlineStyle(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + + $html = << + + A + + + HTML; + + Html::addHtml($section, $html); + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblW'; + self::assertTrue($doc->elementExists($xpath)); + self::assertEquals(100 * 50, $doc->getElement($xpath)->getAttribute('w:w')); + self::assertEquals('pct', $doc->getElement($xpath)->getAttribute('w:type')); + + $xpath = '/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:shd'; + self::assertTrue($doc->elementExists($xpath)); + self::assertEquals('red', $doc->getElement($xpath)->getAttribute('w:fill')); + } + + /** + * Tests parsing of ul/li. + */ + public function testParseList(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = ''; + Html::addHtml($section, $html, false, false); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); + self::assertEquals('list item1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); + self::assertEquals('list item2', $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:t')->nodeValue); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:b')); + } + + /** + * Tests parsing of ul/li. + */ + public function testOrderedListNumbering(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '
    +
  1. List 1 item 1
  2. +
  3. List 1 item 2
  4. +
+

Some Text

+
    +
  1. List 2 item 1
  2. +
  3. List 2 item 2
  4. +
'; + Html::addHtml($section, $html, false, false); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); + + self::assertEquals('List 1 item 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); + self::assertEquals('List 2 item 1', $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:t')->nodeValue); + + $firstListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId', 'w:val'); + $secondListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:numPr/w:numId', 'w:val'); + + self::assertNotEquals($firstListnumId, $secondListnumId); + } + + /** + * Tests parsing of nested ul/li. + */ + public function testOrderedNestedListNumbering(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '
    +
  1. List 1 item 1
  2. +
  3. List 1 item 2
  4. +
+

Some Text

+
    +
  1. List 2 item 1
  2. +
  3. +
      +
    1. sub list 1
    2. +
    3. sub list 2
    4. +
    +
  4. +
'; + Html::addHtml($section, $html, false, false); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); + + self::assertEquals('List 1 item 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue); + self::assertEquals('List 2 item 1', $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:t')->nodeValue); + + $firstListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId', 'w:val'); + $secondListnumId = $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:numPr/w:numId', 'w:val'); + + self::assertNotEquals($firstListnumId, $secondListnumId); + } + + /** + * Tests parsing of ul/li. + */ + public function testParseListWithFormat(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = preg_replace('/\s+/', ' ', ''); + Html::addHtml($section, $html, false, false); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:numPr/w:numId')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); + self::assertEquals('list item2', $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:t')->nodeValue); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r[3]/w:rPr/w:b')); + self::assertEquals('bold', $doc->getElement('/w:document/w:body/w:p[1]/w:r[3]/w:t')->nodeValue); + } + + /** + * Tests parsing of br. + */ + public function testParseLineBreak(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

This is some text
with a linebreak.

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:br')); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:t')); + self::assertEquals('This is some text', $doc->getElement('/w:document/w:body/w:p/w:r[1]/w:t')->nodeValue); + self::assertEquals('with a linebreak.', $doc->getElement('/w:document/w:body/w:p/w:r[2]/w:t')->nodeValue); + } + + /** + * Test parsing of img. + */ + public function testParseImage(): void + { + $src = __DIR__ . '/../_files/images/firefox.png'; + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $baseXpath = '/w:document/w:body/w:p/w:r'; + self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); + self::assertStringMatchesFormat('%Swidth:150px%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); + self::assertStringMatchesFormat('%Sheight:200px%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); + self::assertStringMatchesFormat('%Smso-position-horizontal:right%S', $doc->getElementAttribute($baseXpath . '[1]/w:pict/v:shape', 'style')); + self::assertStringMatchesFormat('%Smso-position-horizontal:left%S', $doc->getElementAttribute($baseXpath . '[2]/w:pict/v:shape', 'style')); + } + + /** + * Test parsing of remote img. + */ + public function testParseRemoteImage(): void + { + $src = self::getRemoteImageUrl(); + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $baseXpath = '/w:document/w:body/w:p/w:r'; + self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); + } + + /** + * Test parsing embedded image. + */ + public function testParseEmbeddedImage(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $baseXpath = '/w:document/w:body/w:p/w:r'; + self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); + } + + /** + * Test parsing of remote img that can be found locally. + */ + public function testParseRemoteLocalImage(): void + { + $src = 'https://fakedomain.io/images/firefox.png'; + $localPath = __DIR__ . '/../_files/images/'; + $options = [ + 'IMG_SRC_SEARCH' => 'https://fakedomain.io/images/', + 'IMG_SRC_REPLACE' => $localPath, + ]; + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

'; + Html::addHtml($section, $html, false, true, $options); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $baseXpath = '/w:document/w:body/w:p/w:r'; + self::assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape')); + } + + /** + * Test parsing of remote img that can be found locally. + */ + public function testCouldNotLoadImage(): void + { + $this->expectException(Exception::class); + $src = 'https://fakedomain.io/images/firefox.png'; + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

'; + Html::addHtml($section, $html, false, true); + } + + public function testParseLink(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

link text

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink')); + self::assertEquals('link text', $doc->getElement('/w:document/w:body/w:p/w:hyperlink/w:r/w:t')->nodeValue); + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:u')); + self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:hyperlink/w:r/w:rPr/w:u', 'w:val')); + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $section->addBookmark('bookmark'); + $html = '

internal link text

'; + Html::addHtml($section, $html); + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:hyperlink')); + self::assertTrue($doc->getElement('/w:document/w:body/w:p/w:hyperlink')->hasAttribute('w:anchor')); + self::assertEquals('bookmark', $doc->getElement('/w:document/w:body/w:p/w:hyperlink')->getAttribute('w:anchor')); + } + + public function testParseMalformedStyleIsIgnored(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

text

'; + Html::addHtml($section, $html); + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:jc')); + } + + /** + * Tests parsing hidden text. + */ + public function testParseHiddenText(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

This is some hidden text.

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:vanish')); + } + + /** + * Tests parsing letter spacing. + */ + public function testParseLetterSpacing(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = '

This is some text with letter spacing.

'; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:spacing')); + self::assertEquals(150 * 15, $doc->getElement('/w:document/w:body/w:p/w:r/w:rPr/w:spacing')->getAttribute('w:val')); + } + + /** + * Tests checkbox input field. + */ + public function testInputCheckbox(): void + { + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $html = ''; + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:fldChar/w:ffData/w:checkBox')); + self::assertEquals(1, $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:fldChar/w:ffData/w:checkBox/w:checked')->getAttribute('w:val')); + + self::assertTrue($doc->elementExists('/w:document/w:body/w:p[2]/w:r/w:fldChar/w:ffData/w:checkBox')); + self::assertEquals(0, $doc->getElement('/w:document/w:body/w:p[2]/w:r/w:fldChar/w:ffData/w:checkBox/w:checked')->getAttribute('w:val')); + } + /** * Parse horizontal rule. */ public function testParseHorizontalRule(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); // borders & backgrounds are here just for better visual comparison @@ -865,7 +895,7 @@ HTML; */ public function testParseOrderedList(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); // borders & backgrounds are here just for better visual comparison @@ -926,7 +956,7 @@ HTML; */ public function testParseVerticalAlign(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); // borders & backgrounds are here just for better visual comparison @@ -966,7 +996,7 @@ HTML; */ public function testDontDecodeAlreadyEncodedDoubleQuotes(): void { - $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $phpWord = new PhpWord(); $section = $phpWord->addSection(); // borders & backgrounds are here just for better visual comparison