zip_extension.lib.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Interface for the zip extension
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * Gets zip file contents
  13. *
  14. * @param string $file zip file
  15. * @param string $specific_entry regular expression to match a file
  16. *
  17. * @return array ($error_message, $file_data); $error_message
  18. * is empty if no error
  19. */
  20. function PMA_getZipContents($file, $specific_entry = null)
  21. {
  22. $error_message = '';
  23. $file_data = '';
  24. $zip_handle = zip_open($file);
  25. if (is_resource($zip_handle)) {
  26. $first_zip_entry = zip_read($zip_handle);
  27. if (false === $first_zip_entry) {
  28. $error_message = __('No files found inside ZIP archive!');
  29. } else {
  30. /* Is the the zip really an ODS file? */
  31. $read = zip_entry_read($first_zip_entry);
  32. $ods_mime = 'application/vnd.oasis.opendocument.spreadsheet';
  33. if (!strcmp($ods_mime, $read)) {
  34. $specific_entry = '/^content\.xml$/';
  35. }
  36. if (isset($specific_entry)) {
  37. /* Return the correct contents, not just the first entry */
  38. for ( ; ; ) {
  39. $entry = zip_read($zip_handle);
  40. if (is_resource($entry)) {
  41. if (preg_match($specific_entry, zip_entry_name($entry))) {
  42. zip_entry_open($zip_handle, $entry, 'r');
  43. $file_data = zip_entry_read(
  44. $entry,
  45. zip_entry_filesize($entry)
  46. );
  47. zip_entry_close($entry);
  48. break;
  49. }
  50. } else {
  51. /**
  52. * Either we have reached the end of the zip and still
  53. * haven't found $specific_entry or there was a parsing
  54. * error that we must display
  55. */
  56. if ($entry === false) {
  57. $error_message = __('Error in ZIP archive:')
  58. . ' Could not find "' . $specific_entry . '"';
  59. } else {
  60. $error_message = __('Error in ZIP archive:')
  61. . ' ' . PMA_getZipError($zip_handle);
  62. }
  63. break;
  64. }
  65. }
  66. } else {
  67. zip_entry_open($zip_handle, $first_zip_entry, 'r');
  68. /* File pointer has already been moved,
  69. * so include what was read above */
  70. $file_data = $read;
  71. $file_data .= zip_entry_read(
  72. $first_zip_entry,
  73. zip_entry_filesize($first_zip_entry)
  74. );
  75. zip_entry_close($first_zip_entry);
  76. }
  77. }
  78. } else {
  79. $error_message = __('Error in ZIP archive:')
  80. . ' ' . PMA_getZipError($zip_handle);
  81. }
  82. zip_close($zip_handle);
  83. return (array('error' => $error_message, 'data' => $file_data));
  84. }
  85. /**
  86. * Returns the file name of the first file that matches the given $file_regexp.
  87. *
  88. * @param string $file_regexp regular expression for the file name to match
  89. * @param string $file zip archive
  90. *
  91. * @return string the file name of the first file that matches the given regexp
  92. */
  93. function PMA_findFileFromZipArchive ($file_regexp, $file)
  94. {
  95. $zip_handle = zip_open($file);
  96. if (is_resource($zip_handle)) {
  97. $entry = zip_read($zip_handle);
  98. while (is_resource($entry)) {
  99. if (preg_match($file_regexp, zip_entry_name($entry))) {
  100. $file_name = zip_entry_name($entry);
  101. zip_close($zip_handle);
  102. return $file_name;
  103. }
  104. $entry = zip_read($zip_handle);
  105. }
  106. }
  107. zip_close($zip_handle);
  108. return false;
  109. }
  110. /**
  111. * Returns the number of files in the zip archive.
  112. *
  113. * @param string $file zip archive
  114. *
  115. * @return int the number of files in the zip archive
  116. */
  117. function PMA_getNoOfFilesInZip($file)
  118. {
  119. $count = 0;
  120. $zip_handle = zip_open($file);
  121. if (is_resource($zip_handle)) {
  122. $entry = zip_read($zip_handle);
  123. while (is_resource($entry)) {
  124. $count++;
  125. $entry = zip_read($zip_handle);
  126. }
  127. }
  128. zip_close($zip_handle);
  129. return $count;
  130. }
  131. /**
  132. * Extracts a set of files from the given zip archive to a given destinations.
  133. *
  134. * @param string $zip_path path to the zip archive
  135. * @param string $entry file in the archive that should be extracted
  136. *
  137. * @return string|bool data on sucess, false otherwise
  138. */
  139. function PMA_zipExtract($zip_path, $entry)
  140. {
  141. $zip = new ZipArchive;
  142. if ($zip->open($zip_path) === true) {
  143. $result = $zip->getFromName($entry);
  144. $zip->close();
  145. return $result;
  146. }
  147. return false;
  148. }
  149. /**
  150. * Gets zip error message
  151. *
  152. * @param integer $code error code
  153. *
  154. * @return string error message
  155. */
  156. function PMA_getZipError($code)
  157. {
  158. // I don't think this needs translation
  159. switch ($code) {
  160. case ZIPARCHIVE::ER_MULTIDISK:
  161. $message = 'Multi-disk zip archives not supported';
  162. break;
  163. case ZIPARCHIVE::ER_READ:
  164. $message = 'Read error';
  165. break;
  166. case ZIPARCHIVE::ER_CRC:
  167. $message = 'CRC error';
  168. break;
  169. case ZIPARCHIVE::ER_NOZIP:
  170. $message = 'Not a zip archive';
  171. break;
  172. case ZIPARCHIVE::ER_INCONS:
  173. $message = 'Zip archive inconsistent';
  174. break;
  175. default:
  176. $message = $code;
  177. }
  178. return $message;
  179. }
  180. ?>