ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilFileDataForumDraftsLegacyImplementation.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 {
23  private string $drafts_path;
24  private ilLanguage $lng;
27 
28  public function __construct(private readonly int $obj_id, private readonly int $draft_id)
29  {
30  global $DIC;
31  $this->main_tpl = $DIC->ui()->mainTemplate();
32  $this->lng = $DIC->language();
33  $this->error = $DIC['ilErr'];
34 
36  $this->drafts_path = $this->getPath() . '/forum/drafts';
37 
38  if (!$this->checkForumDraftsPath()) {
39  $this->initDirectory();
40  }
41  }
42 
43  public function getObjId(): int
44  {
45  return $this->obj_id;
46  }
47 
48  private function getDraftsPath(): string
49  {
50  return $this->drafts_path;
51  }
52 
56  public function getFiles(): array
57  {
58  $files = [];
59 
60  foreach (new DirectoryIterator($this->getDraftsPath() . '/' . $this->draft_id) as $file) {
62  if ($file->isDir()) {
63  continue;
64  }
65 
66  $files[] = [
67  'path' => $file->getPathname(),
68  'md5' => md5($file->getFilename()),
69  'name' => $file->getFilename(),
70  'size' => $file->getSize(),
71  'ctime' => date('Y-m-d H:i:s', $file->getCTime())
72  ];
73  }
74 
75  return $files;
76  }
77 
81  public function getFilesOfPost(): array
82  {
83  $files = [];
84 
85  foreach (new DirectoryIterator($this->getDraftsPath() . '/' . $this->draft_id) as $file) {
90  if ($file->isDir()) {
91  continue;
92  }
93 
94  $files[$file->getFilename()] = [
95  'path' => $file->getPathname(),
96  'md5' => md5($file->getFilename()),
97  'name' => $file->getFilename(),
98  'size' => $file->getSize(),
99  'ctime' => date('Y-m-d H:i:s', $file->getCTime())
100  ];
101  }
102 
103  return $files;
104  }
105 
106  public function delete(array $posting_ids_to_delete = null): bool
107  {
108  // Each element of $posting_ids_to_delete represents a "Draft Id", NOT a "Posting Id"
109  if ($posting_ids_to_delete === null) {
110  return true;
111  }
112 
113  foreach ($posting_ids_to_delete as $draft_id) {
114  ilFileUtils::delDir($this->getDraftsPath() . '/' . $draft_id);
115  }
116 
117  return true;
118  }
119 
120  public function storeUploadedFile(array $files): bool
121  {
122  if (isset($files['name']) && is_array($files['name'])) {
123  foreach ($files['name'] as $index => $name) {
124  $name = rtrim($name, '/');
126  $temp_name = $files['tmp_name'][$index];
127  $error = $files['error'][$index];
128 
129  if ($filename !== '' && $temp_name !== '' && (int) $error === 0) {
130  $path = $this->getDraftsPath() . '/' . $this->draft_id . '/' . $filename;
131 
132  $this->rotateFiles($path);
134  }
135  }
136 
137  return true;
138  }
139 
140  if (isset($files['name']) && is_string($files['name'])) {
141  $files['name'] = rtrim($files['name'], '/');
142  $filename = ilFileUtils::_sanitizeFilemame($files['name']);
143  $temp_name = $files['tmp_name'];
144 
145  $path = $this->getDraftsPath() . '/' . $this->draft_id . '/' . $filename;
146 
147  $this->rotateFiles($path);
149 
150  return true;
151  }
152 
153  return false;
154  }
155 
156  public function unlinkFile(string $filename): bool
157  {
158  throw new DomainException('Not implemented');
159  }
160 
164  public function getFileDataByMD5Filename(string $hashed_filename): ?array
165  {
166  $files = ilFileUtils::getDir($this->getDraftsPath() . '/' . $this->draft_id);
167  foreach ($files as $file) {
168  if ($file['type'] === 'file' && md5($file['entry']) === $hashed_filename) {
169  return [
170  'path' => $this->getDraftsPath() . '/' . $this->draft_id . '/' . $file['entry'],
171  'filename' => $file['entry'],
172  'clean_filename' => $file['entry']
173  ];
174  }
175  }
176 
177  return null;
178  }
179 
183  public function unlinkFilesByMD5Filenames($hashedFilenameOrFilenames): bool
184  {
185  $files = ilFileUtils::getDir($this->getDraftsPath() . '/' . $this->draft_id);
186  if (is_array($hashedFilenameOrFilenames)) {
187  foreach ($files as $file) {
188  if ($file['type'] === 'file' && in_array(md5($file['entry']), $hashedFilenameOrFilenames, true)) {
189  unlink($this->getDraftsPath() . '/' . $this->draft_id . '/' . $file['entry']);
190  }
191  }
192 
193  return true;
194  }
195 
196  foreach ($files as $file) {
197  if ($file['type'] === 'file' && md5($file['entry']) === $hashedFilenameOrFilenames) {
198  return unlink($this->getDraftsPath() . '/' . $this->draft_id . '/' . $file['entry']);
199  }
200  }
201 
202  return false;
203  }
204 
205  public function checkForumDraftsPath(): bool
206  {
207  if (!is_dir($this->getDraftsPath() . '/' . $this->draft_id)) {
208  return false;
209  }
210  $this->checkReadWrite();
211 
212  return true;
213  }
214 
215  private function checkReadWrite(): void
216  {
217  if (!is_writable($this->getDraftsPath() . '/' . $this->draft_id) ||
218  !is_readable($this->getDraftsPath() . '/' . $this->draft_id)) {
219  $this->error->raiseError('Forum directory is not readable/writable by webserver', $this->error->FATAL);
220  }
221  }
222 
223  private function initDirectory(): void
224  {
225  if (is_writable($this->getPath()) && ilFileUtils::makeDirParents(
226  $this->getDraftsPath() . '/' . $this->draft_id
227  ) && chmod(
228  $this->getDraftsPath() . '/' . $this->draft_id,
229  0755
230  )) {
231  // Empty, whyever @nmatuschek?
232  }
233  }
234 
235  private function rotateFiles(string $a_path): void
236  {
237  if (is_file($a_path)) {
238  $this->rotateFiles($a_path . '.old');
239  ilFileUtils::rename($a_path, $a_path . '.old');
240  }
241  }
242 
243  public function deliverFile(string $file): void
244  {
245  if (($path = $this->getFileDataByMD5Filename($file)) !== null) {
246  ilFileDelivery::deliverFileLegacy($path['path'], $path['clean_filename']);
247  } else {
248  $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('error_reading_file'), true);
249  }
250  }
251 
252  public function deliverZipFile(): bool
253  {
254  global $DIC;
255 
256  $zip_file = $this->createZipFile();
257  if (!$zip_file) {
258  $this->main_tpl->setOnScreenMessage('failure', $this->lng->txt('error_reading_file'), true);
259  return false;
260  }
261 
263  ilFileDelivery::deliverFileLegacy($zip_file, $post->getPostSubject() . '.zip', '', false, true, false);
264  ilFileUtils::delDir($this->getDraftsPath() . '/drafts_zip/' . $this->draft_id);
265  $DIC->http()->close();
266 
267  return true; // never
268  }
269 
270  private function createZipFile(): ?string
271  {
272  $filesOfDraft = $this->getFilesOfPost();
273  ilFileUtils::makeDirParents($this->getDraftsPath() . '/drafts_zip/' . $this->draft_id);
274  $tmp_dir = $this->getDraftsPath() . '/drafts_zip/' . $this->draft_id;
275 
276  if ($filesOfDraft !== []) {
277  ksort($filesOfDraft);
278 
279  foreach ($filesOfDraft as $file) {
280  copy($file['path'], $tmp_dir . '/' . $file['name']);
281  }
282  }
283 
284  $zip_file = null;
285  if (ilFileUtils::zip($tmp_dir, $this->getDraftsPath() . '/drafts_zip/' . $this->draft_id . '.zip')) {
286  $zip_file = $this->getDraftsPath() . '/drafts_zip/' . $this->draft_id . '.zip';
287  }
288 
289  return $zip_file;
290  }
291 
292  public function getPosId(): int
293  {
294  return $this->draft_id;
295  }
296 
297  public function setPosId(int $posting_id): void
298  {
299  }
300 
301  public function getForumPath(): string
302  {
303  return '';
304  }
305 
306  public function moveFilesOfPost(int $new_frm_id = 0): bool
307  {
308  return true;
309  }
310 
311  public function ilClone(int $new_obj_id, int $new_posting_id): bool
312  {
313  return true;
314  }
315 
316  public function storeUploadedFiles(): bool
317  {
318  throw new DomainException('Not implemented');
319  }
320 }
__construct(private readonly int $obj_id, private readonly int $draft_id)
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
global $DIC
Definition: feed.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(VocabulariesInterface $vocabularies)
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static _sanitizeFilemame(string $a_filename)
$filename
Definition: buildRTE.php:78
Error Handling & global info handling.
static zip(string $a_dir, string $a_file, bool $compress_content=false)
static rename(string $a_source, string $a_target)
static newInstanceByDraftId(int $draft_id)
$post
Definition: ltitoken.php:49
string $path