ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
StreamInfoResolver.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use DateTimeImmutable;
27
34{
35 protected string $path;
36 protected ?string $file_name = null;
37 protected string $suffix;
38 protected string $mime_type;
39 protected ?\DateTimeImmutable $creation_date = null;
40 protected int $size = 0;
42
43 public function __construct(
45 int $next_version_number,
46 int $revision_owner_id,
47 string $revision_title,
48 ?string $file_name = null
49 ) {
50 $metadata = $file_stream->getMetadata();
51 $uri = $metadata['uri'];
52
53 if ($file_stream instanceof ZIPStream) {
54 // ZIPStreams are not seekable and rewindable, we need to wrap them in another ZIPStream to
55 // be able to read(255) and get the mime-type without loosing the 255 bytes
56 $this->file_stream = new ZIPStream(fopen($uri, 'rb'));
57 } else {
58 $this->file_stream = $file_stream;
59 }
60
61 parent::__construct($next_version_number, $revision_owner_id, $revision_title);
62 $this->path = $uri;
63 $this->initFileName($file_name);
64 $this->suffix = pathinfo((string) $this->file_name, PATHINFO_EXTENSION);
65 $this->initSize();
66 $this->initMimeType();
67 $this->initCreationDate();
68 }
69
70 protected function initMimeType(): void
71 {
72 $this->mime_type = 'unknown';
73 if (function_exists('mime_content_type') && file_exists($this->path)) {
74 $this->mime_type = mime_content_type($this->path);
75 return;
76 }
78 if (class_exists('finfo')) {
79 $finfo = finfo_open(FILEINFO_MIME_TYPE);
80 if ($this->file_stream->isSeekable()) {
81 //We only need the first few bytes to determine the mime-type this helps to reduce RAM-Usage
82 $this->mime_type = finfo_buffer($finfo, $this->file_stream->read(255));
83 $this->file_stream->rewind();
84 } else {
85 $this->mime_type = $this->getFileTypeFromSuffix();
86 }
87 //All MS-Types are 'application/zip' we need to look at the extension to determine the type.
88 if ($this->mime_type === 'application/zip' && $this->suffix !== 'zip') {
89 $this->mime_type = $this->getFileTypeFromSuffix();
90 }
91 if ($this->mime_type === 'application/x-empty') {
92 $this->mime_type = $this->getFileTypeFromSuffix();
93 }
94 }
95 }
96
97 protected function initSize(): void
98 {
99 $this->size = 0;
100 try {
101 $this->size = $this->file_stream->getSize();
102 } catch (\Throwable) {
103 $mb_strlen_exists = function_exists('mb_strlen');
104 //We only read one MB at a time as this radically reduces RAM-Usage
105 while ($content = $this->file_stream->read(1_048_576)) {
106 if ($mb_strlen_exists) {
107 $this->size += mb_strlen($content, '8bit');
108 } else {
109 $this->size += strlen($content);
110 }
111 }
112 } catch (\Throwable $exception) {
113 if ($this->file_stream->isSeekable()) {
114 $mb_strlen_exists = function_exists('mb_strlen');
115 //We only read one MB at a time as this radically reduces RAM-Usage
116 while ($content = $this->file_stream->read(1_048_576)) {
117 if ($mb_strlen_exists) {
118 $this->size += mb_strlen($content, '8bit');
119 } else {
120 $this->size += strlen($content);
121 }
122 }
123 $this->file_stream->rewind();
124 }
125 }
126 }
127
128 protected function initCreationDate(): void
129 {
130 $filectime = file_exists($this->path) ? filectime($this->path) : false;
131 $this->creation_date = $filectime ? (new \DateTimeImmutable())->setTimestamp(
132 $filectime
133 ) : new \DateTimeImmutable();
134 }
135
136 protected function initFileName(?string $file_name = null): void
137 {
138 if ($file_name !== null) {
139 $this->file_name = $file_name;
140 return;
141 }
142 $this->file_name = basename($this->path);
143 // in case the stream is ofString or of php://input, php://memory or php://input
144 if ($this->file_name === 'memory' || $this->file_name === 'input' || $this->file_name === 'temp') {
145 $this->file_name = $this->getRevisionTitle();
146 }
147 }
148
149 public function getFileName(): string
150 {
151 return $this->file_name;
152 }
153
154 public function getMimeType(): string
155 {
156 return $this->mime_type;
157 }
158
159 public function getSuffix(): string
160 {
161 return $this->suffix;
162 }
163
164 public function getCreationDate(): DateTimeImmutable
165 {
167 }
168
169 public function getSize(): int
170 {
171 return $this->size;
172 }
173
174 protected function getFileTypeFromSuffix(): string
175 {
176 $mime_types_array = MimeType::getExt2MimeMap();
177 $suffix_with_dot = '.' . $this->getSuffix();
178 if (array_key_exists($suffix_with_dot, $mime_types_array)) {
179 return $mime_types_array[$suffix_with_dot];
180 }
181 return 'application/octet-stream';
182 }
183}
Mime type determination.
Definition: MimeType.php:30
__construct(FileStream $file_stream, int $next_version_number, int $revision_owner_id, string $revision_title, ?string $file_name=null)
The base interface for all filesystem streams.
Definition: FileStream.php:32
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc