diff --git a/components/ILIAS/Filesystem/src/Util/Archive/Zip.php b/components/ILIAS/Filesystem/src/Util/Archive/Zip.php index 173f94ea7930..6f22748305ba 100755 --- a/components/ILIAS/Filesystem/src/Util/Archive/Zip.php +++ b/components/ILIAS/Filesystem/src/Util/Archive/Zip.php @@ -38,6 +38,8 @@ class Zip private int $store_counter = 1; private int $path_counter = 1; + private bool $zip_opened = false; + /** * @var FileStream[] */ @@ -70,7 +72,16 @@ public function __construct( if (!file_exists($this->zip_output_file)) { touch($this->zip_output_file); } - if ($this->zip->open($this->zip_output_file, \ZipArchive::OVERWRITE) !== true) { + + $this->maybeOpenZip(\ZipArchive::OVERWRITE); + } + + private function maybeOpenZip(?int $flags = null): void + { + if (!$this->zip_opened) { + $this->zip_opened = $this->zip->open($this->zip_output_file, $flags) === true; + } + if (!$this->zip_opened) { throw new \Exception("cannot open <$this->zip_output_file>\n"); } } @@ -99,7 +110,7 @@ private function storeZIPtoFilesystem(): void foreach ($this->streams as $path_inside_zip => $stream) { $path = $stream->getMetadata('uri'); if ($this->store_counter === 0) { - $this->zip->open($this->zip_output_file); + $this->maybeOpenZip(); } if (is_int($path_inside_zip)) { $path_inside_zip = basename((string) $path); @@ -120,6 +131,7 @@ private function storeZIPtoFilesystem(): void || count(get_resources('stream')) > ($this->iteration_limit * 0.9) ) { $this->zip->close(); + $this->zip_opened = false; $this->store_counter = 0; } else { $this->store_counter++; @@ -132,6 +144,7 @@ public function get(): Stream $this->storeZIPtoFilesystem(); $this->zip->close(); + $this->zip_opened = false; return Streams::ofResource(fopen($this->zip_output_file, 'rb')); } @@ -156,7 +169,9 @@ public function destroy(): void */ public function addPath(string $path, ?string $path_inside_zip = null): void { - $path_inside_zip = $path_inside_zip ?? basename($path); + $path_inside_zip ??= basename($path); + + $this->maybeOpenZip(); // create directory if it does not exist $this->zip->addEmptyDir(rtrim(dirname($path_inside_zip), '/') . '/'); @@ -225,7 +240,7 @@ public function addDirectory(string $directory_to_zip): void /** @var $file \SplFileInfo */ if ($file->isDir()) { // add directory to zip if it's empty - $sub_items = array_filter(scandir($pathname), static fn($d): bool => !str_contains((string) $d, '.DS_Store')); + $sub_items = array_filter(scandir($pathname), static fn($d): bool => !str_contains($d, '.DS_Store')); if (count($sub_items) === 2) { $this->zip->addEmptyDir($path_inside_zip); }