ZipArchiver.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Package\Archiver;
  12. use ZipArchive;
  13. use Composer\Util\Filesystem;
  14. /**
  15. * @author Jan Prieser <jan@prieser.net>
  16. */
  17. class ZipArchiver implements ArchiverInterface
  18. {
  19. protected static $formats = array(
  20. 'zip' => 1,
  21. );
  22. /**
  23. * {@inheritdoc}
  24. */
  25. public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
  26. {
  27. $fs = new Filesystem();
  28. $sources = $fs->normalizePath($sources);
  29. $zip = new ZipArchive();
  30. $res = $zip->open($target, ZipArchive::CREATE);
  31. if ($res === true) {
  32. $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
  33. foreach ($files as $file) {
  34. /** @var \SplFileInfo $file */
  35. $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/');
  36. $localname = str_replace($sources.'/', '', $filepath);
  37. if ($file->isDir()) {
  38. $zip->addEmptyDir($localname);
  39. } else {
  40. $zip->addFile($filepath, $localname);
  41. }
  42. /**
  43. * ZipArchive::setExternalAttributesName is available from >= PHP 5.6
  44. */
  45. if (PHP_VERSION_ID >= 50600) {
  46. $perms = fileperms($filepath);
  47. /**
  48. * Ensure to preserve the permission umasks for the filepath in the archive.
  49. */
  50. $zip->setExternalAttributesName($localname, ZipArchive::OPSYS_UNIX, $perms << 16);
  51. }
  52. }
  53. if ($zip->close()) {
  54. return $target;
  55. }
  56. }
  57. $message = sprintf(
  58. "Could not create archive '%s' from '%s': %s",
  59. $target,
  60. $sources,
  61. $zip->getStatusString()
  62. );
  63. throw new \RuntimeException($message);
  64. }
  65. /**
  66. * {@inheritdoc}
  67. */
  68. public function supports($format, $sourceType)
  69. {
  70. return isset(static::$formats[$format]) && $this->compressionAvailable();
  71. }
  72. private function compressionAvailable()
  73. {
  74. return class_exists('ZipArchive');
  75. }
  76. }