diff --git a/docs/elements.rst b/docs/elements.rst index d68ee035dc..27fd76b86c 100644 --- a/docs/elements.rst +++ b/docs/elements.rst @@ -232,7 +232,7 @@ To add an image, use the ``addImage`` method to sections, headers, footers, text $section->addImage($src, [$style]); -- ``$src``. String path to a local image or URL of a remote image. +- ``$src``. String path to a local image, URL of a remote image or the image data, as a string. - ``$style``. See :ref:`image-style`. Examples: @@ -254,6 +254,8 @@ Examples: $footer->addImage('http://example.com/image.php'); $textrun = $section->addTextRun(); $textrun->addImage('http://php.net/logo.jpg'); + $source = file_get_contents('/path/to/my/images/earth.jpg'); + $textrun->addImage($source); Watermarks ~~~~~~~~~~ diff --git a/src/PhpWord/Element/Image.php b/src/PhpWord/Element/Image.php index bf2b03d635..d7e5a66530 100644 --- a/src/PhpWord/Element/Image.php +++ b/src/PhpWord/Element/Image.php @@ -35,6 +35,7 @@ class Image extends AbstractElement const SOURCE_LOCAL = 'local'; // Local images const SOURCE_GD = 'gd'; // Generated using GD const SOURCE_ARCHIVE = 'archive'; // Image in archives zip://$archive#$image + const SOURCE_STRING = 'string'; // Image from string /** * Image source @@ -379,6 +380,8 @@ private function checkImage($source) // Check image data if ($this->sourceType == self::SOURCE_ARCHIVE) { $imageData = $this->getArchiveImageSize($source); + } else if ($this->sourceType == self::SOURCE_STRING) { + $imageData = $this->getStringImageSize($source); } else { $imageData = @getimagesize($source); } @@ -416,9 +419,15 @@ private function setSourceType($source) } elseif (strpos($source, 'zip://') !== false) { $this->memoryImage = false; $this->sourceType = self::SOURCE_ARCHIVE; + } elseif (filter_var($source, FILTER_VALIDATE_URL) !== false) { + $this->memoryImage = true; + $this->sourceType = self::SOURCE_GD; + } elseif (@file_exists($source)) { + $this->memoryImage = false; + $this->sourceType = self::SOURCE_LOCAL; } else { - $this->memoryImage = (filter_var($source, FILTER_VALIDATE_URL) !== false); - $this->sourceType = $this->memoryImage ? self::SOURCE_GD : self::SOURCE_LOCAL; + $this->memoryImage = true; + $this->sourceType = self::SOURCE_STRING; } } @@ -460,6 +469,24 @@ private function getArchiveImageSize($source) return $imageData; } + /** + * get image size from string + * + * @param string $source + * + * @codeCoverageIgnore this method is just a replacement for getimagesizefromstring which exists only as of PHP 5.4 + */ + private function getStringImageSize($source) + { + if (!function_exists('getimagesizefromstring')) { + $uri = 'data://application/octet-stream;base64,' . base64_encode($source); + return @getimagesize($uri); + } else { + return @getimagesizefromstring($source); + } + return false; + } + /** * Set image functions and extensions. * diff --git a/tests/PhpWord/Element/ImageTest.php b/tests/PhpWord/Element/ImageTest.php index c463b0c4d4..9ef9694bd5 100644 --- a/tests/PhpWord/Element/ImageTest.php +++ b/tests/PhpWord/Element/ImageTest.php @@ -156,4 +156,57 @@ public function testArchivedImage() $image = new Image("zip://{$archiveFile}#{$imageFile}"); $this->assertEquals('image/jpeg', $image->getImageType()); } + + /** + * Test getting image as string + */ + public function testImageAsStringFromFile() + { + $image = new Image(__DIR__ . '/../_files/images/earth.jpg'); + + $this->assertNotNull($image->getImageStringData()); + $this->assertNotNull($image->getImageStringData(true)); + } + + /** + * Test getting image from zip as string + */ + public function testImageAsStringFromZip() + { + $archiveFile = __DIR__ . '/../_files/documents/reader.docx'; + $imageFile = 'word/media/image1.jpeg'; + $image = new Image("zip://{$archiveFile}#{$imageFile}"); + + $this->assertNotNull($image->getImageStringData()); + $this->assertNotNull($image->getImageStringData(true)); + } + + /** + * Test construct from string + */ + public function testConstructFromString() + { + $source = file_get_contents(__DIR__ . '/../_files/images/earth.jpg'); + + $image = new Image($source); + $this->assertInstanceOf('PhpOffice\\PhpWord\\Element\\Image', $image); + $this->assertEquals($source, $image->getSource()); + $this->assertEquals(md5($source), $image->getMediaId()); + $this->assertEquals('image/jpeg', $image->getImageType()); + $this->assertEquals('jpg', $image->getImageExtension()); + $this->assertEquals('imagecreatefromjpeg', $image->getImageCreateFunction()); + $this->assertEquals('imagejpeg', $image->getImageFunction()); + $this->assertTrue($image->isMemImage()); + } + + /** + * Test invalid string image + * + * @expectedException \PhpOffice\PhpWord\Exception\InvalidImageException + */ + public function testInvalidImageString() + { + $object = new Image('this_is-a_non_valid_image'); + $object->getSource(); + } }