addSection();
self::assertCount(0, $section->getElements());
// Heading
$styles = ['strong', 'em', 'sup', 'sub'];
for ($level = 1; $level <= 6; ++$level) {
$content .= "Heading {$level} ";
}
// Styles
$content .= '
';
foreach ($styles as $style) {
$content .= "<{$style}>{$style}{$style}>";
}
$content .= '
';
// Add HTML
Html::addHtml($section, $content);
self::assertCount(7, $section->getElements());
// Other parts
$section = $phpWord->addSection();
$content = '';
$content .= '';
$content .= '';
$content .= 'Bullet ';
$content .= "'Single Quoted Text'";
$content .= '"Double Quoted Text"';
$content .= '& Ampersand';
$content .= '<>“‘’«»‹›';
$content .= '&•°…™©®—';
$content .= '– ²³¼½¾';
Html::addHtml($section, $content);
}
/**
* Test that html already in body element can be read.
*
* @ignore
*/
public function testParseFullHtml(): void
{
$section = new Section(1);
Html::addHtml($section, 'test paragraph1
test paragraph2
', true);
self::assertCount(2, $section->getElements());
}
/**
* Test HTML entities.
*/
public function testParseHtmlEntities(): void
{
\PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'text with entities <my text>');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
self::assertEquals('text with entities ', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->nodeValue);
}
/**
* Test underline.
*/
public function testParseUnderline(): void
{
$html = 'test ';
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:u'));
self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val'));
}
/**
* Test text-decoration style.
*/
public function testParseTextDecoration(): void
{
$html = 'test ';
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:u'));
self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val'));
}
/**
* Test font.
*/
public function testParseFont(): void
{
$html = 'test ';
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr'));
//TODO check style
}
/**
* Test line-height style.
*/
public function testParseLineHeight(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:spacing'));
self::assertEquals(Paragraph::LINE_HEIGHT * 1.5, $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:spacing', 'w:line'));
self::assertEquals(LineSpacingRule::AUTO, $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:spacing', 'w:lineRule'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[2]/w:pPr/w:spacing'));
self::assertEquals(300, $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:pPr/w:spacing', 'w:line'));
self::assertEquals(LineSpacingRule::EXACT, $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:pPr/w:spacing', 'w:lineRule'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[3]/w:pPr/w:spacing'));
self::assertEquals(Paragraph::LINE_HEIGHT * 1.2, $doc->getElementAttribute('/w:document/w:body/w:p[3]/w:pPr/w:spacing', 'w:line'));
self::assertEquals(LineSpacingRule::AUTO, $doc->getElementAttribute('/w:document/w:body/w:p[3]/w:pPr/w:spacing', 'w:lineRule'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[4]/w:pPr/w:spacing'));
self::assertEquals(244.8, $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:spacing', 'w:line'));
self::assertEquals(LineSpacingRule::EXACT, $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:spacing', 'w:lineRule'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[5]/w:pPr/w:spacing'));
self::assertEquals(Paragraph::LINE_HEIGHT, $doc->getElementAttribute('/w:document/w:body/w:p[5]/w:pPr/w:spacing', 'w:line'));
self::assertEquals(LineSpacingRule::AUTO, $doc->getElementAttribute('/w:document/w:body/w:p[5]/w:pPr/w:spacing', 'w:lineRule'));
}
/**
* Test text-indent style.
*/
public function testParseTextIndent(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test
');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:ind'));
self::assertEquals(750, $doc->getElementAttribute('/w:document/w:body/w:p/w:pPr/w:ind', 'w:firstLine'));
}
/**
* Test text-align style.
*/
public function testParseTextAlign(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
Html::addHtml($section, 'test
');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:jc'));
self::assertEquals(Jc::START, $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:jc', 'w:val'));
self::assertEquals(Jc::END, $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:pPr/w:jc', 'w:val'));
self::assertEquals(Jc::CENTER, $doc->getElementAttribute('/w:document/w:body/w:p[3]/w:pPr/w:jc', 'w:val'));
self::assertEquals(Jc::BOTH, $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:jc', 'w:val'));
}
/**
* Test font-size style.
*/
public function testParseFontSize(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test ');
Html::addHtml($section, 'test ');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:sz'));
self::assertEquals('20', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:r/w:rPr/w:sz', 'w:val'));
self::assertEquals('15', $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:r/w:rPr/w:sz', 'w:val'));
}
/**
* Test direction style.
*/
public function testParseTextDirection(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test ');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:rtl'));
}
/**
* Test html lang.
*/
public function testParseLang(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test ');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:lang'));
self::assertEquals('fr-BE', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:lang', 'w:val'));
}
/**
* Test font-family style.
*/
public function testParseFontFamily(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test ');
Html::addHtml($section, 'test ');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:rFonts'));
self::assertEquals('Arial', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:r/w:rPr/w:rFonts', 'w:ascii'));
self::assertEquals('Times New Roman', $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:r/w:rPr/w:rFonts', 'w:ascii'));
}
/**
* Test parsing paragraph and span styles.
*/
public function testParseParagraphAndSpanStyle(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, 'test
');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:jc'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:spacing'));
self::assertEquals(Jc::CENTER, $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:jc', 'w:val'));
self::assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:r/w:rPr/w:u', 'w:val'));
}
/**
* Test parsing paragraph with `page-break-after` style.
*/
public function testParseParagraphWithPageBreak(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
Html::addHtml($section, '
');
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:br'));
self::assertEquals('page', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:br', 'w:type'));
}
/**
* Test parsing table.
*/
public function testParseTable(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
$html = '
header a
header b
header c
1 2
This is bold text 5 6
';
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:tr/w:tc'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tblPr/w:jc'));
self::assertEquals(Jc::START, $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tblPr/w:jc', 'w:val'));
//check border colors
self::assertEquals('00EE00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:tcPr/w:tcBorders/w:top', 'w:color'));
self::assertEquals('00EE00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:tcPr/w:tcBorders/w:right', 'w:color'));
self::assertEquals('00EE00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:tcPr/w:tcBorders/w:bottom', 'w:color'));
self::assertEquals('00EE00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:tcPr/w:tcBorders/w:left', 'w:color'));
self::assertEquals('00AA00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:top', 'w:color'));
self::assertEquals('00BB00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:right', 'w:color'));
self::assertEquals('00CC00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:bottom', 'w:color'));
self::assertEquals('00DD00', $doc->getElementAttribute('/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/w:left', 'w:color'));
//check borders are not propagated inside cells
self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p'));
self::assertFalse($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:pBdr'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:p'));
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 = '';
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 = '
List 1 item 1
List 1 item 2
Some Text
List 2 item 1
List 2 item 2
';
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 = '
List 1 item 1
List 1 item 2
Some Text
List 2 item 1
sub list 1
sub list 2
';
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+/', ' ', '
Some text before
list item1 bold with text after bold
and some after
list item2
');
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();
$section = $phpWord->addSection([
'orientation' => \PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE,
]);
// borders & backgrounds are here just for better visual comparison
$html = <<
25%
400px
T2.R2.C1
50pt
T2.R2.C3
300px
T2.R3.C3
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
// outer table grid
$xpath = '/w:document/w:body/w:tbl/w:tblGrid/w:gridCol';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals(25 * 50, $doc->getElement($xpath)->getAttribute('w:w'));
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
// elementExists($xpath));
self::assertEquals(6000, $doc->getElement($xpath)->getAttribute('w:w'));
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
// elementExists($xpath));
self::assertEquals(4500, $doc->getElement($xpath)->getAttribute('w:w'));
self::assertEquals('dxa', $doc->getElement($xpath)->getAttribute('w:type'));
}
/**
* Test parsing background color for table rows and table cellspacing.
*/
public function testParseCellspacingRowBgColor(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection([
'orientation' => \PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE,
]);
// borders & backgrounds are here just for better visual comparison
$html = <<
A
B
C
D
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
$xpath = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals(3 * 15, $doc->getElement($xpath)->getAttribute('w:w'));
self::assertEquals('dxa', $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('lightgreen', $doc->getElement($xpath)->getAttribute('w:fill'));
$xpath = '/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('FF0000', $doc->getElement($xpath)->getAttribute('w:fill'));
}
/**
* Parse horizontal rule.
*/
public function testParseHorizontalRule(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
// borders & backgrounds are here just for better visual comparison
$html = <<Simple default rule:
Custom style rule:
END
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
// default rule
$xpath = '/w:document/w:body/w:p[2]/w:pPr/w:pBdr/w:bottom';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('single', $doc->getElement($xpath)->getAttribute('w:val')); // solid
self::assertEquals('1', $doc->getElement($xpath)->getAttribute('w:sz')); // 1 twip
self::assertEquals('000000', $doc->getElement($xpath)->getAttribute('w:color')); // black
// custom style rule
$xpath = '/w:document/w:body/w:p[4]/w:pPr/w:pBdr/w:bottom';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('single', $doc->getElement($xpath)->getAttribute('w:val'));
self::assertEquals((int) (5 * 15 / 2), $doc->getElement($xpath)->getAttribute('w:sz'));
self::assertEquals('lightblue', $doc->getElement($xpath)->getAttribute('w:color'));
$xpath = '/w:document/w:body/w:p[4]/w:pPr/w:spacing';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals(450, $doc->getElement($xpath)->getAttribute('w:before'));
self::assertEquals(0, $doc->getElement($xpath)->getAttribute('w:after'));
self::assertEquals(240, $doc->getElement($xpath)->getAttribute('w:line'));
}
/**
* Parse ordered list start & numbering style.
*/
public function testParseOrderedList(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
// borders & backgrounds are here just for better visual comparison
$html = <<
standard ordered list line 1
standard ordered list line 2
ordered list alphabetical, line 5 => E
ordered list alphabetical, line 6 => F
ordered list roman lower, line 3 => iii
ordered list roman lower, line 4 => iv
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
// compare numbering file
$xmlFile = 'word/numbering.xml';
// default - decimal start = 1
$xpath = '/w:numbering/w:abstractNum[1]/w:lvl[1]/w:start';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('1', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
$xpath = '/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('decimal', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
// second list - start = 5, type A = upperLetter
$xpath = '/w:numbering/w:abstractNum[2]/w:lvl[1]/w:start';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('5', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
$xpath = '/w:numbering/w:abstractNum[2]/w:lvl[1]/w:numFmt';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('upperLetter', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
// third list - start = 3, type i = lowerRoman
$xpath = '/w:numbering/w:abstractNum[3]/w:lvl[1]/w:start';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('3', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
$xpath = '/w:numbering/w:abstractNum[3]/w:lvl[1]/w:numFmt';
self::assertTrue($doc->elementExists($xpath, $xmlFile));
self::assertEquals('lowerRoman', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val'));
}
/**
* Parse ordered list start & numbering style.
*/
public function testParseVerticalAlign(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
// borders & backgrounds are here just for better visual comparison
$html = <<
default
top
middle
bottom
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:tcPr/w:vAlign';
self::assertFalse($doc->elementExists($xpath));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:vAlign';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('top', $doc->getElement($xpath)->getAttribute('w:val'));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[3]/w:tcPr/w:vAlign';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('center', $doc->getElement($xpath)->getAttribute('w:val'));
$xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[4]/w:tcPr/w:vAlign';
self::assertTrue($doc->elementExists($xpath));
self::assertEquals('bottom', $doc->getElement($xpath)->getAttribute('w:val'));
}
/**
* Fix bug - don't decode double quotes inside double quoted string.
*/
public function testDontDecodeAlreadyEncodedDoubleQuotes(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
// borders & backgrounds are here just for better visual comparison
$html = <<This would crash if inline quotes also decoded at loading XML into DOMDocument!
HTML;
Html::addHtml($section, $html);
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
self::assertIsObject($doc);
}
}