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

Public Member Functions

 __construct (protected ZipOptions $options,... $streams)
 
 get ()
 
 addPath (string $path, ?string $path_inside_zip=null)
 
 addStream (FileStream $stream, string $path_inside_zip)
 

Data Fields

const DOT_EMPTY = '.empty'
 

Protected Attributes

ZipArchive $zip
 

Private Member Functions

 buildTempPath ()
 
 registerShutdownFunction (\Closure $c)
 
 storeZIPtoFilesystem ()
 

Private Attributes

string $zip_output_file = ''
 
int $iteration_limit
 
int $store_counter = 1
 
int $path_counter = 1
 
array $streams
 

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 Zip.php.

Constructor & Destructor Documentation

◆ __construct()

ILIAS\Filesystem\Util\Archive\Zip::__construct ( protected ZipOptions  $options,
  $streams 
)

Definition at line 46 of file Zip.php.

References ILIAS\Filesystem\Util\Archive\Zip\buildTempPath(), ILIAS\Filesystem\Util\Archive\ZipOptions\getZipOutputName(), ILIAS\Filesystem\Util\Archive\ZipOptions\getZipOutputPath(), ILIAS\Repository\int(), null, and ILIAS\Filesystem\Util\Archive\Zip\registerShutdownFunction().

49  {
50  $this->streams = array_filter($streams, fn($stream): bool => $stream instanceof FileStream);
51 
52  if ($options->getZipOutputPath() !== null && $options->getZipOutputName() !== null) {
53  $this->zip_output_file = $this->ensureDirectorySeperator(
54  $options->getZipOutputPath()
55  ) . $options->getZipOutputName();
56  } else {
57  $this->zip_output_file = $this->buildTempPath();
58  $this->registerShutdownFunction(function (): void {
59  if (file_exists($this->zip_output_file)) {
60  unlink($this->zip_output_file);
61  }
62  });
63  }
64  $system_limit = (int) shell_exec('ulimit -n') ?: 0;
65 
66  $this->iteration_limit = $system_limit < 10 ? 100 : min(
67  $system_limit / 2,
68  5000
69  );
70 
71  $this->zip = new \ZipArchive();
72  if (!file_exists($this->zip_output_file)) {
73  touch($this->zip_output_file);
74  }
75  if ($this->zip->open($this->zip_output_file, \ZipArchive::OVERWRITE) !== true) {
76  throw new \Exception("cannot open <$this->zip_output_file>\n");
77  }
78  }
registerShutdownFunction(\Closure $c)
Definition: Zip.php:94
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:

Member Function Documentation

◆ addPath()

ILIAS\Filesystem\Util\Archive\Zip::addPath ( string  $path,
?string  $path_inside_zip = null 
)
Deprecated:
in general, it should be avoided to operate with correct paths in the file system.

it is also usually not necessary to zip whole directories, as a ZIP can be seen as an "on-the-fly" compilation of different streams. However, since ILIAS still relies on zipping entire directories in many places, this method is still offered for the moment.

Definition at line 147 of file Zip.php.

References ILIAS\Filesystem\Util\Archive\Zip\addStream().

Referenced by ILIAS\Filesystem\Util\Archive\Zip\addStream().

147  : void
148  {
149  $path_inside_zip ??= basename($path);
150 
151  // create directory if it does not exist
152  $this->zip->addEmptyDir(rtrim(dirname($path_inside_zip), '/') . '/');
153 
154  $this->addStream(
155  Streams::ofResource(fopen($path, 'rb')),
156  $path_inside_zip
157  );
158  }
addStream(FileStream $stream, string $path_inside_zip)
Definition: Zip.php:160
$path
Definition: ltiservices.php:29
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ addStream()

ILIAS\Filesystem\Util\Archive\Zip::addStream ( FileStream  $stream,
string  $path_inside_zip 
)

Definition at line 160 of file Zip.php.

References Vendor\Package\$d, ILIAS\Filesystem\Util\Archive\Zip\addPath(), null, and ILIAS\Filesystem\Util\Archive\Zip\storeZIPtoFilesystem().

Referenced by ILIAS\Filesystem\Util\Archive\Zip\addPath().

