Skip to content

Commit 46a0768

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into develop
2 parents 07b8430 + 595bcc3 commit 46a0768

File tree

11 files changed

+192
-52
lines changed

11 files changed

+192
-52
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
namespace PhpOffice\PhpWord\Exceptions;
3+
4+
use Exception;
5+
6+
/**
7+
* InvalidImageException
8+
*
9+
* Exception used for when an image is not found
10+
*
11+
* @package PHPWord
12+
*/
13+
class InvalidImageException extends Exception
14+
{
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
namespace PhpOffice\PhpWord\Exceptions;
3+
4+
use Exception;
5+
6+
/**
7+
* UnsupportedImageTypeException
8+
*
9+
* Exception used for when an image type is unsupported
10+
*
11+
* @package PHPWord
12+
*/
13+
class UnsupportedImageTypeException extends Exception
14+
{
15+
}

Classes/PHPWord/Section/Image.php

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
* @version 0.7.0
2626
*/
2727

28+
use PhpOffice\PhpWord\Exceptions\InvalidImageException;
29+
use PhpOffice\PhpWord\Exceptions\UnsupportedImageTypeException;
30+
2831
/**
2932
* Class PHPWord_Section_Image
3033
*/
3134
class PHPWord_Section_Image
3235
{
33-
3436
/**
3537
* Image Src
3638
*
@@ -64,42 +66,43 @@ class PHPWord_Section_Image
6466
* Create a new Image
6567
*
6668
* @param string $src
67-
* @param mixed style
69+
* @param mixed $style
70+
* @param bool $isWatermark
71+
* @throws InvalidImageException|UnsupportedImageTypeException
6872
*/
6973
public function __construct($src, $style = null, $isWatermark = false)
7074
{
71-
$_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff');
72-
73-
$inf = pathinfo($src);
74-
$ext = strtolower($inf['extension']);
75-
76-
if (file_exists($src) && in_array($ext, $_supportedImageTypes)) {
77-
$this->_src = $src;
78-
$this->_isWatermark = $isWatermark;
79-
$this->_style = new PHPWord_Style_Image();
80-
81-
if (!is_null($style) && is_array($style)) {
82-
foreach ($style as $key => $value) {
83-
if (substr($key, 0, 1) != '_') {
84-
$key = '_' . $key;
85-
}
86-
$this->_style->setStyleValue($key, $value);
87-
}
88-
}
75+
$supportedImageTypes = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM);
8976

90-
if (isset($style['wrappingStyle'])) {
91-
$this->_style->setWrappingStyle($style['wrappingStyle']);
92-
}
77+
if (!file_exists($src)) {
78+
throw new InvalidImageException;
79+
}
9380

94-
if ($this->_style->getWidth() == null && $this->_style->getHeight() == null) {
95-
$imgData = getimagesize($this->_src);
96-
$this->_style->setWidth($imgData[0]);
97-
$this->_style->setHeight($imgData[1]);
81+
if (!in_array(exif_imagetype($src), $supportedImageTypes)) {
82+
throw new UnsupportedImageTypeException;
83+
}
84+
85+
$this->_src = $src;
86+
$this->_isWatermark = $isWatermark;
87+
$this->_style = new PHPWord_Style_Image();
88+
89+
if (!is_null($style) && is_array($style)) {
90+
foreach ($style as $key => $value) {
91+
if (substr($key, 0, 1) != '_') {
92+
$key = '_' . $key;
93+
}
94+
$this->_style->setStyleValue($key, $value);
9895
}
96+
}
97+
98+
if (isset($style['wrappingStyle'])) {
99+
$this->_style->setWrappingStyle($style['wrappingStyle']);
100+
}
99101

100-
return $this;
101-
} else {
102-
return false;
102+
if ($this->_style->getWidth() == null && $this->_style->getHeight() == null) {
103+
$imgData = getimagesize($this->_src);
104+
$this->_style->setWidth($imgData[0]);
105+
$this->_style->setHeight($imgData[1]);
103106
}
104107
}
105108

Classes/PHPWord/Writer/Word2007/Base.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ protected function _writePreserveText(PHPWord_Shared_XMLWriter $objWriter = null
285285
$SpIsObject = ($styleParagraph instanceof PHPWord_Style_Paragraph) ? true : false;
286286

287287
$arrText = $textrun->getText();
288+
if (!is_array($arrText)) {
289+
$arrText = array($arrText);
290+
}
288291

289292
$objWriter->startElement('w:p');
290293

Tests/PHPWord/Section/ImageTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,32 @@ public function testConstructWithStyle()
3333
$this->assertInstanceOf('PHPWord_Style_Image', $oImage->getStyle());
3434
}
3535

36+
public function testValidImageTypes()
37+
{
38+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars_noext_jpg");
39+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars.jpg");
40+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mario.gif");
41+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/firefox.png");
42+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/duke_nukem.bmp");
43+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/angela_merkel.tif");
44+
}
45+
46+
/**
47+
* @expectedException \PhpOffice\PhpWord\Exceptions\InvalidImageException
48+
*/
49+
public function testImageNotFound()
50+
{
51+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/thisisnotarealimage");
52+
}
53+
54+
/**
55+
* @expectedException \PhpOffice\PhpWord\Exceptions\UnsupportedImageTypeException
56+
*/
57+
public function testInvalidImageTypes()
58+
{
59+
new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/alexz-johnson.pcx");
60+
}
61+
3662
public function testStyle()
3763
{
3864
$oImage = new PHPWord_Section_Image(\join(

Tests/PHPWord/Writer/Word2007/BaseTest.php

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function tearDown()
2020
TestHelperDOCX::clear();
2121
}
2222

23-
public function testWriteImagePosition()
23+
public function testWriteImage_Position()
2424
{
2525
$PHPWord = new PHPWord();
2626
$section = $PHPWord->createSection();
@@ -42,7 +42,7 @@ public function testWriteImagePosition()
4242
$this->assertRegExp('/position:absolute;/', $style);
4343
}
4444

45-
public function testWriteParagraphStyleAlign()
45+
public function testWriteParagraphStyle_Align()
4646
{
4747
$PHPWord = new PHPWord();
4848
$section = $PHPWord->createSection();
@@ -55,10 +55,34 @@ public function testWriteParagraphStyleAlign()
5555
$this->assertEquals('right', $element->getAttribute('w:val'));
5656
}
5757

58+
public function testWriteCellStyle_CellGridSpan()
59+
{
60+
$PHPWord = new PHPWord();
61+
$section = $PHPWord->createSection();
62+
63+
$table = $section->addTable();
64+
65+
$table->addRow();
66+
$cell = $table->addCell(200);
67+
$cell->getStyle()->setGridSpan(5);
68+
69+
$table->addRow();
70+
$table->addCell(40);
71+
$table->addCell(40);
72+
$table->addCell(40);
73+
$table->addCell(40);
74+
$table->addCell(40);
75+
76+
$doc = TestHelperDOCX::getDocument($PHPWord);
77+
$element = $doc->getElement('/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:gridSpan');
78+
79+
$this->assertEquals(5, $element->getAttribute('w:val'));
80+
}
81+
5882
/**
5983
* Test write paragraph pagination
6084
*/
61-
public function testWriteParagraphStylePagination()
85+
public function testWriteParagraphStyle_Pagination()
6286
{
6387
// Create the doc
6488
$PHPWord = new PHPWord();
@@ -85,27 +109,18 @@ public function testWriteParagraphStylePagination()
85109
}
86110
}
87111

88-
public function testWriteCellStyleCellGridSpan()
112+
public function testWritePreserveText()
89113
{
90114
$PHPWord = new PHPWord();
91115
$section = $PHPWord->createSection();
116+
$footer = $section->createFooter();
92117

93-
$table = $section->addTable();
94-
95-
$table->addRow();
96-
$cell = $table->addCell(200);
97-
$cell->getStyle()->setGridSpan(5);
98-
99-
$table->addRow();
100-
$table->addCell(40);
101-
$table->addCell(40);
102-
$table->addCell(40);
103-
$table->addCell(40);
104-
$table->addCell(40);
118+
$footer->addPreserveText('{PAGE}');
105119

106120
$doc = TestHelperDOCX::getDocument($PHPWord);
107-
$element = $doc->getElement('/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:gridSpan');
121+
$preserve = $doc->getElement("w:p/w:r[2]/w:instrText", 'word/footer1.xml');
108122

109-
$this->assertEquals(5, $element->getAttribute('w:val'));
123+
$this->assertEquals('PAGE', $preserve->nodeValue);
124+
$this->assertEquals('preserve', $preserve->getAttribute('xml:space'));
110125
}
111-
}
126+
}

Tests/_files/images/alexz-johnson.pcx

283 KB
Binary file not shown.

Tests/_files/images/angela_merkel.tif

373 KB
Binary file not shown.

Tests/_files/images/mars_noext_jpg

23.9 KB
Binary file not shown.

Tests/_inc/TestHelperDOCX.php

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
namespace PHPWord\Tests;
33

44
use PHPWord;
5+
use DOMDocument;
56

67
class TestHelperDOCX
78
{
89
static protected $file;
910

1011
/**
1112
* @param \PHPWord $PHPWord
12-
* @return \PHPWord\Tests\XmlDocument
13+
* @return \PHPWord\Tests\Xml_Document
1314
*/
1415
public static function getDocument(PHPWord $PHPWord)
1516
{
@@ -28,7 +29,7 @@ public static function getDocument(PHPWord $PHPWord)
2829
$zip->close();
2930
}
3031

31-
return new XmlDocument(sys_get_temp_dir() . '/PHPWord_Unit_Test/');
32+
return new Xml_Document(sys_get_temp_dir() . '/PHPWord_Unit_Test/');
3233
}
3334

3435
public static function clear()
@@ -59,3 +60,65 @@ public static function deleteDir($dir)
5960
rmdir($dir);
6061
}
6162
}
63+
64+
class Xml_Document
65+
{
66+
/** @var string $path */
67+
private $path;
68+
69+
/** @var \DOMDocument $dom */
70+
private $dom;
71+
72+
/** @var \DOMXpath $xpath */
73+
private $xpath;
74+
75+
/** @var string $file */
76+
private $file;
77+
78+
/**
79+
* @param string $path
80+
*/
81+
public function __construct($path)
82+
{
83+
$this->path = realpath($path);
84+
}
85+
86+
/**
87+
* @param string $file
88+
* @return \DOMDocument
89+
*/
90+
public function getFileDom($file = 'word/document.xml')
91+
{
92+
if (null !== $this->dom && $file === $this->file) {
93+
return $this->dom;
94+
}
95+
96+
$this->xpath = null;
97+
$this->file = $file;
98+
99+
$file = $this->path . '/' . $file;
100+
$this->dom = new DOMDocument();
101+
$this->dom->load($file);
102+
return $this->dom;
103+
}
104+
105+
/**
106+
* @param string $path
107+
* @param string $file
108+
* @return \DOMElement
109+
*/
110+
public function getElement($path, $file = 'word/document.xml')
111+
{
112+
if ($this->dom === null || $file !== $this->file) {
113+
$this->getFileDom($file);
114+
}
115+
116+
if (null === $this->xpath) {
117+
$this->xpath = new \DOMXpath($this->dom);
118+
119+
}
120+
121+
$elements = $this->xpath->query($path);
122+
return $elements->item(0);
123+
}
124+
}

0 commit comments

Comments
 (0)