Skip to content

Commit 58c6c52

Browse files
author
Javier Garcia
committed
merged with local version
1 parent e6501eb commit 58c6c52

File tree

2 files changed

+103
-2
lines changed

2 files changed

+103
-2
lines changed

src/PhpWord/Shared/Html.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use PhpOffice\PhpWord\Element\Table;
2323
use PhpOffice\PhpWord\SimpleType\Jc;
2424
use PhpOffice\PhpWord\SimpleType\NumberFormat;
25+
use PhpOffice\PhpWord\Settings;
2526

2627
/**
2728
* Common Html functions
@@ -32,6 +33,7 @@ class Html
3233
{
3334
private static $listIndex = 0;
3435
private static $xpath;
36+
private static $options;
3537

3638
/**
3739
* Add HTML parts.
@@ -44,13 +46,17 @@ class Html
4446
* @param string $html The code to parse
4547
* @param bool $fullHTML If it's a full HTML, no need to add 'body' tag
4648
* @param bool $preserveWhiteSpace If false, the whitespaces between nodes will be removed
49+
* @param array $options:
50+
* + IMG_SRC_SEARCH: optional to speed up images loading from remote url when files can be found locally
51+
* + IMG_SRC_REPLACE: optional to speed up images loading from remote url when files can be found locally
4752
*/
48-
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true)
53+
public static function addHtml($element, $html, $fullHTML = false, $preserveWhiteSpace = true, $options = null )
4954
{
5055
/*
5156
* @todo parse $stylesheet for default styles. Should result in an array based on id, class and element,
5257
* which could be applied when such an element occurs in the parseNode function.
5358
*/
59+
self::$options = $options;
5460

5561
// Preprocess: remove all line ends, decode HTML entity,
5662
// fix ampersand and angle brackets and add body tag for HTML fragments
@@ -141,6 +147,7 @@ protected static function parseNode($node, $element, $styles = array(), $data =
141147
'sup' => array('Property', null, null, $styles, null, 'superScript', true),
142148
'sub' => array('Property', null, null, $styles, null, 'subScript', true),
143149
'span' => array('Span', $node, null, $styles, null, null, null),
150+
'font' => array('Span', $node, null, $styles, null, null, null),
144151
'table' => array('Table', $node, $element, $styles, null, null, null),
145152
'tr' => array('Row', $node, $element, $styles, null, null, null),
146153
'td' => array('Cell', $node, $element, $styles, null, null, null),
@@ -296,8 +303,9 @@ private static function parseSpan($node, &$styles)
296303
*
297304
* @todo As soon as TableItem, RowItem and CellItem support relative width and height
298305
*/
299-
private static function parseTable($node, $element, &$styles)
306+
private static function parseTable($node, $element, &$styles )
300307
{
308+
301309
$elementStyles = self::parseInlineStyle($node, $styles['table']);
302310

303311
$newElement = $element->addTable($elementStyles);
@@ -648,6 +656,45 @@ private static function parseImage($node, $element)
648656
break;
649657
}
650658
}
659+
if( strpos( $src, "data:image" ) !== false ){
660+
if( ! is_dir( self::$imgdir ) )
661+
mkdir( self::$imgdir ) ;
662+
663+
$match = array();
664+
preg_match( '/data:image\/(\w+);base64,(.+)/', $src, $match );
665+
666+
$src = $imgFile = self::$imgdir . uniqid() . "." . $match[1];
667+
668+
$ifp = fopen( $imgFile, "wb");
669+
670+
fwrite($ifp, base64_decode( $match[2] ) );
671+
fclose($ifp);
672+
673+
}
674+
$src= urldecode($src);
675+
676+
if( ! is_file( $src )
677+
&& !is_null(self::$options)
678+
&& isset(self::$options['IMG_SRC_SEARCH'])
679+
&& isset(self::$options['IMG_SRC_REPLACE'])){
680+
$src = str_replace( self::$options['IMG_SRC_SEARCH'], self::$options['IMG_SRC_REPLACE'], $src );
681+
}
682+
683+
if(! is_file($src)){
684+
if($imgBlob=file_get_contents($src)){
685+
$tmpDir= Settings::getTempDir().'/';
686+
if( ! is_dir( $tmpDir ) )
687+
mkdir( $tmpDir ) ;
688+
$match = array();
689+
preg_match( '/.+\.(\w+)$/', $src, $match );
690+
$src = $tmpDir . uniqid() . "." . $match[1];
691+
692+
$ifp = fopen( $src, "wb");
693+
694+
fwrite($ifp, $imgBlob );
695+
fclose($ifp);
696+
}
697+
}
651698
$newElement = $element->addImage($src, $style);
652699

653700
return $newElement;

tests/PhpWord/Shared/HtmlTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,20 @@ public function testParseTextDecoration()
115115
$this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:u'));
116116
$this->assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val'));
117117
}
118+
/**
119+
* Test font
120+
*/
121+
public function testParseFont()
122+
{
123+
$html = '<font style="font-family: Arial;">test</font>';
124+
$phpWord = new \PhpOffice\PhpWord\PhpWord();
125+
$section = $phpWord->addSection();
126+
Html::addHtml($section, $html);
127+
128+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
129+
$this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr'));
130+
//TODO check style
131+
}
118132

119133
/**
120134
* Test line-height style
@@ -447,6 +461,46 @@ public function testParseImage()
447461
$this->assertStringMatchesFormat('%Smso-position-horizontal:left%S', $doc->getElementAttribute($baseXpath . '[2]/w:pict/v:shape', 'style'));
448462
}
449463

464+
/**
465+
* Test parsing of remote img
466+
*/
467+
public function testParseRemoteImage()
468+
{
469+
$src = 'https://phpword.readthedocs.io/en/latest/_images/phpword.png';
470+
471+
$phpWord = new \PhpOffice\PhpWord\PhpWord();
472+
$section = $phpWord->addSection();
473+
$html = '<p><img src="' . $src . '" width="150" height="200" style="float: right;"/><img src="' . $src . '" style="float: left;"/></p>';
474+
Html::addHtml($section, $html);
475+
476+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
477+
478+
$baseXpath = '/w:document/w:body/w:p/w:r';
479+
$this->assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape'));
480+
}
481+
/**
482+
* Test parsing of remote img that can be found locally
483+
*/
484+
public function testParseRemoteLocalImage()
485+
{
486+
$src = 'https://fakedomain.io/images/firefox.png';
487+
$localPath = __DIR__ . '/../_files/images/';
488+
$options= [
489+
'IMG_SRC_SEARCH'=> 'https://fakedomain.io/images/',
490+
'IMG_SRC_REPLACE'=> $localPath
491+
];
492+
493+
$phpWord = new \PhpOffice\PhpWord\PhpWord();
494+
$section = $phpWord->addSection();
495+
$html = '<p><img src="' . $src . '" width="150" height="200" style="float: right;"/></p>';
496+
Html::addHtml($section, $html, false, true, $options);
497+
498+
$doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
499+
500+
$baseXpath = '/w:document/w:body/w:p/w:r';
501+
$this->assertTrue($doc->elementExists($baseXpath . '/w:pict/v:shape'));
502+
}
503+
450504
public function testParseLink()
451505
{
452506
$phpWord = new \PhpOffice\PhpWord\PhpWord();

0 commit comments

Comments
 (0)