160  : void
161  {
162  // we remove the "empty zip file" now if possible
163  if (count($this->streams) === 1 && isset($this->streams[self::DOT_EMPTY])) {
164  unset($this->streams[self::DOT_EMPTY]);
165  }
166 
167  // we must store the ZIP to e temporary files every 1000 files, otherwise we will get a Too Many Open Files error
168  $this->streams[$path_inside_zip] = $stream;
169 
170  if (
171  $this->path_counter === $this->iteration_limit
172  || count(get_resources('stream')) > ($this->iteration_limit * 0.9)
173  ) {
174  $this->storeZIPtoFilesystem();
175  $this->streams = [];
176  $this->path_counter = 0;
177  } else {
178  $this->path_counter++;
179  }
180  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildTempPath()

ILIAS\Filesystem\Util\Archive\Zip::buildTempPath ( )
private

Definition at line 80 of file Zip.php.

References CLIENT_DATA_DIR.

Referenced by ILIAS\Filesystem\Util\Archive\Zip\__construct().

80  : string
81  {
82  $directory = defined('CLIENT_DATA_DIR') ? \CLIENT_DATA_DIR . '/temp' : sys_get_temp_dir();
83  $tempnam = tempnam($directory, 'zip');
84  if (is_file($tempnam)) {
85  return $tempnam;
86  }
87  if (is_dir($tempnam)) {
88  rmdir($tempnam);
89  touch($tempnam);
90  }
91  return $tempnam;
92  }
const CLIENT_DATA_DIR
Definition: constants.php:46
+ Here is the caller graph for this function:

◆ get()

ILIAS\Filesystem\Util\Archive\Zip::get ( )

Definition at line 132 of file Zip.php.

References ILIAS\Filesystem\Util\Archive\Zip\storeZIPtoFilesystem().

132  : Stream
133  {
134  $this->storeZIPtoFilesystem();
135 
136  $this->zip->close();
137 
138  return Streams::ofResource(fopen($this->zip_output_file, 'rb'));
139  }
+ Here is the call graph for this function:

◆ registerShutdownFunction()

ILIAS\Filesystem\Util\Archive\Zip::registerShutdownFunction ( \Closure  $c)
private

Definition at line 94 of file Zip.php.

Referenced by ILIAS\Filesystem\Util\Archive\Zip\__construct().

94  : void
95  {
96  register_shutdown_function($c);
97  }
$c
Definition: deliver.php:25
+ Here is the caller graph for this function:

◆ storeZIPtoFilesystem()

ILIAS\Filesystem\Util\Archive\Zip::storeZIPtoFilesystem ( )
private

Definition at line 99 of file Zip.php.

References $path.

Referenced by ILIAS\Filesystem\Util\Archive\Zip\addStream(), and ILIAS\Filesystem\Util\Archive\Zip\get().

99  : void
100  {
101  foreach ($this->streams as $path_inside_zip => $stream) {
102  $path = $stream->getMetadata('uri');
103  if ($this->store_counter === 0) {
104  $this->zip->open($this->zip_output_file);
105  }
106  if (is_int($path_inside_zip)) {
107  $path_inside_zip = basename((string) $path);
108  }
109 
110  if ($path === 'php://memory') {
111  $this->zip->addFromString($path_inside_zip, (string) $stream);
112  $stream->close();
113  } elseif (is_file($path)) {
114  $this->zip->addFile($path, $path_inside_zip);
115  $stream->close();
116  } else {
117  continue;
118  }
119 
120  if (
121  $this->store_counter === $this->iteration_limit
122  || count(get_resources('stream')) > ($this->iteration_limit * 0.9)
123  ) {
124  $this->zip->close();
125  $this->store_counter = 0;
126  } else {
127  $this->store_counter++;
128  }
129  }
130  }
$path
Definition: ltiservices.php:29
+ Here is the caller graph for this function:

Field Documentation

◆ $iteration_limit

int ILIAS\Filesystem\Util\Archive\Zip::$iteration_limit
private

Definition at line 37 of file Zip.php.

◆ $path_counter

int ILIAS\Filesystem\Util\Archive\Zip::$path_counter = 1
private

Definition at line 39 of file Zip.php.

◆ $store_counter

int ILIAS\Filesystem\Util\Archive\Zip::$store_counter = 1
private

Definition at line 38 of file Zip.php.

◆ $streams

array ILIAS\Filesystem\Util\Archive\Zip::$streams
private

Definition at line 44 of file Zip.php.

◆ $zip

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

Definition at line 36 of file Zip.php.

◆ $zip_output_file

string ILIAS\Filesystem\Util\Archive\Zip::$zip_output_file = ''
private

Definition at line 35 of file Zip.php.

◆ DOT_EMPTY

const ILIAS\Filesystem\Util\Archive\Zip::DOT_EMPTY = '.empty'

Definition at line 34 of file Zip.php.

Referenced by ILIAS\Filesystem\Util\Archive\Archives\zip().


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