Zip.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Archive;
  7. /**
  8. * Zip compressed file archive.
  9. */
  10. class Zip extends AbstractArchive implements ArchiveInterface
  11. {
  12. /**
  13. * @throws \Magento\Framework\Exception\LocalizedException
  14. */
  15. public function __construct()
  16. {
  17. $type = 'Zip';
  18. if (!class_exists('\ZipArchive')) {
  19. throw new \Magento\Framework\Exception\LocalizedException(
  20. new \Magento\Framework\Phrase('\'%1\' file extension is not supported', [$type])
  21. );
  22. }
  23. }
  24. /**
  25. * Pack file.
  26. *
  27. * @param string $source
  28. * @param string $destination
  29. *
  30. * @return string
  31. */
  32. public function pack($source, $destination)
  33. {
  34. $zip = new \ZipArchive();
  35. $zip->open($destination, \ZipArchive::CREATE);
  36. $zip->addFile($source);
  37. $zip->close();
  38. return $destination;
  39. }
  40. /**
  41. * Unpack file.
  42. *
  43. * @param string $source
  44. * @param string $destination
  45. *
  46. * @return string
  47. */
  48. public function unpack($source, $destination)
  49. {
  50. $zip = new \ZipArchive();
  51. if ($zip->open($source) === true) {
  52. $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: '');
  53. if ($filename) {
  54. $zip->extractTo(dirname($destination), $filename);
  55. rename(dirname($destination).'/'.$filename, $destination);
  56. } else {
  57. $destination = '';
  58. }
  59. $zip->close();
  60. } else {
  61. $destination = '';
  62. }
  63. return $destination;
  64. }
  65. /**
  66. * Filter file names with relative paths.
  67. *
  68. * @param string $path
  69. * @return string
  70. */
  71. private function filterRelativePaths(string $path): string
  72. {
  73. if ($path && preg_match('#^\s*(../)|(/../)#i', $path)) {
  74. $path = '';
  75. }
  76. return $path;
  77. }
  78. }