ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilFileDataForumLegacyImplementation.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 {
23  private const FORUM_PATH = 'forum';
24 
25  private string $forum_path;
28 
29  public function __construct(private readonly int $obj_id = 0, private int $pos_id = 0)
30  {
31  global $DIC;
32  $this->main_tpl = $DIC->ui()->mainTemplate();
33 
34  $this->error = $DIC['ilErr'];
35 
37  $this->forum_path = $this->getPath() . '/' . self::FORUM_PATH;
38 
39  if (!$this->checkForumPath()) {
40  $this->initDirectory();
41  }
42  }
43 
44  public function getObjId(): int
45  {
46  return $this->obj_id;
47  }
48 
49  public function getPosId(): int
50  {
51  return $this->pos_id;
52  }
53 
54  public function setPosId(int $posting_id): void
55  {
56  $this->pos_id = $posting_id;
57  }
58 
59  public function getForumPath(): string
60  {
61  return $this->forum_path;
62  }
63 
67  public function getFiles(): array
68  {
69  $directory_iterator = new DirectoryIterator($this->forum_path);
70  $filter_iterator = new RegexIterator($directory_iterator, "/^{$this->obj_id}_(.+)$/");
71 
72  $files = [];
73  foreach ($filter_iterator as $file) {
75  if (!$file->isFile()) {
76  continue;
77  }
78 
79  [$obj_id, $rest] = explode('_', $file->getFilename(), 2);
80  if ((int) $obj_id === $this->obj_id) {
81  $files[] = [
82  'path' => $file->getPathname(),
83  'md5' => md5($this->obj_id . '_' . $rest),
84  'name' => $rest,
85  'size' => $file->getSize(),
86  'ctime' => date('Y-m-d H:i:s', $file->getCTime())
87  ];
88  }
89  }
90 
91  return $files;
92  }
93 
97  public function getFilesOfPost(): array
98  {
99  $directory_iterator = new DirectoryIterator($this->forum_path);
100  $filter_iterator = new RegexIterator($directory_iterator, "/^{$this->obj_id}_{$this->getPosId()}_(.+)$/");
101 
102  $files = [];
103  foreach ($filter_iterator as $file) {
105  if (!$file->isFile()) {
106  continue;
107  }
108 
109  [$obj_id, $pos_id, $rest] = explode('_', $file->getFilename(), 3);
110  if ((int) $pos_id === $this->getPosId()) {
111  $files[$rest] = [
112  'path' => $file->getPathname(),
113  'md5' => md5($this->obj_id . '_' . $this->pos_id . '_' . $rest),
114  'name' => $rest,
115  'size' => $file->getSize(),
116  'ctime' => date('Y-m-d H:i:s', $file->getCTime())
117  ];
118  }
119  }
120 
121  return $files;
122  }
123 
124  public function moveFilesOfPost(int $new_frm_id = 0): bool
125  {
126  if ($new_frm_id !== 0) {
127  $directory_iterator = new DirectoryIterator($this->forum_path);
128  $filter_iterator = new RegexIterator($directory_iterator, "/^{$this->obj_id}_(\d+)_(.+)$/");
129 
130  foreach ($filter_iterator as $file) {
132  if (!$file->isFile()) {
133  continue;
134  }
135 
136  [$obj_id, $pos_id, $rest] = explode('_', $file->getFilename(), 3);
137  if ((int) $obj_id !== $this->obj_id || (int) $pos_id !== $this->getPosId()) {
138  continue;
139  }
140 
142  $file->getPathname(),
143  $this->forum_path . '/' . $new_frm_id . '_' . $this->pos_id . '_' . $rest
144  );
145  }
146 
147  return true;
148  }
149 
150  return false;
151  }
152 
153  public function ilClone(int $new_obj_id, int $new_posting_id): bool
154  {
155  foreach ($this->getFilesOfPost() as $file) {
156  copy(
157  $this->getForumPath() . '/' . $this->obj_id . '_' . $this->pos_id . '_' . $file['name'],
158  $this->getForumPath() . '/' . $new_obj_id . '_' . $new_posting_id . '_' . $file['name']
159  );
160  }
161 
162  return true;
163  }
164 
165  public function delete(array $posting_ids_to_delete = null): bool
166  {
167  if ($posting_ids_to_delete === null) {
168  return true;
169  }
170 
171  foreach ($this->getFiles() as $file) {
172  if (is_file($this->getForumPath() . '/' . $this->getObjId() . '_' . $file['name'])) {
173  unlink($this->getForumPath() . '/' . $this->getObjId() . '_' . $file['name']);
174  }
175  }
176 
177  return true;
178  }
179 
180  public function storeUploadedFiles(): bool
181  {
182  throw new DomainException('Not implemented');
183  }
184 
185  public function unlinkFile(string $filename): bool
186  {
187  if (is_file($this->forum_path . '/' . $this->obj_id . '_' . $this->pos_id . '_' . $filename)) {
188  return unlink($this->forum_path . '/' . $this->obj_id . '_' . $this->pos_id . '_' . $filename);
189  }
190 
191  return false;
192  }
193 
197  public function getFileDataByMD5Filename(string $hashed_filename): ?array
198  {
199  $files = ilFileUtils::getDir($this->forum_path);
200  foreach ($files as $file) {
201  if ($file['type'] === 'file' && md5($file['entry']) === $hashed_filename) {
202  return [
203  'path' => $this->forum_path . '/' . $file['entry'],
204  'filename' => $file['entry'],
205  'clean_filename' => str_replace($this->obj_id . '_' . $this->pos_id . '_', '', $file['entry'])
206  ];
207  }
208  }
209 
210  return null;
211  }
212 
216  public function unlinkFilesByMD5Filenames($hashed_filename_or_filenames): bool
217  {
218  $files = ilFileUtils::getDir($this->forum_path);
219  if (is_array($hashed_filename_or_filenames)) {
220  foreach ($files as $file) {
221  if ($file['type'] === 'file' && in_array(md5($file['entry']), $hashed_filename_or_filenames, true)) {
222  unlink($this->forum_path . '/' . $file['entry']);
223  }
224  }
225 
226  return true;
227  }
228 
229  foreach ($files as $file) {
230  if ($file['type'] === 'file' && md5($file['entry']) === $hashed_filename_or_filenames) {
231  return unlink($this->forum_path . '/' . $file['entry']);
232  }
233  }
234 
235  return false;
236  }
237 
238  private function checkForumPath(): bool
239  {
240  if (!is_dir($this->getForumPath())) {
241  return false;
242  }
243  $this->checkReadWrite();
244 
245  return true;
246  }
247 
248  private function checkReadWrite(): void
249  {
250  if (!is_writable($this->forum_path) || !is_readable($this->forum_path)) {
251  $this->error->raiseError('Forum directory is not readable/writable by webserver', $this->error->FATAL);
252  }
253  }
254 
255  private function initDirectory(): void
256  {
257  if (is_writable($this->getPath()) && mkdir($this->getPath() . '/' . self::FORUM_PATH) && chmod(
258  $this->getPath() . '/' . self::FORUM_PATH,
259  0755
260  )) {
261  $this->forum_path = $this->getPath() . '/' . self::FORUM_PATH;
262  }
263  }
264 
265  public function deliverFile(string $file): void
266  {
267  global $DIC;
268 
269  if (($path = $this->getFileDataByMD5Filename($file)) !== null) {
270  ilFileDelivery::deliverFileLegacy($path['path'], $path['clean_filename']);
271  } else {
272  $this->main_tpl->setOnScreenMessage('failure', $DIC->lanuage()->txt('error_reading_file'), true);
273  }
274  }
275 
276  public function deliverZipFile(): bool
277  {
278  global $DIC;
279 
280  $zip_file = $this->createZipFile();
281  if (!$zip_file) {
282  $this->main_tpl->setOnScreenMessage('failure', $DIC->language()->txt('error_reading_file'), true);
283  return false;
284  }
285 
286  $post = new ilForumPost($this->getPosId());
287  ilFileDelivery::deliverFileLegacy($zip_file, $post->getSubject() . '.zip', '', false, true, false);
288  ilFileUtils::delDir($this->getForumPath() . '/zip/' . $this->getObjId() . '_' . $this->getPosId());
289  $DIC->http()->close();
290 
291  return true; // never
292  }
293 
294  private function createZipFile(): ?string
295  {
296  $filesOfPost = $this->getFilesOfPost();
297  ksort($filesOfPost);
298 
299  ilFileUtils::makeDirParents($this->getForumPath() . '/zip/' . $this->getObjId() . '_' . $this->getPosId());
300  $tmp_dir = $this->getForumPath() . '/zip/' . $this->getObjId() . '_' . $this->getPosId();
301  foreach ($filesOfPost as $file) {
302  copy($file['path'], $tmp_dir . '/' . $file['name']);
303  }
304 
305  $zip_file = null;
306  if (ilFileUtils::zip(
307  $tmp_dir,
308  $this->getForumPath() . '/zip/' . $this->getObjId() . '_' . $this->getPosId() . '.zip'
309  )) {
310  $zip_file = $this->getForumPath() . '/zip/' . $this->getObjId() . '_' . $this->getPosId() . '.zip';
311  }
312 
313  return $zip_file;
314  }
315 }
__construct(private readonly int $obj_id=0, private int $pos_id=0)
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
moveFilesOfPost(int $new_frm_id=0)
$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)
$post
Definition: ltitoken.php:49
string $path