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);
rename($name, "results/{$name}");
$writers = array('Word2007' => 'docx');
echo getEndingNotes($writers);
echo getEndingNotes(array('Word2007' => 'docx'));
if (!CLI) {
include_once 'Sample_Footer.php';
}

View File

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

View File

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

View File

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

View File

@ -11,9 +11,9 @@ namespace PhpOffice\PhpWord\Shared;
use PhpOffice\PhpWord\Exception\Exception;
// PCLZIP needs the temp path to end in a back slash
// @codeCoverageIgnoreStart
if (!defined('PCLZIP_TEMPORARY_DIR')) {
// PCLZIP needs the temp path to end in a back slash
define('PCLZIP_TEMPORARY_DIR', sys_get_temp_dir() . '/');
}
require_once 'PCLZip/pclzip.lib.php';
@ -67,7 +67,7 @@ class ZipArchive
}
/**
* Close this zip archive
* Close this zip archive (emulate \ZipArchive)
*
* @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 $localname Directory/Name of the file added to the zip
@ -104,15 +104,11 @@ class ZipArchive
$localnameParts["dirname"]
);
if ($res == 0) {
throw new Exception("Error zipping files : " . $this->zip->errorInfo(true));
}
return true;
return ($res == 0) ? false : 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 $contents String of data to add to the zip archive
@ -134,21 +130,18 @@ class ZipArchive
PCLZIP_OPT_ADD_PATH,
$filenameParts["dirname"]
);
if ($res == 0) {
throw new Exception("Error zipping files : " . $this->zip->errorInfo(true));
}
// 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
* @return boolean
* @param string $filename Filename for the file in zip archive
* @return integer|false
*/
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
* @return string $contents File string contents
* @return string|false $contents File string contents
*/
public function getFromName($filename)
{
$list = $this->zip->listContent();
$listCount = count($list);
$listIndex = -1;
$contents = null;
$listIndex = $this->locateName($filename);
$contents = false;
for ($i = 0; $i < $listCount; ++$i) {
if (strtolower($list[$i]["filename"]) == strtolower($filename) ||
strtolower($list[$i]["stored_filename"]) == strtolower($filename)) {
$listIndex = $i;
break;
}
}
if ($listIndex != -1) {
if ($listIndex !== false) {
$extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING);
} else {
$filename = substr($filename, 1);
$listIndex = -1;
for ($i = 0; $i < $listCount; ++$i) {
if (strtolower($list[$i]["filename"]) == strtolower($filename) ||
strtolower($list[$i]["stored_filename"]) == strtolower($filename)) {
$listIndex = $i;
break;
}
}
$listIndex = $this->locateName($filename);
$extracted = $this->zip->extractByIndex($listIndex, PCLZIP_OPT_EXTRACT_AS_STRING);
}
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
* @return string|false
* @since 0.10.0
*/
public function getNameIndex($index)
{
@ -223,4 +200,39 @@ class ZipArchive
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) {
$source = substr($source, 6);
list($zipFilename, $imageFilename) = explode('#', $source);
$zip = new \ZipArchive();
$zipClass = \PhpOffice\PhpWord\Settings::getZipClass();
$zip = new $zipClass();
if ($zip->open($zipFilename) !== false) {
if ($zip->locateName($imageFilename)) {
$zip->extractTo($this->getTempDir(), $imageFilename);

View File

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

View File

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

View File

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

View File

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

View File

@ -14,62 +14,73 @@ use PhpOffice\PhpWord\Shared\ZipArchive;
/**
* Test class for PhpOffice\PhpWord\Shared\ZipArchive
*
* @coversDefaultClass \PhpOffice\PhpWord\Shared\ZipArchive
* @runTestsInSeparateProcesses
*/
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";
$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->addFile($existingFile, 'xls/new.xls');
$object->addFromString('content/string.txt', 'Test');
$object->close();
$this->assertTrue($object->locateName('xls/new.xls'));
$this->assertEquals('Test', $object->getFromName('content/string.txt'));
$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'));
// Run tests
$this->assertEquals(0, $object->locateName('xls/new.xls'));
$this->assertFalse($object->locateName('blablabla'));
unlink($zipFile);
}
/**
* 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->assertEquals('Test', $object->getFromName('content/string.txt'));
$this->assertEquals('Test', $object->getFromName('/content/string.txt'));
$this->assertFalse($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);
}
}