ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
StreamInfoResolver.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
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(
44  FileStream $file_stream,
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  //We only need the first few bytes to determine the mime-type this helps to reduce RAM-Usage
81  $this->mime_type = finfo_buffer($finfo, $this->file_stream->read(255));
82  if ($this->file_stream->isSeekable()) {
83  $this->file_stream->rewind();
84  }
85  //All MS-Types are 'application/zip' we need to look at the extension to determine the type.
86  if ($this->mime_type === 'application/zip' && $this->suffix !== 'zip') {
87  $this->mime_type = $this->getFileTypeFromSuffix();
88  }
89  if ($this->mime_type === 'application/x-empty') {
90  $this->mime_type = $this->getFileTypeFromSuffix();
91  }
92  }
93  }
94 
95  protected function initSize(): void
96  {
97  $this->size = 0;
98  try {
99  $this->size = $this->file_stream->getSize();
100  } catch (\Throwable) {
101  $mb_strlen_exists = function_exists('mb_strlen');
102  //We only read one MB at a time as this radically reduces RAM-Usage
103  while ($content = $this->file_stream->read(1_048_576)) {
104  if ($mb_strlen_exists) {
105  $this->size += mb_strlen($content, '8bit');
106  } else {
107  $this->size += strlen($content);
108  }
109  }
110 
111  if ($this->file_stream->isSeekable()) {
112  $this->file_stream->rewind();
113  }
114  }
115  }
116 
117  protected function initCreationDate(): void
118  {
119  $filectime = file_exists($this->path) ? filectime($this->path) : false;
120  $this->creation_date = $filectime ? (new \DateTimeImmutable())->setTimestamp(
121  $filectime
122  ) : new \DateTimeImmutable();
123  }
124 
125  protected function initFileName(?string $file_name = null): void
126  {
127  if ($file_name !== null) {
128  $this->file_name = $file_name;
129  return;
130  }
131  $this->file_name = basename($this->path);
132  // in case the stream is ofString or of php://input, php://memory or php://input
133  if ($this->file_name === 'memory' || $this->file_name === 'input' || $this->file_name === 'temp') {
134  $this->file_name = $this->getRevisionTitle();
135  }
136  }
137 
138  public function getFileName(): string
139  {
140  return $this->file_name;
141  }
142 
143  public function getMimeType(): string
144  {
145  return $this->mime_type;
146  }
147 
148  public function getSuffix(): string
149  {
150  return $this->suffix;
151  }
152 
154  {
155  return $this->creation_date;
156  }
157 
158  public function getSize(): int
159  {
160  return $this->size;
161  }
162 
163  protected function getFileTypeFromSuffix(): string
164  {
165  $mime_types_array = MimeType::getExt2MimeMap();
166  $suffix_with_dot = '.' . $this->getSuffix();
167  if (array_key_exists($suffix_with_dot, $mime_types_array)) {
168  return $mime_types_array[$suffix_with_dot];
169  }
170  return 'application/octet-stream';
171  }
172 }
__construct(FileStream $file_stream, int $next_version_number, int $revision_owner_id, string $revision_title, ?string $file_name=null)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
__construct(Container $dic, ilPlugin $plugin)
The base interface for all filesystem streams.
Definition: FileStream.php:31