Skip to content

Commit

Permalink
Writer ODText: Support for images inside a textRun (#2668)
Browse files Browse the repository at this point in the history
  • Loading branch information
Progi1984 authored Sep 3, 2024
1 parent 1f2ff44 commit a0d00e7
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 24 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# ![PHPWord](https://rawgit.com/PHPOffice/PHPWord/develop/docs/images/phpword.svg "PHPWord")

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

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)

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.

Expand Down
1 change: 1 addition & 0 deletions docs/changes/1.x/1.4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

### Bug fixes

- 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)

### Miscellaneous

Expand Down
15 changes: 8 additions & 7 deletions samples/Sample_13_Images.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
<?php

use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Shared\Converter;

include_once 'Sample_Header.php';

// New Word document
echo date('H:i:s'), ' Create new PhpWord object', EOL;
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord = new PhpWord();

// Begin code
$section = $phpWord->addSection();
$section->addText('Local image without any styles:');
$section->addImage('resources/_mars.jpg');
$section->addImage(__DIR__ . '/resources/_mars.jpg');

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

// Remote image
printSeparator($section);
Expand All @@ -26,7 +27,7 @@

// Image from string
printSeparator($section);
$source = 'resources/_mars.jpg';
$source = __DIR__ . '/resources/_mars.jpg';
$fileContent = file_get_contents($source);
$section->addText('Image from string');
$section->addImage($fileContent);
Expand All @@ -38,7 +39,7 @@
foreach ($wrappingStyles as $wrappingStyle) {
$section->addText("Wrapping style {$wrappingStyle}");
$section->addImage(
'resources/_earth.jpg',
__DIR__ . '/resources/_earth.jpg',
[
'positioning' => 'relative',
'marginTop' => -1,
Expand All @@ -57,7 +58,7 @@
//Absolute positioning
$section->addText('Absolute positioning: see top right corner of page');
$section->addImage(
'resources/_mars.jpg',
__DIR__ . '/resources/_mars.jpg',
[
'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
'height' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
Expand All @@ -75,7 +76,7 @@
$section->addText('Relative positioning: Horizontal position center relative to column,');
$section->addText('Vertical position top relative to line');
$section->addImage(
'resources/_mars.jpg',
__DIR__ . '/resources/_mars.jpg',
[
'width' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
'height' => \PhpOffice\PhpWord\Shared\Converter::cmToPixel(3),
Expand Down
17 changes: 12 additions & 5 deletions src/PhpWord/Writer/ODText/Element/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace PhpOffice\PhpWord\Writer\ODText\Element;

use PhpOffice\PhpWord\Element\Image as ElementImage;
use PhpOffice\PhpWord\Shared\Converter;

/**
Expand All @@ -31,9 +32,8 @@ class Image extends AbstractElement
*/
public function write(): void
{
$xmlWriter = $this->getXmlWriter();
$element = $this->getElement();
if (!$element instanceof \PhpOffice\PhpWord\Element\Image) {
if (!$element instanceof ElementImage) {
return;
}

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

$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'IM' . $mediaIndex);
$xmlWriter = $this->getXmlWriter();

if (!$this->withoutP) {
$xmlWriter->startElement('text:p');
$xmlWriter->writeAttribute('text:style-name', 'IM' . $mediaIndex);
}

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

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

$xmlWriter->endElement(); // text:p
if (!$this->withoutP) {
$xmlWriter->endElement(); // text:p
}
}
}
6 changes: 1 addition & 5 deletions src/PhpWord/Writer/Word2007/Element/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,8 @@ public function write(): void

/**
* Write individual element.
*
* @param bool $withoutP
*
* @return string
*/
private function writeElement(XMLWriter $xmlWriter, Element $element, $withoutP)
private function writeElement(XMLWriter $xmlWriter, Element $element, bool $withoutP): string
{
$elementClass = substr(get_class($element), strrpos(get_class($element), '\\') + 1);
$writerClass = $this->namespace . '\\' . $elementClass;
Expand Down
35 changes: 33 additions & 2 deletions tests/PhpWordTests/Writer/ODText/Element/ImageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace PhpOffice\PhpWordTests\Writer\ODText\Style;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style\Image;
use PhpOffice\PhpWordTests\TestHelperDOCX;
Expand All @@ -42,7 +43,7 @@ protected function tearDown(): void
*/
public function testImage1(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord = new PhpWord();
$section = $phpWord->addSection();
$section->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
$section->addImage(__DIR__ . '/../../../_files/images/mario.gif', ['align' => 'end']);
Expand All @@ -59,9 +60,11 @@ public function testImage1(): void

$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
self::assertTrue($doc->elementExists($path));
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
self::assertEquals('IM1', $doc->getElementAttribute($path, 'text:style-name'));
$path = '/office:document-content/office:body/office:text/text:section/text:p[3]';
self::assertTrue($doc->elementExists($path));
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
self::assertEquals('IM2', $doc->getElementAttribute($path, 'text:style-name'));
}

Expand All @@ -70,7 +73,7 @@ public function testImage1(): void
*/
public function testImage2(): void
{
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$phpWord = new PhpWord();
Settings::setDefaultRtl(false);
$section = $phpWord->addSection();
$section->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
Expand All @@ -89,8 +92,36 @@ public function testImage2(): void
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
self::assertTrue($doc->elementExists($path));
self::assertEquals('IM1', $doc->getElementAttribute($path, 'text:style-name'));
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
$path = '/office:document-content/office:body/office:text/text:section/text:p[3]';
self::assertTrue($doc->elementExists($path));
self::assertEquals('IM2', $doc->getElementAttribute($path, 'text:style-name'));
self::assertFalse($doc->hasElementAttribute($path, 'draw:text-style-name'));
}

/**
* Test writing image not in a section.
*/
public function testImageInTextRun(): void
{
$phpWord = new PhpWord();
Settings::setDefaultRtl(false);
$section = $phpWord->addSection();
$textRun = $section->addTextRun();
$textRun->addImage(__DIR__ . '/../../../_files/images/earth.jpg');
$doc = TestHelperDOCX::getDocument($phpWord, 'ODText');
$s2a = '/office:document-content/office:automatic-styles';
$element = "$s2a/style:style[4]";
self::assertEquals('IM1', $doc->getElementAttribute($element, 'style:name'));
$element .= '/style:paragraph-properties';
self::assertEquals('left', $doc->getElementAttribute($element, 'fo:text-align'));

$path = '/office:document-content/office:body/office:text/text:section/text:p[2]';
self::assertTrue($doc->elementExists($path));
self::assertEquals('P1', $doc->getElementAttribute($path, 'text:style-name'));
$path = '/office:document-content/office:body/office:text/text:section/text:p[2]/draw:frame';
self::assertTrue($doc->elementExists($path));
self::assertTrue($doc->hasElementAttribute($path, 'draw:text-style-name'));
self::assertEquals('IM1', $doc->getElementAttribute($path, 'draw:text-style-name'));
}
}
8 changes: 8 additions & 0 deletions tests/PhpWordTests/XmlDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ public function getElementAttribute(string $path, string $attribute, string $fil
return $this->getElement($path, $file)->getAttribute($attribute);
}

/**
* Return if element attribute exists.
*/
public function hasElementAttribute(string $path, string $attribute, string $file = ''): bool
{
return $this->getElement($path, $file)->hasAttribute($attribute);
}

/**
* Check if element exists.
*/
Expand Down

0 comments on commit a0d00e7

Please sign in to comment.