Emulate \ZipArchive::extractTo for PCLZip

This commit is contained in:
Ivan Lanin 2014-04-18 01:58:03 +07:00
parent 4db75c37a9
commit f5f03a5b2b
11 changed files with 118 additions and 96 deletions

View File

@ -60,8 +60,7 @@ echo date('H:i:s'), " Write to Word2007 format", EOL;
$document->saveAs($name); $document->saveAs($name);
rename($name, "results/{$name}"); rename($name, "results/{$name}");
$writers = array('Word2007' => 'docx'); echo getEndingNotes(array('Word2007' => 'docx'));
echo getEndingNotes($writers);
if (!CLI) { if (!CLI) {
include_once 'Sample_Footer.php'; include_once 'Sample_Footer.php';
} }

View File

@ -18,8 +18,7 @@ echo date('H:i:s'), " Write to Word2007 format", EOL;
$document->saveAs($name); $document->saveAs($name);
rename($name, "results/{$name}"); rename($name, "results/{$name}");
$writers = array('Word2007' => 'docx'); echo getEndingNotes(array('Word2007' => 'docx'));
echo getEndingNotes($writers);
if (!CLI) { if (!CLI) {
include_once 'Sample_Footer.php'; include_once 'Sample_Footer.php';
} }

View File

@ -9,6 +9,7 @@
namespace PhpOffice\PhpWord\Element; namespace PhpOffice\PhpWord\Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Exception\InvalidImageException; use PhpOffice\PhpWord\Exception\InvalidImageException;
use PhpOffice\PhpWord\Exception\UnsupportedImageTypeException; use PhpOffice\PhpWord\Exception\UnsupportedImageTypeException;
use PhpOffice\PhpWord\Style\Image as ImageStyle; use PhpOffice\PhpWord\Style\Image as ImageStyle;
@ -283,7 +284,8 @@ class Image extends AbstractElement
list($zipFilename, $imageFilename) = explode('#', $source); list($zipFilename, $imageFilename) = explode('#', $source);
$tempFilename = tempnam(sys_get_temp_dir(), 'PHPWordImage'); $tempFilename = tempnam(sys_get_temp_dir(), 'PHPWordImage');
$zip = new \ZipArchive(); $zipClass = Settings::getZipClass();
$zip = new $zipClass();
if ($zip->open($zipFilename) !== false) { if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) { if ($zip->locateName($imageFilename)) {
$imageContent = $zip->getFromName($imageFilename); $imageContent = $zip->getFromName($imageFilename);

View File

@ -12,7 +12,6 @@ namespace PhpOffice\PhpWord\Reader;
use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Footnote; use PhpOffice\PhpWord\Footnote;
use PhpOffice\PhpWord\Endnotes;
use PhpOffice\PhpWord\DocumentProperties; use PhpOffice\PhpWord\DocumentProperties;
use PhpOffice\PhpWord\Shared\XMLReader; use PhpOffice\PhpWord\Shared\XMLReader;
use PhpOffice\PhpWord\Element\Section; use PhpOffice\PhpWord\Element\Section;

View File

@ -11,9 +11,9 @@ namespace PhpOffice\PhpWord\Shared;
use PhpOffice\PhpWord\Exception\Exception; use PhpOffice\PhpWord\Exception\Exception;
// PCLZIP needs the temp path to end in a back slash
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
if (!defined('PCLZIP_TEMPORARY_DIR')) { if (!defined('PCLZIP_TEMPORARY_DIR')) {
// PCLZIP needs the temp path to end in a back slash
define('PCLZIP_TEMPORARY_DIR', sys_get_temp_dir() . '/'); define('PCLZIP_TEMPORARY_DIR', sys_get_temp_dir() . '/');
} }
require_once 'PCLZip/pclzip.lib.php'; require_once 'PCLZip/pclzip.lib.php';
@ -67,7 +67,7 @@ class ZipArchive
} }
/** /**
* Close this zip archive * Close this zip archive (emulate \ZipArchive)
* *
* @codeCoverageIgnore * @codeCoverageIgnore
*/ */
@ -76,7 +76,7 @@ class ZipArchive
} }
/** /**
* Add a new file to the zip archive. * Add a new file to the zip archive (emulate \ZipArchive)
* *
* @param string $filename Directory/Name of the file to add to the zip archive * @param string $filename Directory/Name of the file to add to the zip archive
* @param string $localname Directory/Name of the file added to the zip * @param string $localname Directory/Name of the file added to the zip
@ -104,15 +104,11 @@ class ZipArchive
$localnameParts["dirname"] $localnameParts["dirname"]
); );
if ($res == 0) { return ($res == 0) ? false : true;
throw new Exception("Error zipping files : " . $this->zip->errorInfo(true));
}
return true;
} }
/** /**
* Add a new file to the zip archive from a string of raw data. * Add a new file to the zip archive from a string of raw data (emulate \ZipArchive)
* *
* @param string $localname Directory/Name of the file to add to the zip archive * @param string $localname Directory/Name of the file to add to the zip archive
* @param string $contents String of data to add to the zip archive * @param string $contents String of data to add to the zip archive
@ -134,21 +130,18 @@ class ZipArchive
PCLZIP_OPT_ADD_PATH, PCLZIP_OPT_ADD_PATH,
$filenameParts["dirname"] $filenameParts["dirname"]
); );
if ($res == 0) {
throw new Exception("Error zipping files : " . $this->zip->errorInfo(true));
}
// Remove temp file // Remove temp file
unlink($this->tempDir . '/' . $filenameParts["basename"]); @unlink($this->tempDir . '/' . $filenameParts["basename"]);
return true; return ($res == 0) ? false : true;
} }
/** /**
* Find if given file name exist in archive (Emulate ZipArchive locateName()) * Returns the index of the entry in the archive (emulate \ZipArchive)
* *
* @param string $filename Filename for the file in zip archive * @param string $filename Filename for the file in zip archive
* @return boolean * @return integer|false
*/ */
public function locateName($filename) public function locateName($filename)
{ {
@ -163,42 +156,25 @@ class ZipArchive
} }
} }
return ($listIndex > -1); return ($listIndex > -1) ? $listIndex : false;
} }
/** /**
* Extract file from archive by given file name (Emulate ZipArchive getFromName()) * Extract file from archive by given file name (emulate \ZipArchive)
* *
* @param string $filename Filename for the file in zip archive * @param string $filename Filename for the file in zip archive
* @return string $contents File string contents * @return string|false $contents File string contents
*/ */
public function getFromName($filename) public function getFromName($filename)
{ {
$list = $this->zip->listContent(); $listIndex = $this->locateName($filename);
$listCount = count($list); $contents = false;
$listIndex = -1;
$contents = null;
for ($i = 0; $i < $listCount; ++$i) { if ($listIndex !== false) {
if (strtolower($list[$i]["filename"]) == strtolower($filename) ||
strtolower($list[$i]["stored_filename"]) == strtolower($filename)) {
$listIndex = $i;
break;
}
}
if ($listIndex != -1) {
$extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING); $extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING);
} else { } else {
$filename = substr($filename, 1); $filename = substr($filename, 1);
$listIndex = -1; $listIndex = $this->locateName($filename);
for ($i = 0; $i < $listCount; ++$i) {
if (strtolower($list[$i]["filename"]) == strtolower($filename) ||
strtolower($list[$i]["stored_filename"]) == strtolower($filename)) {
$listIndex = $i;
break;
}
}
$extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING); $extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING);
} }
if ((is_array($extracted)) && ($extracted != 0)) { if ((is_array($extracted)) && ($extracted != 0)) {
@ -209,10 +185,11 @@ class ZipArchive
} }
/** /**
* Returns the name of an entry using its index * Returns the name of an entry using its index (emulate \ZipArchive)
* *
* @param integer $index * @param integer $index
* @return string|false * @return string|false
* @since 0.10.0
*/ */
public function getNameIndex($index) public function getNameIndex($index)
{ {
@ -223,4 +200,39 @@ class ZipArchive
return false; return false;
} }
} }
/**
* Extract the archive contents (emulate \ZipArchive)
*
* @param string $destination
* @param string|array $entries
* @return boolean
* @since 0.10.0
*/
public function extractTo($destination, $entries = null)
{
if (!is_dir($destination)) {
return false;
}
// Extract all files
if (is_null($entries)) {
$result = $this->zip->extract(PCLZIP_OPT_PATH, $destination);
return ($result > 0) ? true : false;
}
// Extract by entries
if (!is_array($entries)) {
$entries = array($entries);
}
foreach ($entries as $entry) {
$entryIndex = $this->locateName($entry);
$result = $this->zip->extractByIndex($entryIndex, PCLZIP_OPT_PATH, $destination);
if ($result <= 0) {
return false;
}
}
return true;
}
} }

