ILIAS  trunk Revision v11.0_alpha-1831-g8615d53dadb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ILIAS\Filesystem\Util\Archive\Unzip Class Reference
+ Collaboration diagram for ILIAS\Filesystem\Util\Archive\Unzip:

Public Member Functions

 __construct (protected UnzipOptions $options, protected FileStream $stream)
 
 getPaths ()
 
 getStreams ()
 
 getFileStreams ()
 
 getAmountOfDirectories ()
 
 getDirectories ()
 Yields the directory-paths of the currently open zip-archive. More...
 
 getAmountOfFiles ()
 
 getFiles ()
 Yields the file-paths of the currently open zip-archive. More...
 
 hasMultipleRootEntriesInZip ()
 
 extract ()
 
 hasZipReadingError ()
 

Data Fields

const DS_UNIX = "/"
 
const DS_WIN = "\\"
 
const BASE_DIR = '.'
 

Protected Member Functions

 pathToStreamGenerator ()
 

Protected Attributes

const URI = 'uri'
 
const DIRECTORY_SEPARATOR = DIRECTORY_SEPARATOR
 
ZipArchive $zip
 
bool $error_reading_zip = false
 
string $path_to_zip
 

Private Attributes

int $amount_of_entries = 0
 

Detailed Description

Author
Fabian Schmid fabia.nosp@m.n@sr.nosp@m..solu.nosp@m.tion.nosp@m.s

Definition at line 30 of file Unzip.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\Filesystem\Util\Archive\Unzip::__construct ( protected UnzipOptions  $options,
protected FileStream  $stream 
)

Definition at line 44 of file Unzip.php.

47  {
48  $this->path_to_zip = $this->stream->getMetadata(self::URI);
49  $this->zip = new \ZipArchive();
50  try {
51  $this->zip->open($this->path_to_zip, \ZipArchive::RDONLY);
52  $this->amount_of_entries = $this->zip->count();
53  } catch (\Throwable) {
54  $this->error_reading_zip = true;
55  }
56  }

Member Function Documentation

◆ extract()

ILIAS\Filesystem\Util\Archive\Unzip::extract ( )

Definition at line 195 of file Unzip.php.

References $path, ILIAS\Filesystem\Util\Archive\FLAT_STRUCTURE, ILIAS\Filesystem\Util\Archive\Unzip\getPaths(), ILIAS\Filesystem\Util\Archive\Unzip\getStreams(), null, and ILIAS\Filesystem\Util\sanitizeFileName().

195  : bool
196  {
197  if ($this->error_reading_zip) {
198  return false;
199  }
200 
201  $destination_path = $this->options->getZipOutputPath();
202  if ($destination_path === null) {
203  return false;
204  }
205 
206  switch ($this->options->getDirectoryHandling()) {
207  case ZipDirectoryHandling::KEEP_STRUCTURE:
208  break;
209  case ZipDirectoryHandling::ENSURE_SINGLE_TOP_DIR:
210  // top directory with same name as the ZIP without suffix
211  $zip_path = $this->stream->getMetadata(self::URI);
212  $sufix = '.' . pathinfo((string) $zip_path, PATHINFO_EXTENSION);
213  $top_directory = basename((string) $zip_path, $sufix);
214 
215  // first we check if the ZIP contains the top directory
216  $has_top_directory = true;
217  foreach ($this->getPaths() as $path) {
218  $has_top_directory = str_starts_with($path, $top_directory) && $has_top_directory;
219  }
220 
221  // if not, we prepend the top directory to the destination path
222  if (!$has_top_directory) {
223  $destination_path .= self::DIRECTORY_SEPARATOR . $top_directory;
224  }
225  break;
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));
229  }
230 
231  foreach ($this->getStreams() as $stream) {
232  $uri = $stream->getMetadata(self::URI);
233  if (substr((string) $uri, -1) === self::DIRECTORY_SEPARATOR) {
234  continue; // Skip directories
235  }
236  $file_name = Util::sanitizeFileName($destination_path . self::DIRECTORY_SEPARATOR . basename((string) $uri));
237  file_put_contents(
238  $file_name,
239  $stream->getContents()
240  );
241  }
242  return true; // Stop here
243  }
244 
245  $this->zip->extractTo($destination_path, iterator_to_array($this->getPaths()));
246 
247  return true;
248  }
Will keep the top directory of the ZIP file if there is one (simple unzip).
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static sanitizeFileName(string $filename)
Definition: Util.php:48
+ Here is the call graph for this function:

◆ getAmountOfDirectories()

ILIAS\Filesystem\Util\Archive\Unzip::getAmountOfDirectories ( )

Definition at line 112 of file Unzip.php.

References ILIAS\Filesystem\Util\Archive\Unzip\getDirectories().

