19 declare(strict_types=1);
34 protected const URI =
'uri';
39 protected \ZipArchive
$zip;
48 $this->path_to_zip = $this->stream->getMetadata(self::URI);
49 $this->zip = new \ZipArchive();
51 $this->zip->open($this->path_to_zip, \ZipArchive::RDONLY);
52 $this->amount_of_entries = $this->zip->count();
54 $this->error_reading_zip =
true;
63 return function (\Generator $paths): \
Generator {
64 foreach ($paths as
$path) {
65 $resource = $this->zip->getStream($path);
67 yield Streams::ofResource($resource);
77 if (!$this->error_reading_zip) {
78 for ($i = 0, $i_max = $this->amount_of_entries; $i < $i_max; $i++) {
79 $path = $this->zip->getNameIndex($i, \ZipArchive::FL_UNCHANGED);
80 if ($this->isPathIgnored(
$path, $this->options)) {
96 yield
from $paths_to_stream_generator($this->
getFiles());
98 yield
from $paths_to_stream_generator($this->
getPaths());
109 yield
from $paths_to_stream_generator($this->
getFiles());
126 if (substr($path, -1) === self::DS_UNIX || substr($path, -1) === self::DS_WIN) {
127 $directories[] =
$path;
130 if ((str_contains($path, self::DS_UNIX) || str_contains($path, self::DS_WIN))) {
131 $directories[] = dirname($path) . self::DIRECTORY_SEPARATOR;
135 $directories_with_parents = [];
137 foreach ($directories as $directory) {
138 $parent = dirname($directory) . self::DIRECTORY_SEPARATOR;
139 if ($parent !== self::BASE_DIR . self::DIRECTORY_SEPARATOR && !in_array($parent, $directories,
true)) {
140 $directories_with_parents[] = $parent;
142 $directories_with_parents[] = $directory;
145 $directories_with_parents = array_unique($directories_with_parents);
146 sort($directories_with_parents);
147 yield
from $directories_with_parents;
152 return iterator_count($this->
getFiles());
163 if (substr($path, -1) !== self::DS_UNIX && substr($path, -1) !== self::DS_WIN) {
175 $dirname = dirname($zip_directory);
176 if ($dirname === self::BASE_DIR) {
183 foreach ($this->
getFiles() as $zip_file) {
184 $dirname = dirname($zip_file);
185 if ($dirname === self::BASE_DIR) {
197 if ($this->error_reading_zip) {
201 $destination_path = $this->options->getZipOutputPath();
202 if ($destination_path ===
null) {
206 switch ($this->options->getDirectoryHandling()) {
207 case ZipDirectoryHandling::KEEP_STRUCTURE:
209 case ZipDirectoryHandling::ENSURE_SINGLE_TOP_DIR:
211 $zip_path = $this->stream->getMetadata(self::URI);
212 $sufix =
'.' . pathinfo((
string) $zip_path, PATHINFO_EXTENSION);
213 $top_directory = basename((
string) $zip_path, $sufix);
216 $has_top_directory =
true;
218 $has_top_directory = str_starts_with($path, $top_directory) && $has_top_directory;
222 if (!$has_top_directory) {
223 $destination_path .= self::DIRECTORY_SEPARATOR . $top_directory;
227 if (!is_dir($destination_path) && (!mkdir($destination_path, 0777,
true) && !is_dir($destination_path))) {
228 throw new \RuntimeException(sprintf(
'Directory "%s" was not created', $destination_path));
232 $uri = $stream->getMetadata(self::URI);
233 if (substr((
string) $uri, -1) === self::DIRECTORY_SEPARATOR) {
236 $file_name =
Util::sanitizeFileName($destination_path . self::DIRECTORY_SEPARATOR . basename((
string) $uri));
239 $stream->getContents()
245 $this->zip->extractTo($destination_path, iterator_to_array($this->
getPaths()));
Will keep the top directory of the ZIP file if there is one (simple unzip).
getDirectories()
Yields the directory-paths of the currently open zip-archive.
getFiles()
Yields the file-paths of the currently open zip-archive.
sort()
description: > Example for rendering a Sort Glyph.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static sanitizeFileName(string $filename)
const DIRECTORY_SEPARATOR
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(protected UnzipOptions $options, protected FileStream $stream)
hasMultipleRootEntriesInZip()
The base interface for all filesystem streams.