View File

@ -714,7 +714,9 @@ class HTML extends AbstractWriter implements WriterInterface
if ($element->getSourceType() == Image::SOURCE_ARCHIVE) { if ($element->getSourceType() == Image::SOURCE_ARCHIVE) {
$source = substr($source, 6); $source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source); list($zipFilename, $imageFilename) = explode('#', $source);
$zip = new \ZipArchive();
$zipClass = \PhpOffice\PhpWord\Settings::getZipClass();
$zip = new $zipClass();
if ($zip->open($zipFilename) !== false) { if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) { if ($zip->locateName($imageFilename)) {
$zip->extractTo($this->getTempDir(), $imageFilename); $zip->extractTo($this->getTempDir(), $imageFilename);

View File

@ -50,7 +50,6 @@ class ODText extends AbstractWriter implements WriterInterface
* *
* @param string $filename * @param string $filename
* @throws \PhpOffice\PhpWord\Exception\Exception * @throws \PhpOffice\PhpWord\Exception\Exception
* @todo Not in \ZipArchive::CM_STORE mode
*/ */
public function save($filename = null) public function save($filename = null)
{ {

View File

@ -109,7 +109,7 @@ abstract class AbstractRenderer extends \PhpOffice\PhpWord\Writer\HTML
/** /**
* Set Paper Size * Set Paper Size
* *
* @param string $pValue Paper size = PAPERSIZE_A4 * @param int $pValue Paper size = PAPERSIZE_A4
* @return self * @return self
*/ */
public function setPaperSize($pValue = 9) public function setPaperSize($pValue = 9)

View File

@ -9,20 +9,20 @@
namespace PhpOffice\PhpWord\Writer; namespace PhpOffice\PhpWord\Writer;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Media; use PhpOffice\PhpWord\Media;
use PhpOffice\PhpWord\Element\Section; use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Writer\Word2007\ContentTypes; use PhpOffice\PhpWord\Writer\Word2007\ContentTypes;
use PhpOffice\PhpWord\Writer\Word2007\Rels;
use PhpOffice\PhpWord\Writer\Word2007\DocProps; use PhpOffice\PhpWord\Writer\Word2007\DocProps;
use PhpOffice\PhpWord\Writer\Word2007\Document; use PhpOffice\PhpWord\Writer\Word2007\Document;
use PhpOffice\PhpWord\Writer\Word2007\Footer; use PhpOffice\PhpWord\Writer\Word2007\Footer;
use PhpOffice\PhpWord\Writer\Word2007\Header;
use PhpOffice\PhpWord\Writer\Word2007\Notes; use PhpOffice\PhpWord\Writer\Word2007\Notes;
use PhpOffice\PhpWord\Writer\Word2007\Numbering; use PhpOffice\PhpWord\Writer\Word2007\Numbering;
use PhpOffice\PhpWord\Writer\Word2007\Header; use PhpOffice\PhpWord\Writer\Word2007\Rels;
use PhpOffice\PhpWord\Writer\Word2007\Styles;
use PhpOffice\PhpWord\Writer\Word2007\Settings; use PhpOffice\PhpWord\Writer\Word2007\Settings;
use PhpOffice\PhpWord\Writer\Word2007\Styles;
use PhpOffice\PhpWord\Writer\Word2007\WebSettings; use PhpOffice\PhpWord\Writer\Word2007\WebSettings;
/** /**
@ -199,7 +199,8 @@ class Word2007 extends AbstractWriter implements WriterInterface
$source = substr($source, 6); $source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source); list($zipFilename, $imageFilename) = explode('#', $source);
$zip = new \ZipArchive(); $zipClass = \PhpOffice\PhpWord\Settings::getZipClass();
$zip = new $zipClass();
if ($zip->open($zipFilename) !== false) { if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) { if ($zip->locateName($imageFilename)) {
$zip->extractTo($this->getTempDir(), $imageFilename); $zip->extractTo($this->getTempDir(), $imageFilename);

View File

@ -9,8 +9,6 @@
namespace PhpOffice\PhpWord\Writer\Word2007; namespace PhpOffice\PhpWord\Writer\Word2007;
use PhpOffice\PhpWord\Shared\XMLWriter;
/** /**
* Word2007 web settings part writer * Word2007 web settings part writer
*/ */

View File

@ -14,62 +14,73 @@ use PhpOffice\PhpWord\Shared\ZipArchive;
/** /**
* Test class for PhpOffice\PhpWord\Shared\ZipArchive * Test class for PhpOffice\PhpWord\Shared\ZipArchive
* *
* @coversDefaultClass \PhpOffice\PhpWord\Shared\ZipArchive
* @runTestsInSeparateProcesses * @runTestsInSeparateProcesses
*/ */
class ZipArchiveTest extends \PHPUnit_Framework_TestCase class ZipArchiveTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* Test add from file and string * Test all methods
*
* @covers ::<public>
*/ */
public function testAdd() public function testAllMethods()
{ {
// Preparation
$existingFile = __DIR__ . "/../_files/documents/sheet.xls"; $existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip"; $zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive(); $destination1 = __DIR__ . "/../_files/extract1";
$destination2 = __DIR__ . "/../_files/extract2";
$destination3 = __DIR__ . "/../_files/extract3";
@mkdir($destination1);
@mkdir($destination2);
@mkdir($destination3);
$object = new ZipArchive();
$object->open($zipFile); $object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls'); $object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test'); $object->addFromString('content/string.txt', 'Test');
$object->close();
$this->assertTrue($object->locateName('xls/new.xls')); // Run tests
$this->assertEquals('Test', $object->getFromName('content/string.txt')); $this->assertEquals(0, $object->locateName('xls/new.xls'));
$this->assertEquals('Test', $object->getFromName('/content/string.txt'));
unlink($zipFile);
}
/**
* Test find if a given name exists in the archive
*/
public function testLocate()
{
$existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$this->assertEquals(1, $object->locateName('content/string.txt'));
$this->assertFalse($object->locateName('blablabla')); $this->assertFalse($object->locateName('blablabla'));
unlink($zipFile); $this->assertEquals('Test', $object->getFromName('content/string.txt'));
} $this->assertEquals('Test', $object->getFromName('/content/string.txt'));
/**
* Test returns the name of an entry using its index
*/
public function testNameIndex()
{
$existingFile = __DIR__ . "/../_files/documents/sheet.xls";
$zipFile = __DIR__ . "/../_files/documents/ziptest.zip";
$object = new ZipArchive();
$object->open($zipFile);
$object->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$this->assertFalse($object->getNameIndex(-1)); $this->assertFalse($object->getNameIndex(-1));
$this->assertEquals('content/string.txt', $object->getNameIndex(1)); $this->assertEquals('content/string.txt', $object->getNameIndex(1));
unlink($zipFile); $this->assertFalse($object->extractTo('blablabla'));
$this->assertTrue($object->extractTo($destination1));
$this->assertTrue($object->extractTo($destination2, 'xls/new.xls'));
$this->assertFalse($object->extractTo($destination2, 'blablabla'));
// Cleanup
$this->deleteDir($destination1);
$this->deleteDir($destination2);
$this->deleteDir($destination3);
@unlink($zipFile);
}
/**
* Delete directory
*
* @param string $dir
*/
private function deleteDir($dir)
{
foreach (scandir($dir) as $file) {
if ($file === '.' || $file === '..') {
continue;
} elseif (is_file($dir . "/" . $file)) {
unlink($dir . "/" . $file);
} elseif (is_dir($dir . "/" . $file)) {
$this->deleteDir($dir . "/" . $file);
}
}
rmdir($dir);
} }
} }