112  : int
113  {
114  return iterator_count($this->getDirectories());
115  }
getDirectories()
Yields the directory-paths of the currently open zip-archive.
Definition: Unzip.php:122
+ Here is the call graph for this function:

◆ getAmountOfFiles()

ILIAS\Filesystem\Util\Archive\Unzip::getAmountOfFiles ( )

Definition at line 150 of file Unzip.php.

References ILIAS\Filesystem\Util\Archive\Unzip\getFiles().

150  : int
151  {
152  return iterator_count($this->getFiles());
153  }
getFiles()
Yields the file-paths of the currently open zip-archive.
Definition: Unzip.php:159
+ Here is the call graph for this function:

◆ getDirectories()

ILIAS\Filesystem\Util\Archive\Unzip::getDirectories ( )

Yields the directory-paths of the currently open zip-archive.

This fixes the issue that win and mac zip archives have different directory structures.

Returns
|string[]

Definition at line 122 of file Unzip.php.

References $path, ILIAS\ResourceStorage\Flavour\Machine\DefaultMachines\from(), ILIAS\Filesystem\Util\Archive\Unzip\getPaths(), and ILIAS\UI\examples\Symbol\Glyph\Sort\sort().

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\getAmountOfDirectories(), and ILIAS\Filesystem\Util\Archive\Unzip\hasMultipleRootEntriesInZip().

122  : \Generator
123  {
124  $directories = [];
125  foreach ($this->getPaths() as $path) {
126  if (substr($path, -1) === self::DS_UNIX || substr($path, -1) === self::DS_WIN) {
127  $directories[] = $path;
128  continue;
129  }
130  if ((str_contains($path, self::DS_UNIX) || str_contains($path, self::DS_WIN))) {
131  $directories[] = dirname($path) . self::DIRECTORY_SEPARATOR;
132  }
133  }
134 
135  $directories_with_parents = [];
136 
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;
141  }
142  $directories_with_parents[] = $directory;
143  }
144 
145  $directories_with_parents = array_unique($directories_with_parents);
146  sort($directories_with_parents);
147  yield from $directories_with_parents;
148  }
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
$path
Definition: ltiservices.php:29
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFiles()

ILIAS\Filesystem\Util\Archive\Unzip::getFiles ( )

Yields the file-paths of the currently open zip-archive.

Returns
|string[]

Definition at line 159 of file Unzip.php.

References $path, ILIAS\ResourceStorage\Flavour\Machine\DefaultMachines\from(), ILIAS\Filesystem\Util\Archive\Unzip\getPaths(), and ILIAS\UI\examples\Symbol\Glyph\Sort\sort().

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\getAmountOfFiles(), ILIAS\Filesystem\Util\Archive\Unzip\getFileStreams(), ILIAS\Filesystem\Util\Archive\Unzip\getStreams(), and ILIAS\Filesystem\Util\Archive\Unzip\hasMultipleRootEntriesInZip().

159  : \Generator
160  {
161  $files = [];
162  foreach ($this->getPaths() as $path) {
163  if (substr($path, -1) !== self::DS_UNIX && substr($path, -1) !== self::DS_WIN) {
164  $files[] = $path;
165  }
166  }
167  sort($files);
168  yield from $files;
169  }
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
$path
Definition: ltiservices.php:29
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFileStreams()

ILIAS\Filesystem\Util\Archive\Unzip::getFileStreams ( )
Returns
|FileStream[]

Definition at line 105 of file Unzip.php.

References ILIAS\ResourceStorage\Flavour\Machine\DefaultMachines\from(), ILIAS\Filesystem\Util\Archive\Unzip\getFiles(), and ILIAS\Filesystem\Util\Archive\Unzip\pathToStreamGenerator().

105  : \Generator
106  {
107  $paths_to_stream_generator = $this->pathToStreamGenerator();
108 
109  yield from $paths_to_stream_generator($this->getFiles());
110  }
getFiles()
Yields the file-paths of the currently open zip-archive.
Definition: Unzip.php:159
+ Here is the call graph for this function:

◆ getPaths()

ILIAS\Filesystem\Util\Archive\Unzip::getPaths ( )
Returns
<bool|string>

Definition at line 75 of file Unzip.php.

References $path.

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\extract(), ILIAS\Filesystem\Util\Archive\Unzip\getDirectories(), ILIAS\Filesystem\Util\Archive\Unzip\getFiles(), and ILIAS\Filesystem\Util\Archive\Unzip\getStreams().

75  : \Generator
76  {
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)) {
81  continue;
82  }
83  yield $path;
84  }
85  }
86  }
$path
Definition: ltiservices.php:29
+ Here is the caller graph for this function:

◆ getStreams()

ILIAS\Filesystem\Util\Archive\Unzip::getStreams ( )
Returns
|FileStream[]

Definition at line 91 of file Unzip.php.

