Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update a docx containing an image #1212

Open
wadmiraal opened this issue Nov 30, 2017 · 7 comments
Open

Cannot update a docx containing an image #1212

wadmiraal opened this issue Nov 30, 2017 · 7 comments
Assignees

Comments

@wadmiraal
Copy link

wadmiraal commented Nov 30, 2017

I need to generate a pretty large Word document, with lots of data from a database.

Instead of fetching all the data in one go, and risking a timeout, I fetch a set number of elements at a time, and process the document in a batch.

A very crude simplification would look like this:

$filepath = '/absolute/path/to/file.docx';

// Initial batch run:
$phpword = new \PhpOffice\PhpWord\PhpWord();
$phpword->getSettings()->setUpdateFields(true);
// Set some settings...
$section = $phpword->addSection();
// Add text, images, etc;
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

// Subsequent batch runs:
$phpword = \PhpOffice\PhpWord\IOFactory::load($filepath);
$phpword->getSettings()->setUpdateFields(true);
// Set some settings...
$section = $phpword->addSection();
// Add text, images, etc;
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

So far so good.

However (and I've been banging my head for hours now), if at one point I add an image, I can no longer update the document. It will throw an exception: Could not close zip file, and PHP throws the following warning: ZipArchive::close(): Invalid or uninitialized Zip object.

If I use PeclZip, it will not throw any error, but the file won't be readable.

Expected Behavior

I would expect a document to be loaded correctly, and then be save-able again. This is the case as long as no image is added.

Current Behavior

If the document contains an image, it can be opened, but not updated.

I tried copying the file prior to opening it, renaming it, to no avail. I checked file permissions, but it doesn't seem to matter. I updated the user:group of the webserver to make certain it wasn't that either: no success.

Failure Information

\PhpOffice\PhpWord\Exception\Exception thrown: Could not close zip file (in \PhpOffice\PhpWord\Shared\ZipArchive::close())
PHP warning: ZipArchive::close(): Invalid or uninitialized Zip object

How to Reproduce

Running this code triggers the error (I'm on the latest dev commit):

$filepath = '/absolute/path/to/file.docx';
$image = '/absolute/path/to/image.png';

$phpword = new \PhpOffice\PhpWord\PhpWord();
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addImage($image);
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

sleep(5); // This is not needed, but just to make absolutely sure 

$phpword = \PhpOffice\PhpWord\IOFactory::load($filepath);
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addText('Lorem ipsum');
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

Context

  • PHP version: 5.6.31 and 7.1.12
  • PHPWord version: master-dev
@wadmiraal
Copy link
Author

wadmiraal commented Nov 30, 2017

I forgot to mention that the initial exception is this one:

\PhpOffice\PhpWord\Exception\InvalidImageException: Invalid image: zip:https:///absolute/path/to/file.docx#word/media/section_image1.png (in \PhpOffice\PhpWord\Element\Image::checkImage())

I applied the following changes, which gets a step further, but still fails to close the document (Exception described above):

diff --git a/src/PhpWord/Element/Image.php b/src/PhpWord/Element/Image.php
index f1f6bab..68c813e 100644
--- a/src/PhpWord/Element/Image.php
+++ b/src/PhpWord/Element/Image.php
@@ -454,7 +454,7 @@ class Image extends AbstractElement
 
         $zip = new ZipArchive();
         if ($zip->open($zipFilename) !== false) {
-            if ($zip->locateName($imageFilename)) {
+            if ($zip->locateName($imageFilename) !== false) {
                 $imageContent = $zip->getFromName($imageFilename);
                 if ($imageContent !== false) {
                     file_put_contents($tempFilename, $imageContent);

@FBnil
Copy link

FBnil commented Dec 1, 2017

what if you add the sections inside a function block? (so that variables get undefined when the function ends)
I suspect you actually need unset() to undefine/destroy all lingering variables before they get reused.
(or you are on to a bug)

@wadmiraal
Copy link
Author

wadmiraal commented Dec 1, 2017 via email

@troosan
Copy link
Contributor

troosan commented Dec 4, 2017

@wadmiraal could you give it a try with the dev-develop version, just to make sure this is still valid?

@wadmiraal
Copy link
Author

I just tried again with the latest dev-develop branch. Clean install in another folder, called composer install to get a fresh copy of all dependencies.

I then modified src/PhpWord/Element/Image.php again, as noted in my previous comment, as the image is at position 0, which is a "falsy" value, and breaks the loading of a Docx file.

I then created the following PHP file in the root of the PHPWord repo (test.php):

require 'vendor/autoload.php';

$filepath = 'file.docx';
$image = 'image.png';

$phpword = new \PhpOffice\PhpWord\PhpWord();
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addImage($image);
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

sleep(5); // This is not needed, but just to make absolutely sure

$phpword = \PhpOffice\PhpWord\IOFactory::load($filepath);
$phpword->getSettings()->setUpdateFields(true);
$phpword->setDefaultFontName('Verdana');
$phpword->setDefaultFontSize(9);
$section = $phpword->addSection();
$section->addText('Lorem ipsum');
$section->addTextBreak();
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpword, 'Word2007');
$writer->save($filepath);

Note: Make sure file.docx doesn't exist before executing the file.

I then executed it like this: php test.php.

Stack trace:

PHP Warning:  ZipArchive::close(): Invalid or uninitialized Zip object in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php on line 163
PHP Stack trace:
PHP   1. {main}() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:0
PHP   2. PhpOffice\PhpWord\Writer\Word2007->save() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:28
PHP   3. PhpOffice\PhpWord\Writer\AbstractWriter->addFilesToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/Word2007.php:111
PHP   4. PhpOffice\PhpWord\Writer\AbstractWriter->addFileToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:362
PHP   5. PhpOffice\PhpWord\Shared\ZipArchive->close() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:391
PHP   6. ZipArchive->close() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php:163

Warning: ZipArchive::close(): Invalid or uninitialized Zip object in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php on line 163

Call Stack:
    0.0002     364584   1. {main}() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:0
    5.0326    3125784   2. PhpOffice\PhpWord\Writer\Word2007->save() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:28
    5.0329    3126936   3. PhpOffice\PhpWord\Writer\AbstractWriter->addFilesToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/Word2007.php:111
    5.0329    3126992   4. PhpOffice\PhpWord\Writer\AbstractWriter->addFileToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:362
    5.0330    3127360   5. PhpOffice\PhpWord\Shared\ZipArchive->close() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:391
    5.0330    3127360   6. ZipArchive->close() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php:163

PHP Fatal error:  Uncaught PhpOffice\PhpWord\Exception\Exception: Could not close zip file file.docx. in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php:164
Stack trace:
#0 /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php(391): PhpOffice\PhpWord\Shared\ZipArchive->close()
#1 /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php(362): PhpOffice\PhpWord\Writer\AbstractWriter->addFileToPackage(Object(PhpOffice\PhpWord\Shared\ZipArchive), 'file.docx#word/...', 'word/media/sect...')
#2 /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/Word2007.php(111): PhpOffice\PhpWord\Writer\AbstractWriter->addFilesToPackage(Object(PhpOffice\PhpWord\Shared\ZipArchive), Array)
#3 /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php(28): PhpOffice\PhpWord\Writer\W in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php on line 164

Fatal error: Uncaught PhpOffice\PhpWord\Exception\Exception: Could not close zip file file.docx. in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php on line 164

PhpOffice\PhpWord\Exception\Exception: Could not close zip file file.docx. in /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Shared/ZipArchive.php on line 164

Call Stack:
    0.0002     364584   1. {main}() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:0
    5.0326    3125784   2. PhpOffice\PhpWord\Writer\Word2007->save() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/test.php:28
    5.0329    3126936   3. PhpOffice\PhpWord\Writer\AbstractWriter->addFilesToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/Word2007.php:111
    5.0329    3126992   4. PhpOffice\PhpWord\Writer\AbstractWriter->addFileToPackage() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:362
    5.0330    3127360   5. PhpOffice\PhpWord\Shared\ZipArchive->close() /Users/wadmiraal/Documents/inovae/projects/wto/tprqa/sites/all/libraries/PHPWord/src/PhpWord/Writer/AbstractWriter.php:391

@troosan troosan self-assigned this Dec 29, 2017
@vladshoob
Copy link

Experiencing same problem after adding image.

I am adding image like this:
$section->addImage($path);

And when trying to do it second time it errors out:

Invalid image: zip:https://F:\WEB\xampp\htdocs\workflow\storage/app/files/FILENAME.docx#word/media/section_image1.jpg

@oscardrm
Copy link

I have the same problem any solution ? The file forget de previous images
Check the result:
Screenshot_20200522-184852_Stack Exchange

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants