Skip to content

Commit 344fd52

Browse files
committed
Writer ODText: Support for images inside a textRun
1 parent 1f2ff44 commit 344fd52

File tree

7 files changed

+68
-24
lines changed

7 files changed

+68
-24
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# ![PHPWord](https://rawgit.com/PHPOffice/PHPWord/develop/docs/images/phpword.svg "PHPWord")
22

3-
[![Latest Stable Version](https://poser.pugx.org/phpoffice/phpword/v/stable.png)](https://packagist.org/packages/phpoffice/phpword)
3+
[![Latest Stable Version](https://poser.pugx.org/phpoffice/phpword/v)](https://packagist.org/packages/phpoffice/phpword)
44
[![Coverage Status](https://coveralls.io/repos/github/PHPOffice/PHPWord/badge.svg?branch=master)](https://coveralls.io/github/PHPOffice/PHPWord?branch=master)
5-
[![Total Downloads](https://poser.pugx.org/phpoffice/phpword/downloads.png)](https://packagist.org/packages/phpoffice/phpword)
6-
[![License](https://poser.pugx.org/phpoffice/phpword/license.png)](https://packagist.org/packages/phpoffice/phpword)
7-
[![CI](https://github.com/PHPOffice/PHPWord/actions/workflows/ci.yml/badge.svg)](https://github.com/PHPOffice/PHPWord/actions/workflows/ci.yml)
8-
[![Join the chat at https://gitter.im/PHPOffice/PHPWord](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/PHPOffice/PHPWord)
5+
[![Total Downloads](https://poser.pugx.org/phpoffice/phpword/downloads)](https://packagist.org/packages/phpoffice/phpword)
6+
[![License](https://poser.pugx.org/phpoffice/phpword/license)](https://packagist.org/packages/phpoffice/phpword)
7+
8+
Branch Master : [![PHPWord](https://github.com/PHPOffice/PHPWord/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/PHPOffice/PHPWord/actions/workflows/php.yml)
99

1010
PHPWord is a library written in pure PHP that provides a set of classes to write to and read from different document file formats. The current version of PHPWord supports Microsoft [Office Open XML](http://en.wikipedia.org/wiki/Office_Open_XML) (OOXML or OpenXML), OASIS [Open Document Format for Office Applications](http://en.wikipedia.org/wiki/OpenDocument) (OpenDocument or ODF), [Rich Text Format](http://en.wikipedia.org/wiki/Rich_Text_Format) (RTF), HTML, and PDF.
1111

docs/changes/1.x/1.4.0.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
### Bug fixes
99

10+
- Writer ODText: Support for images inside a textRun by [@Progi1984](https://github.com/Progi1984) fixing [#2240](https://github.com/PHPOffice/PHPWord/issues/2240) in [#2668](https://github.com/PHPOffice/PHPWord/pull/2668)
1011

1112
### Miscellaneous
1213

samples/Sample_13_Images.php

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
<?php
22

33
use PhpOffice\PhpWord\Element\Section;
4+
use PhpOffice\PhpWord\PhpWord;
45
use PhpOffice\PhpWord\Shared\Converter;
56

67
include_once 'Sample_Header.php';
78

89
// New Word document
910
echo date('H:i:s'), ' Create new PhpWord object', EOL;
10-
$phpWord = new \PhpOffice\PhpWord\PhpWord();
11+
$phpWord = new PhpWord();
1112

1213
// Begin code
1314
$section = $phpWord->addSection();
1415
$section->addText('Local image without any styles:');
15-
$section->addImage('resources/_mars.jpg');
16+
$section->addImage(__DIR__ . '/resources/_mars.jpg');
1617

1718
printSeparator($section);
1819
$section->addText('Local image with styles:');
19-
$section->addImage('resources/_earth.jpg', ['width' => 210, 'height' => 210, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
20+
$section->addImage(__DIR__ . '/resources/_earth.jpg', ['width' => 210, 'height' => 210, 'alignment' => \PhpOffice\PhpWord\SimpleType\Jc::CENTER]);
2021

2122
// Remote image
2223
printSeparator($section);
@@ -26,7 +27,7 @@
2627

2728
// Image from string
2829
printSeparator($section);
29-
$source = 'resources/_mars.jpg';
30+
$source = __DIR__ . '/resources/_mars.jpg';
3031
$fileContent = file_get_contents($source);
3132
$section->addText('Image from string');
3233
$section->addImage($fileContent);
@@ -38,7 +39,7 @@
3839
foreach ($wrappingStyles as $wrappingStyle) {
3940
$section->addText("Wrapping style {$wrappingStyle}");
4041
$section->addImage(
41-
'resources/_earth.jpg',
42+
__DIR__ . '/resources/_earth.jpg',
4243
[
4344
'positioning' => 'relative',
4445
'marginTop' => -1,
@@ -57,7 +58,7 @@
5758
//Absolute positioning
5859
$section->addText('Absolute positioning: see top right corner of page');
5960
$section->addImage(
60-
'resources/_mars.jpg',
61+
__DIR__ . '/resources/_mars.jpg',
6162
[
6263
'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
6364
'height' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
@@ -75,7 +76,7 @@
7576
$section->addText('Relative positioning: Horizontal position center relative to column,');
7677
$section->addText('Vertical position top relative to line');
7778
$section->addImage(
78-
'resources/_mars.jpg',
79+
__DIR__ . '/resources/_mars.jpg',
7980
[
8081
'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
8182
'height' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),

src/PhpWord/Writer/ODText/Element/Image.php

+12-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\ODText\Element;
1919

20+
use PhpOffice\PhpWord\Element\Image as ElementImage;
2021
use PhpOffice\PhpWord\Shared\Converter;
2122

2223
/**
@@ -31,9 +32,8 @@ class Image extends AbstractElement
3132
*/
3233
public function write(): void
3334
{
34-
$xmlWriter = $this->getXmlWriter();
3535
$element = $this->getElement();
36-
if (!$element instanceof \PhpOffice\PhpWord\Element\Image) {
36+
if (!$element instanceof ElementImage) {
3737
return;
3838
}
3939

@@ -43,11 +43,16 @@ public function write(): void
4343
$width = Converter::pixelToCm($style->getWidth());
4444
$height = Converter::pixelToCm($style->getHeight());
4545

46-
$xmlWriter->startElement('text:p');
47-
$xmlWriter->writeAttribute('text:style-name', 'IM' . $mediaIndex);
46+
$xmlWriter = $this->getXmlWriter();
47+
48+
if (!$this->withoutP) {
49+
$xmlWriter->startElement('text:p');
50+
$xmlWriter->writeAttribute('text:style-name', 'IM' . $mediaIndex);
51+
}
4852

4953
$xmlWriter->startElement('draw:frame');
5054
$xmlWriter->writeAttribute('draw:style-name', 'fr' . $mediaIndex);
55+
$xmlWriter->writeAttributeIf($this->withoutP, 'draw:text-style-name', 'IM' . $mediaIndex);
5156
$xmlWriter->writeAttribute('draw:name', $element->getElementId());
5257
$xmlWriter->writeAttribute('text:anchor-type', 'as-char');
5358
$xmlWriter->writeAttribute('svg:width', $width . 'cm');
@@ -63,6 +68,8 @@ public function write(): void
6368

6469
$xmlWriter->endElement(); // draw:frame
6570

66-
$xmlWriter->endElement(); // text:p
71+
if (!$this->withoutP) {
72+
$xmlWriter->endElement(); // text:p
73+
}
6774
}
6875
}

src/PhpWord/Writer/Word2007/Element/Container.php

+1-5
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,8 @@ public function write(): void
7070

7171
/**
7272
* Write individual element.
73-
*
74-
* @param bool $withoutP
75-
*
76-
* @return string
7773
*/
78-
private function writeElement(XMLWriter $xmlWriter, Element $element, $withoutP)
74+
private function writeElement(XMLWriter $xmlWriter, Element $element, bool $withoutP): string
7975
{
8076
$elementClass = substr(get_class($element), strrpos(get_class($element), '\\') + 1);
8177
$writerClass = $this->namespace . '\\' . $elementClass;

tests/PhpWordTests/Writer/ODText/Element/ImageTest.php

+33-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace PhpOffice\PhpWordTests\Writer\ODText\Style;
1919

20+
use PhpOffice\PhpWord\PhpWord;
2021
use PhpOffice\PhpWord\Settings;
2122
use PhpOffice\PhpWord\Style\Image;
2223
use PhpOffice\PhpWordTests\TestHelperDOCX;
@@ -42,7 +43,7 @@ protected function tearDown(): void
4243
*/
4344
public function testImage1(): void
4445
{
45-
$phpWord = new \PhpOffice\PhpWord\PhpWord();
46+
$phpWord = new PhpWord();
4647
$section = $phpWord->addSection();
4748
$section->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
4849
$section->addImage(__DIR__ . '/../../../_files/images/mario.gif', ['align' => 'end']);
@@ -59,9 +60,11 @@ public function testImage1(): void
5960

6061
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
6162
self::assertTrue($doc->elementExists($path));
63+
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
6264
self::assertEquals('IM1', $doc->getElementAttribute($path, 'text:style-name'));
6365
$path = '/office:document-content/office:body/office:text/text:section/text:p[3]';
6466
self::assertTrue($doc->elementExists($path));
67+
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
6568
self::assertEquals('IM2', $doc->getElementAttribute($path, 'text:style-name'));
6669
}
6770

@@ -70,7 +73,7 @@ public function testImage1(): void
7073
*/
7174
public function testImage2(): void
7275
{
73-
$phpWord = new \PhpOffice\PhpWord\PhpWord();
76+
$phpWord = new PhpWord();
7477
Settings::setDefaultRtl(false);
7578
$section = $phpWord->addSection();
7679
$section->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
@@ -89,8 +92,36 @@ public function testImage2(): void
8992
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
9093
self::assertTrue($doc->elementExists($path));
9194
self::assertEquals('IM1', $doc->getElementAttribute($path, 'text:style-name'));
95+
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
9296
$path = '/office:document-content/office:body/office:text/text:section/text:p[3]';
9397
self::assertTrue($doc->elementExists($path));
9498
self::assertEquals('IM2', $doc->getElementAttribute($path, 'text:style-name'));
99+
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
100+
}
101+
102+
/**
103+
* Test writing image not in a section.
104+
*/
105+
public function testImageInTextRun(): void
106+
{
107+
$phpWord = new PhpWord();
108+
Settings::setDefaultRtl(false);
109+
$section = $phpWord->addSection();
110+
$textRun = $section->addTextRun();
111+
$textRun->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
112+
$doc = TestHelperDOCX::getDocument($phpWord, 'ODText');
113+
$s2a = '/office:document-content/office:automatic-styles';
114+
$element = "$s2a/style:style[4]";
115+
self::assertEquals('IM1', $doc->getElementAttribute($element, 'style:name'));
116+
$element .= '/style:paragraph-properties';
117+
self::assertEquals('left', $doc->getElementAttribute($element, 'fo:text-align'));
118+
119+
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
120+
self::assertTrue($doc->elementExists($path));
121+
self::assertEquals('P1', $doc->getElementAttribute($path, 'text:style-name'));
122+
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]/draw:frame';
123+
self::assertTrue($doc->elementExists($path));
124+
self::assertTrue($doc->hasElementAttribute($path, 'draw:text-style-name'));
125+
self::assertEquals('IM1', $doc->getElementAttribute($path, 'draw:text-style-name'));
95126
}
96127
}

tests/PhpWordTests/XmlDocument.php

+8
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ public function getElementAttribute(string $path, string $attribute, string $fil
175175
return $this->getElement($path, $file)->getAttribute($attribute);
176176
}
177177

178+
/**
179+
* Return if element attribute exists.
180+
*/
181+
public function hasElementAttribute(string $path, string $attribute, string $file = ''): bool
182+
{
183+
return $this->getElement($path, $file)->hasAttribute($attribute);
184+
}
185+
178186
/**
179187
* Check if element exists.
180188
*/

0 commit comments

Comments
 (0)