Merge pull request #13360 from mauriciofauth/zip-lib
Refactor zip functions into static methods
This commit is contained in:
commit
7c3cc91e70
@ -8,6 +8,7 @@
|
||||
namespace PMA\libraries;
|
||||
|
||||
use PMA\libraries\config\ConfigFile;
|
||||
use PMA\libraries\ZipExtension;
|
||||
|
||||
/**
|
||||
* File wrapper class
|
||||
@ -671,8 +672,7 @@ class File
|
||||
*/
|
||||
public function openZip($specific_entry = null)
|
||||
{
|
||||
include_once './libraries/zip_extension.lib.php';
|
||||
$result = PMA_getZipContents($this->getName(), $specific_entry);
|
||||
$result = ZipExtension::getContents($this->getName(), $specific_entry);
|
||||
if (! empty($result['error'])) {
|
||||
$this->_error_message = Message::rawError($result['error']);
|
||||
return false;
|
||||
|
||||
201
libraries/ZipExtension.php
Normal file
201
libraries/ZipExtension.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Interface for the zip extension
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
namespace PMA\libraries;
|
||||
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* Transformations class
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
class ZipExtension
|
||||
{
|
||||
/**
|
||||
* Gets zip file contents
|
||||
*
|
||||
* @param string $file zip file
|
||||
* @param string $specific_entry regular expression to match a file
|
||||
*
|
||||
* @return array ($error_message, $file_data); $error_message
|
||||
* is empty if no error
|
||||
*/
|
||||
public static function getContents($file, $specific_entry = null)
|
||||
{
|
||||
$error_message = '';
|
||||
$file_data = '';
|
||||
$zip_handle = zip_open($file);
|
||||
if (!is_resource($zip_handle)) {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' ' . self::getError($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
$first_zip_entry = zip_read($zip_handle);
|
||||
if (false === $first_zip_entry) {
|
||||
$error_message = __('No files found inside ZIP archive!');
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/* Is the the zip really an ODS file? */
|
||||
$read = zip_entry_read($first_zip_entry);
|
||||
$ods_mime = 'application/vnd.oasis.opendocument.spreadsheet';
|
||||
if (!strcmp($ods_mime, $read)) {
|
||||
$specific_entry = '/^content\.xml$/';
|
||||
}
|
||||
|
||||
if (!isset($specific_entry)) {
|
||||
zip_entry_open($zip_handle, $first_zip_entry, 'r');
|
||||
/* File pointer has already been moved,
|
||||
* so include what was read above */
|
||||
$file_data = $read;
|
||||
$file_data .= zip_entry_read(
|
||||
$first_zip_entry,
|
||||
zip_entry_filesize($first_zip_entry)
|
||||
);
|
||||
zip_entry_close($first_zip_entry);
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/* Return the correct contents, not just the first entry */
|
||||
for ( ; ; ) {
|
||||
$entry = zip_read($zip_handle);
|
||||
if (is_resource($entry)) {
|
||||
if (preg_match($specific_entry, zip_entry_name($entry))) {
|
||||
zip_entry_open($zip_handle, $entry, 'r');
|
||||
$file_data = zip_entry_read(
|
||||
$entry,
|
||||
zip_entry_filesize($entry)
|
||||
);
|
||||
zip_entry_close($entry);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Either we have reached the end of the zip and still
|
||||
* haven't found $specific_entry or there was a parsing
|
||||
* error that we must display
|
||||
*/
|
||||
if ($entry === false) {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' Could not find "' . $specific_entry . '"';
|
||||
} else {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' ' . self::getError($zip_handle);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name of the first file that matches the given $file_regexp.
|
||||
*
|
||||
* @param string $file_regexp regular expression for the file name to match
|
||||
* @param string $file zip archive
|
||||
*
|
||||
* @return string the file name of the first file that matches the given regexp
|
||||
*/
|
||||
public static function findFile($file_regexp, $file)
|
||||
{
|
||||
$zip_handle = zip_open($file);
|
||||
if (is_resource($zip_handle)) {
|
||||
$entry = zip_read($zip_handle);
|
||||
while (is_resource($entry)) {
|
||||
if (preg_match($file_regexp, zip_entry_name($entry))) {
|
||||
$file_name = zip_entry_name($entry);
|
||||
zip_close($zip_handle);
|
||||
return $file_name;
|
||||
}
|
||||
$entry = zip_read($zip_handle);
|
||||
}
|
||||
}
|
||||
zip_close($zip_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of files in the zip archive.
|
||||
*
|
||||
* @param string $file zip archive
|
||||
*
|
||||
* @return int the number of files in the zip archive
|
||||
*/
|
||||
public static function getNumberOfFiles($file)
|
||||
{
|
||||
$count = 0;
|
||||
$zip_handle = zip_open($file);
|
||||
if (is_resource($zip_handle)) {
|
||||
$entry = zip_read($zip_handle);
|
||||
while (is_resource($entry)) {
|
||||
$count++;
|
||||
$entry = zip_read($zip_handle);
|
||||
}
|
||||
zip_close($zip_handle);
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a set of files from the given zip archive to a given destinations.
|
||||
*
|
||||
* @param string $zip_path path to the zip archive
|
||||
* @param string $entry file in the archive that should be extracted
|
||||
*
|
||||
* @return string|bool data on sucess, false otherwise
|
||||
*/
|
||||
public static function extract($zip_path, $entry)
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($zip_path) === true) {
|
||||
$result = $zip->getFromName($entry);
|
||||
$zip->close();
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets zip error message
|
||||
*
|
||||
* @param resource $code error code
|
||||
*
|
||||
* @return string error message
|
||||
*/
|
||||
public static function getError($code)
|
||||
{
|
||||
// I don't think this needs translation
|
||||
switch ($code) {
|
||||
case ZIPARCHIVE::ER_MULTIDISK:
|
||||
$message = 'Multi-disk zip archives not supported';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_READ:
|
||||
$message = 'Read error';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_CRC:
|
||||
$message = 'CRC error';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_NOZIP:
|
||||
$message = 'Not a zip archive';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_INCONS:
|
||||
$message = 'Zip archive inconsistent';
|
||||
break;
|
||||
default:
|
||||
$message = $code;
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,7 @@ use PMA\libraries\gis\GISMultilinestring;
|
||||
use PMA\libraries\gis\GISMultipoint;
|
||||
use PMA\libraries\gis\GISPoint;
|
||||
use PMA\libraries\gis\GISPolygon;
|
||||
use PMA\libraries\ZipExtension;
|
||||
|
||||
/**
|
||||
* Handles the import for ESRI Shape files
|
||||
@ -70,7 +71,7 @@ class ImportShp extends ImportPlugin
|
||||
// If the zip archive has more than one file,
|
||||
// get the correct content to the buffer from .shp file.
|
||||
if ($compression == 'application/zip'
|
||||
&& PMA_getNoOfFilesInZip($import_file) > 1
|
||||
&& ZipExtension::getNumberOfFiles($import_file) > 1
|
||||
) {
|
||||
if ($GLOBALS['import_handle']->openZip('/^.*\.shp$/i') === false) {
|
||||
$message = PMA\libraries\Message::error(
|
||||
@ -89,14 +90,14 @@ class ImportShp extends ImportPlugin
|
||||
// If we can extract the zip archive to 'TempDir'
|
||||
// and use the files in it for import
|
||||
if ($compression == 'application/zip' && ! is_null($temp)) {
|
||||
$dbf_file_name = PMA_findFileFromZipArchive(
|
||||
$dbf_file_name = ZipExtension::findFile(
|
||||
'/^.*\.dbf$/i',
|
||||
$import_file
|
||||
);
|
||||
// If the corresponding .dbf file is in the zip archive
|
||||
if ($dbf_file_name) {
|
||||
// Extract the .dbf file and point to it.
|
||||
$extracted = PMA_zipExtract(
|
||||
$extracted = ZipExtension::extract(
|
||||
$import_file,
|
||||
$dbf_file_name
|
||||
);
|
||||
|
||||
@ -1,192 +0,0 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* Interface for the zip extension
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
if (! defined('PHPMYADMIN')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets zip file contents
|
||||
*
|
||||
* @param string $file zip file
|
||||
* @param string $specific_entry regular expression to match a file
|
||||
*
|
||||
* @return array ($error_message, $file_data); $error_message
|
||||
* is empty if no error
|
||||
*/
|
||||
function PMA_getZipContents($file, $specific_entry = null)
|
||||
{
|
||||
$error_message = '';
|
||||
$file_data = '';
|
||||
$zip_handle = zip_open($file);
|
||||
if (!is_resource($zip_handle)) {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' ' . PMA_getZipError($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
$first_zip_entry = zip_read($zip_handle);
|
||||
if (false === $first_zip_entry) {
|
||||
$error_message = __('No files found inside ZIP archive!');
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/* Is the the zip really an ODS file? */
|
||||
$read = zip_entry_read($first_zip_entry);
|
||||
$ods_mime = 'application/vnd.oasis.opendocument.spreadsheet';
|
||||
if (!strcmp($ods_mime, $read)) {
|
||||
$specific_entry = '/^content\.xml$/';
|
||||
}
|
||||
|
||||
if (!isset($specific_entry)) {
|
||||
zip_entry_open($zip_handle, $first_zip_entry, 'r');
|
||||
/* File pointer has already been moved,
|
||||
* so include what was read above */
|
||||
$file_data = $read;
|
||||
$file_data .= zip_entry_read(
|
||||
$first_zip_entry,
|
||||
zip_entry_filesize($first_zip_entry)
|
||||
);
|
||||
zip_entry_close($first_zip_entry);
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/* Return the correct contents, not just the first entry */
|
||||
for ( ; ; ) {
|
||||
$entry = zip_read($zip_handle);
|
||||
if (is_resource($entry)) {
|
||||
if (preg_match($specific_entry, zip_entry_name($entry))) {
|
||||
zip_entry_open($zip_handle, $entry, 'r');
|
||||
$file_data = zip_entry_read(
|
||||
$entry,
|
||||
zip_entry_filesize($entry)
|
||||
);
|
||||
zip_entry_close($entry);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Either we have reached the end of the zip and still
|
||||
* haven't found $specific_entry or there was a parsing
|
||||
* error that we must display
|
||||
*/
|
||||
if ($entry === false) {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' Could not find "' . $specific_entry . '"';
|
||||
} else {
|
||||
$error_message = __('Error in ZIP archive:')
|
||||
. ' ' . PMA_getZipError($zip_handle);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zip_close($zip_handle);
|
||||
return (array('error' => $error_message, 'data' => $file_data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name of the first file that matches the given $file_regexp.
|
||||
*
|
||||
* @param string $file_regexp regular expression for the file name to match
|
||||
* @param string $file zip archive
|
||||
*
|
||||
* @return string the file name of the first file that matches the given regexp
|
||||
*/
|
||||
function PMA_findFileFromZipArchive($file_regexp, $file)
|
||||
{
|
||||
$zip_handle = zip_open($file);
|
||||
if (is_resource($zip_handle)) {
|
||||
$entry = zip_read($zip_handle);
|
||||
while (is_resource($entry)) {
|
||||
if (preg_match($file_regexp, zip_entry_name($entry))) {
|
||||
$file_name = zip_entry_name($entry);
|
||||
zip_close($zip_handle);
|
||||
return $file_name;
|
||||
}
|
||||
$entry = zip_read($zip_handle);
|
||||
}
|
||||
}
|
||||
zip_close($zip_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of files in the zip archive.
|
||||
*
|
||||
* @param string $file zip archive
|
||||
*
|
||||
* @return int the number of files in the zip archive
|
||||
*/
|
||||
function PMA_getNoOfFilesInZip($file)
|
||||
{
|
||||
$count = 0;
|
||||
$zip_handle = zip_open($file);
|
||||
if (is_resource($zip_handle)) {
|
||||
$entry = zip_read($zip_handle);
|
||||
while (is_resource($entry)) {
|
||||
$count++;
|
||||
$entry = zip_read($zip_handle);
|
||||
}
|
||||
zip_close($zip_handle);
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a set of files from the given zip archive to a given destinations.
|
||||
*
|
||||
* @param string $zip_path path to the zip archive
|
||||
* @param string $entry file in the archive that should be extracted
|
||||
*
|
||||
* @return string|bool data on sucess, false otherwise
|
||||
*/
|
||||
function PMA_zipExtract($zip_path, $entry)
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($zip_path) === true) {
|
||||
$result = $zip->getFromName($entry);
|
||||
$zip->close();
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets zip error message
|
||||
*
|
||||
* @param resource $code error code
|
||||
*
|
||||
* @return string error message
|
||||
*/
|
||||
function PMA_getZipError($code)
|
||||
{
|
||||
// I don't think this needs translation
|
||||
switch ($code) {
|
||||
case ZIPARCHIVE::ER_MULTIDISK:
|
||||
$message = 'Multi-disk zip archives not supported';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_READ:
|
||||
$message = 'Read error';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_CRC:
|
||||
$message = 'CRC error';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_NOZIP:
|
||||
$message = 'Not a zip archive';
|
||||
break;
|
||||
case ZIPARCHIVE::ER_INCONS:
|
||||
$message = 'Zip archive inconsistent';
|
||||
break;
|
||||
default:
|
||||
$message = $code;
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
@ -5,18 +5,16 @@
|
||||
* @package PhpMyAdmin-test
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include to test.
|
||||
*/
|
||||
use PMA\libraries\ZipExtension;
|
||||
|
||||
require_once 'libraries/zip_extension.lib.php';
|
||||
require_once 'test/PMATestCase.php';
|
||||
|
||||
/**
|
||||
* Tests zip extension usage.
|
||||
*
|
||||
* @package PhpMyAdmin-test
|
||||
*/
|
||||
class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
class ZipExtensionTest extends PMATestCase
|
||||
{
|
||||
/**
|
||||
* Test zip file content
|
||||
@ -25,13 +23,13 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
* @param string $specific_entry regular expression to match a file
|
||||
* @param mixed $output expected output
|
||||
*
|
||||
* @dataProvider providerForTestGetZipContents
|
||||
* @dataProvider provideTestGetContents
|
||||
* @return void
|
||||
*/
|
||||
public function testGetZipContents($file, $specific_entry, $output)
|
||||
public function testGetContents($file, $specific_entry, $output)
|
||||
{
|
||||
$this->assertEquals(
|
||||
PMA_getZipContents($file, $specific_entry),
|
||||
ZipExtension::getContents($file, $specific_entry),
|
||||
$output
|
||||
);
|
||||
}
|
||||
@ -41,7 +39,7 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerForTestGetZipContents()
|
||||
public function provideTestGetContents()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
@ -70,13 +68,13 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
* @param string $file zip archive
|
||||
* @param mixed $output expected output
|
||||
*
|
||||
* @dataProvider providerForTestFindFileFromZipArchive
|
||||
* @dataProvider provideTestFindFile
|
||||
* @return void
|
||||
*/
|
||||
public function testFindFileFromZipArchive($file_regexp, $file, $output)
|
||||
public function testFindFile($file_regexp, $file, $output)
|
||||
{
|
||||
$this->assertEquals(
|
||||
PMA_findFileFromZipArchive($file_regexp, $file),
|
||||
ZipExtension::findFile($file_regexp, $file),
|
||||
$output
|
||||
);
|
||||
}
|
||||
@ -86,7 +84,7 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @return array Test data
|
||||
*/
|
||||
public function providerForTestFindFileFromZipArchive()
|
||||
public function provideTestFindFile()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
@ -98,52 +96,52 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for PMA_getNoOfFilesInZip
|
||||
* Test for ZipExtension::getNumberOfFiles
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetNoOfFilesInZip()
|
||||
public function testGetNumberOfFiles()
|
||||
{
|
||||
$this->assertEquals(
|
||||
PMA_getNoOfFilesInZip('./test/test_data/test.zip'),
|
||||
ZipExtension::getNumberOfFiles('./test/test_data/test.zip'),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for PMA_zipExtract
|
||||
* Test for ZipExtension::extract
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testZipExtract()
|
||||
public function testExtract()
|
||||
{
|
||||
$this->assertEquals(
|
||||
false,
|
||||
PMA_zipExtract(
|
||||
ZipExtension::extract(
|
||||
'./test/test_data/test.zip', 'wrongName'
|
||||
)
|
||||
);
|
||||
$this->assertEquals(
|
||||
"TEST FILE\n",
|
||||
PMA_zipExtract(
|
||||
ZipExtension::extract(
|
||||
'./test/test_data/test.zip', 'test.file'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for PMA_getZipError
|
||||
* Test for ZipExtension::getError
|
||||
*
|
||||
* @param int $code error code
|
||||
* @param mixed $output expected output
|
||||
*
|
||||
* @dataProvider providerForTestGetZipError
|
||||
* @dataProvider provideTestGetError
|
||||
* @return void
|
||||
*/
|
||||
public function testGetZipError($code, $output)
|
||||
public function testGetError($code, $output)
|
||||
{
|
||||
$this->assertEquals(
|
||||
PMA_getZipError($code),
|
||||
ZipExtension::getError($code),
|
||||
$output
|
||||
);
|
||||
}
|
||||
@ -153,7 +151,7 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function providerForTestGetZipError()
|
||||
public function provideTestGetError()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
@ -183,4 +181,3 @@ class PMA_ZipExtension_Test extends PHPUnit_Framework_TestCase
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user