References ILIAS\Filesystem\Util\Archive\FLAT_STRUCTURE, ILIAS\ResourceStorage\Flavour\Machine\DefaultMachines\from(), ILIAS\Filesystem\Util\Archive\Unzip\getFiles(), ILIAS\Filesystem\Util\Archive\Unzip\getPaths(), and ILIAS\Filesystem\Util\Archive\Unzip\pathToStreamGenerator().

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\extract().

91  : \Generator
92  {
93  $paths_to_stream_generator = $this->pathToStreamGenerator();
94 
95  if ($this->options->getDirectoryHandling() === ZipDirectoryHandling::FLAT_STRUCTURE) {
96  yield from $paths_to_stream_generator($this->getFiles());
97  } else {
98  yield from $paths_to_stream_generator($this->getPaths());
99  }
100  }
Will keep the top directory of the ZIP file if there is one (simple unzip).
getFiles()
Yields the file-paths of the currently open zip-archive.
Definition: Unzip.php:159
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasMultipleRootEntriesInZip()

ILIAS\Filesystem\Util\Archive\Unzip::hasMultipleRootEntriesInZip ( )

Definition at line 171 of file Unzip.php.

References ILIAS\Filesystem\Util\Archive\Unzip\getDirectories(), and ILIAS\Filesystem\Util\Archive\Unzip\getFiles().

171  : bool
172  {
173  $amount = 0;
174  foreach ($this->getDirectories() as $zip_directory) {
175  $dirname = dirname($zip_directory);
176  if ($dirname === self::BASE_DIR) {
177  $amount++;
178  }
179  if ($amount > 1) {
180  return true;
181  }
182  }
183  foreach ($this->getFiles() as $zip_file) {
184  $dirname = dirname($zip_file);
185  if ($dirname === self::BASE_DIR) {
186  $amount++;
187  }
188  if ($amount > 1) {
189  return true;
190  }
191  }
192  return false;
193  }
getDirectories()
Yields the directory-paths of the currently open zip-archive.
Definition: Unzip.php:122
getFiles()
Yields the file-paths of the currently open zip-archive.
Definition: Unzip.php:159
+ Here is the call graph for this function:

◆ hasZipReadingError()

ILIAS\Filesystem\Util\Archive\Unzip::hasZipReadingError ( )

Definition at line 250 of file Unzip.php.

References ILIAS\Filesystem\Util\Archive\Unzip\$error_reading_zip.

250  : bool
251  {
253  }

◆ pathToStreamGenerator()

ILIAS\Filesystem\Util\Archive\Unzip::pathToStreamGenerator ( )
protected
Returns

Definition at line 61 of file Unzip.php.

References $path.

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\getFileStreams(), and ILIAS\Filesystem\Util\Archive\Unzip\getStreams().

61  : \Closure
62  {
63  return function (\Generator $paths): \Generator {
64  foreach ($paths as $path) {
65  $resource = $this->zip->getStream($path);
66 
67  yield Streams::ofResource($resource);
68  }
69  };
70  }
$path
Definition: ltiservices.php:29
+ Here is the caller graph for this function:

Field Documentation

◆ $amount_of_entries

int ILIAS\Filesystem\Util\Archive\Unzip::$amount_of_entries = 0
private

Definition at line 42 of file Unzip.php.

◆ $error_reading_zip

bool ILIAS\Filesystem\Util\Archive\Unzip::$error_reading_zip = false
protected

Definition at line 40 of file Unzip.php.

Referenced by ILIAS\Filesystem\Util\Archive\Unzip\hasZipReadingError().

◆ $path_to_zip

string ILIAS\Filesystem\Util\Archive\Unzip::$path_to_zip
protected

Definition at line 41 of file Unzip.php.

◆ $zip

ZipArchive ILIAS\Filesystem\Util\Archive\Unzip::$zip
protected

Definition at line 39 of file Unzip.php.

◆ BASE_DIR

const ILIAS\Filesystem\Util\Archive\Unzip::BASE_DIR = '.'

Definition at line 38 of file Unzip.php.

◆ DIRECTORY_SEPARATOR

const ILIAS\Filesystem\Util\Archive\Unzip::DIRECTORY_SEPARATOR = DIRECTORY_SEPARATOR
protected

Definition at line 35 of file Unzip.php.

◆ DS_UNIX

const ILIAS\Filesystem\Util\Archive\Unzip::DS_UNIX = "/"

Definition at line 36 of file Unzip.php.

◆ DS_WIN

const ILIAS\Filesystem\Util\Archive\Unzip::DS_WIN = "\\"

Definition at line 37 of file Unzip.php.

◆ URI

const ILIAS\Filesystem\Util\Archive\Unzip::URI = 'uri'
protected

Definition at line 34 of file Unzip.php.


The documentation for this class was generated from the following file: