19declare(strict_types=1);
39 private array
$ignored = [
'.',
'..',
'__MACOSX',
'.info',
'.DS_Store'];
54 $this->irss =
$DIC->resourceStorage();
55 $this->file_delivery =
$DIC->fileDelivery();
57 $this->irss->consume()->stream($rid)->getStream()
71 if ($this->use_flavour) {
72 $flavour_definition = new \ZipStructureDefinition();
73 $flavour = $this->irss->flavours()->get(
77 $flavour_stream = $flavour->getStreamResolvers()[0] ??
null;
78 if ($flavour_stream !==
null) {
79 $this->data = $flavour_definition->wake((
string) $flavour_stream->getStream());
83 if (empty($this->data)) {
84 $this->data = $this->reader->getStructure();
88 $this->data = array_filter(
90 static fn($key):
bool => !in_array($key, [
'.',
'/',
'./',
'..'],
true),
95 public function download(
string $path_inside_zip): never
97 [$stream,
$info] = $this->reader->getItem($path_inside_zip, $this->data);
99 $supported_for_inline = [
105 static fn(
string $mime_type):
string => str_replace(
'*',
'.*', preg_quote($mime_type,
'/')),
106 $supported_for_inline
108 $regex = implode(
'|', $regex);
110 $disposition = preg_match(
"/($regex)/", (
string)
$info[
'mime_type']) ? Disposition::INLINE : Disposition::ATTACHMENT;
112 $this->file_delivery->delivery()->deliver(
120 public function unzip(
string $path_inside_zip): bool
122 [$stream,
$info] = $this->reader->getItem($path_inside_zip, $this->data);
123 if (
$info[
'mime_type'] !==
'application/zip' &&
$info[
'mime_type'] !==
'application/x-zip-compressed') {
128 $tmp_directory = defined(
'CLIENT_DATA_DIR') ?
\CLIENT_DATA_DIR .
'/temp' : sys_get_temp_dir();
129 $tmp_file = tempnam($tmp_directory,
'ilias_zip_');
132 $return = file_put_contents($tmp_file, $stream->detach());
138 foreach ($zip_reader->getStructure() as $append_path_inside_zip => $item) {
139 if ($item[
'is_dir']) {
142 [$stream,
$info] = $zip_reader->getItem($append_path_inside_zip, $this->data);
143 $this->irss->manageContainer()->addStreamToContainer(
146 $this->current_level .
'/' . ltrim($append_path_inside_zip,
'./')
157 uasort($this->data,
static function (array
$a, array
$b):
int {
158 if (
$a[
'is_dir'] ===
$b[
'is_dir']) {
159 return strnatcasecmp((
string)
$a[
'basename'], (
string)
$b[
'basename']);
161 return $a[
'is_dir'] ? 1 : -1;
164 foreach ($this->data as
$path => $path_data) {
165 $dirname = $path_data[
'dirname'] ??
'./';
166 if ($dirname !== $this->current_level) {
169 $basename = $path_data[
'basename'] ??
'';
170 if (in_array($basename, $this->ignored,
true)) {
174 if ($path_data[
'is_dir'] ??
false) {
176 yield $this->directory(
$path, $path_data);
179 $file = $this->file(
$path, $path_data);
180 if ($file !==
null) {
192 private function basename(
string $full_path): string
194 return basename($full_path);
201 $current_level =
'/' . ltrim($current_level,
'./');
202 $current_level = rtrim($current_level,
'/');
203 $this->current_level = $current_level ===
'' ? self::BASE : $current_level;
210 $this->basename($path_inside_zip),
211 new \DateTimeImmutable(
'@' . (
$data[
'modified'] ?? 0))
219 $this->basename($path_inside_zip),
220 $data[
'mime_type'] ??
'application/octet-stream',
222 new \DateTimeImmutable(
'@' . (
$data[
'modified'] ?? 0))
Stream factory which enables the user to create streams without the knowledge of the concrete class.
static ofResource($resource)
Wraps an already created resource with the stream abstraction.
Class ResourceIdentification.
directory(string $path_inside_zip, array $data)
initData(ResourceIdentification $rid)
initCurrentLevel(string $current_level)
basename(string $full_path)
download(string $path_inside_zip)
__construct(private ResourceIdentification $rid, ?string $current_level=self::BASE ?? self::BASE)
file(string $path_inside_zip, array $data)
ILIAS FileDelivery Services $file_delivery
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
if(!file_exists('../ilias.ini.php'))