ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilMailFolderGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
25 
33 {
34  private bool $confirmTrashDeletion = false;
35  private bool $errorDelete = false;
37  private readonly ilGlobalTemplateInterface $tpl;
38  private readonly ilCtrlInterface $ctrl;
39  private readonly ilLanguage $lng;
40  private readonly ilToolbarGUI $toolbar;
41  private readonly ilTabsGUI $tabs;
42  private readonly ilObjUser $user;
43  public ilMail $umail;
44  public ilMailbox $mbox;
45  private readonly GlobalHttpState $http;
46  private readonly Refinery $refinery;
47  private int $currentFolderId = 0;
48  private readonly ilErrorHandling $error;
49  protected readonly Factory $ui_factory;
50  protected readonly Renderer $ui_renderer;
51 
52  public function __construct()
53  {
54  global $DIC;
55 
56  $this->tpl = $DIC->ui()->mainTemplate();
57  $this->ctrl = $DIC->ctrl();
58  $this->lng = $DIC->language();
59  $this->toolbar = $DIC->toolbar();
60  $this->user = $DIC->user();
61  $this->tabs = $DIC->tabs();
62  $this->http = $DIC->http();
63  $this->refinery = $DIC->refinery();
64  $this->error = $DIC['ilErr'];
65  $this->ui_factory = $DIC->ui()->factory();
66  $this->ui_renderer = $DIC->ui()->renderer();
67 
68  $this->umail = new ilMail($this->user->getId());
69  $this->mbox = new ilMailbox($this->user->getId());
70 
71  $this->initFolder();
72  }
73 
74  protected function initFolder(): void
75  {
76  if ($this->http->wrapper()->post()->has('mobj_id')) {
77  $folderId = $this->http->wrapper()->post()->retrieve('mobj_id', $this->refinery->kindlyTo()->int());
78  } elseif ($this->http->wrapper()->query()->has('mobj_id')) {
79  $folderId = $this->http->wrapper()->query()->retrieve('mobj_id', $this->refinery->kindlyTo()->int());
80  } else {
81  $folderId = $this->refinery->byTrying([
82  $this->refinery->kindlyTo()->int(),
83  $this->refinery->always($this->currentFolderId),
84  ])->transform(ilSession::get('mobj_id'));
85  }
86 
87  if (0 === $folderId || !$this->mbox->isOwnedFolder($folderId)) {
88  $folderId = $this->mbox->getInboxFolder();
89  }
90 
91  $this->currentFolderId = $folderId;
92  }
93 
94  protected function parseCommand(string $originalCommand): string
95  {
96  if (preg_match('/^([a-zA-Z0-9]+?)_(\d+?)$/', $originalCommand, $matches) && 3 === count($matches)) {
97  $originalCommand = $matches[1];
98  }
99 
100  return $originalCommand;
101  }
102 
103  protected function parseFolderIdFromCommand(string $command): int
104  {
105  if (
106  preg_match('/^([a-zA-Z0-9]+?)_(\d+?)$/', $command, $matches) &&
107  3 === count($matches) && is_numeric($matches[2])
108  ) {
109  return (int) $matches[2];
110  }
111 
112  throw new InvalidArgumentException("Cannot parse a numeric folder id from command string!");
113  }
114 
115  public function executeCommand(): void
116  {
117  $cmd = $this->parseCommand(
118  $this->ctrl->getCmd()
119  );
120 
121  $nextClass = $this->ctrl->getNextClass($this);
122  switch (strtolower($nextClass)) {
123  case strtolower(ilContactGUI::class):
124  $this->ctrl->forwardCommand(new ilContactGUI());
125  break;
126 
127  case strtolower(ilPublicUserProfileGUI::class):
128  $this->tpl->setTitle($this->lng->txt('mail'));
129  $userId = 0;
130  if ($this->http->wrapper()->query()->has('user')) {
131  $userId = $this->http->wrapper()->query()->retrieve('user', $this->refinery->kindlyTo()->int());
132  }
133  $profileGui = new ilPublicUserProfileGUI($userId);
134 
135  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
136  $profileGui->setBackUrl($this->ctrl->getLinkTarget($this, 'showMail'));
137  $this->ctrl->clearParameters($this);
138 
139  $ret = $this->ctrl->forwardCommand($profileGui);
140  if ($ret !== '') {
141  $this->tpl->setContent($ret);
142  }
143  $this->tpl->printToStdout();
144  break;
145 
146  default:
147  if (!method_exists($this, $cmd)) {
148  $cmd = 'showFolder';
149  }
150  $this->{$cmd}();
151  break;
152  }
153  }
154 
155  protected function performEmptyTrash(): void
156  {
157  $this->umail->deleteMailsOfFolder($this->currentFolderId);
158 
159  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_deleted'), true);
160  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
161  $this->ctrl->redirect($this, 'showFolder');
162  }
163 
164  protected function confirmEmptyTrash(): void
165  {
166  if ($this->umail->countMailsOfFolder($this->currentFolderId) !== 0) {
167  $this->confirmTrashDeletion = true;
168  }
169 
170  $this->showFolder();
171  }
172 
176  protected function showUser(): void
177  {
178  $userId = 0;
179  if ($this->http->wrapper()->query()->has('user')) {
180  $userId = $this->http->wrapper()->query()->retrieve('user', $this->refinery->kindlyTo()->int());
181  }
182  $this->tpl->setVariable('TBL_TITLE', implode(' ', [
183  $this->lng->txt('profile_of'),
184  ilObjUser::_lookupLogin($userId),
185  ]));
186  $this->tpl->setVariable('TBL_TITLE_IMG', ilUtil::getImagePath('standard/icon_usr.svg'));
187  $this->tpl->setVariable('TBL_TITLE_IMG_ALT', $this->lng->txt('public_profile'));
188 
189  $profile_gui = new ilPublicUserProfileGUI($userId);
190 
191  $mailId = 0;
192  if ($this->http->wrapper()->query()->has('mail_id')) {
193  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
194  }
195 
196  $this->ctrl->setParameter(
197  $this,
198  'mail_id',
199  $mailId
200  );
201  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
202  $profile_gui->setBackUrl($this->ctrl->getLinkTarget($this, 'showMail'));
203  $this->ctrl->clearParameters($this);
204 
205  $this->tpl->setTitle($this->lng->txt('mail'));
206  $this->tpl->setContent($this->ctrl->getHTML($profile_gui));
207  $this->tpl->printToStdout();
208  }
209 
210  protected function addSubFolderCommands(bool $isUserSubFolder = false): void
211  {
212  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
213  $this->toolbar->addButton(
214  $this->lng->txt('mail_add_subfolder'),
215  $this->ctrl->getLinkTarget($this, 'addSubFolder')
216  );
217 
218  if ($isUserSubFolder) {
219  $this->toolbar->addButton(
220  $this->lng->txt('rename'),
221  $this->ctrl->getLinkTarget($this, 'renameSubFolder')
222  );
223  $this->toolbar->addButton(
224  $this->lng->txt('delete'),
225  $this->ctrl->getLinkTarget($this, 'deleteSubFolder')
226  );
227  }
228  $this->ctrl->clearParameters($this);
229  }
230 
231  protected function showFolder(bool $oneConfirmationDialogueRendered = false): void
232  {
233  $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.mail.html', 'Services/Mail');
234  $this->tpl->setTitle($this->lng->txt('mail'));
235 
236  $isTrashFolder = $this->currentFolderId === $this->mbox->getTrashFolder();
237 
238  $selected_mail_ids = $this->getMailIdsFromRequest(true);
239  if (!$this->errorDelete && $isTrashFolder && 'deleteMails' === $this->parseCommand($this->ctrl->getCmd())) {
240  $confirmationGui = new ilConfirmationGUI();
241  $confirmationGui->setHeaderText($this->lng->txt('mail_sure_delete'));
242  $selected_mail_ids = $this->getMailIdsFromRequest();
243  foreach ($selected_mail_ids as $mailId) {
244  $confirmationGui->addHiddenItem('mail_id[]', (string) $mailId);
245  }
246  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
247  $confirmationGui->setFormAction($this->ctrl->getFormAction($this, 'showFolder'));
248  $this->ctrl->clearParameters($this);
249  $confirmationGui->setConfirm($this->lng->txt('confirm'), 'confirmDeleteMails');
250  $confirmationGui->setCancel($this->lng->txt('cancel'), 'showFolder');
251  $this->tpl->setVariable('CONFIRMATION', $confirmationGui->getHTML());
252  $oneConfirmationDialogueRendered = true;
253  }
254 
255  $mtree = new ilTree($this->user->getId());
256  $mtree->setTableNames('mail_tree', 'mail_obj_data');
257 
258  $isUserSubFolder = false;
259  $isUserRootFolder = false;
260 
261  $folder_d = $mtree->getNodeData($this->currentFolderId);
262  if ($folder_d['m_type'] === 'user_folder') {
263  $isUserSubFolder = true;
264  } elseif ($folder_d['m_type'] === 'local') {
265  $isUserRootFolder = true;
266  }
267 
268  $mailtable = $this->getMailFolderTable();
269  $mailtable->setSelectedItems($selected_mail_ids);
270 
271  try {
272  $mailtable->prepareHTML();
273  } catch (Exception $e) {
274  $this->tpl->setOnScreenMessage('failure', $this->lng->txt($e->getMessage()) !== '-' . $e->getMessage() . '-' ?
275  $this->lng->txt($e->getMessage()) :
276  $e->getMessage());
277  }
278 
279  $table_html = $mailtable->getHTML();
280 
281  if (!$oneConfirmationDialogueRendered && !$this->confirmTrashDeletion) {
282  $this->toolbar->setFormAction($this->ctrl->getFormAction($this, 'showFolder'));
283 
284  if ($isUserRootFolder || $isUserSubFolder) {
285  $this->addSubFolderCommands($isUserSubFolder);
286  }
287  }
288 
289  if ($this->confirmTrashDeletion && $mailtable->isTrashFolder() && $mailtable->getNumberOfMails() > 0) {
290  $confirmationGui = new ilConfirmationGUI();
291  $confirmationGui->setHeaderText($this->lng->txt('mail_empty_trash_confirmation'));
292  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
293  $confirmationGui->setFormAction($this->ctrl->getFormAction($this, 'performEmptyTrash'));
294  $this->ctrl->clearParameters($this);
295  $confirmationGui->setConfirm($this->lng->txt('confirm'), 'performEmptyTrash');
296  $confirmationGui->setCancel($this->lng->txt('cancel'), 'showFolder');
297  $this->tpl->setVariable('CONFIRMATION', $confirmationGui->getHTML());
298  }
299 
300  $this->tpl->setVariable('MAIL_TABLE', $table_html);
301  $this->tpl->printToStdout();
302  }
303 
304  protected function deleteSubFolder(bool $a_show_confirm = true): void
305  {
306  if ($a_show_confirm) {
307  $confirmationGui = new ilConfirmationGUI();
308  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
309  $confirmationGui->setFormAction($this->ctrl->getFormAction($this, 'showFolder'));
310  $this->ctrl->clearParameters($this);
311  $confirmationGui->setHeaderText($this->lng->txt('mail_sure_delete_folder'));
312  $confirmationGui->setCancel($this->lng->txt('cancel'), 'showFolder');
313  $confirmationGui->setConfirm($this->lng->txt('confirm'), 'performDeleteSubFolder');
314  $this->tpl->setVariable('CONFIRMATION', $confirmationGui->getHTML());
315 
316  $this->showFolder(true);
317  } else {
318  $this->showFolder();
319  }
320  }
321 
325  protected function performDeleteSubFolder(): void
326  {
327  $parentFolderId = $this->mbox->getParentFolderId($this->currentFolderId);
328  if ($parentFolderId > 0 && $this->mbox->deleteFolder($this->currentFolderId)) {
329  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_folder_deleted'), true);
330  $this->ctrl->setParameterByClass(ilMailGUI::class, 'mobj_id', $parentFolderId);
331  $this->ctrl->redirectByClass(ilMailGUI::class);
332  } else {
333  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_error_delete'));
334  $this->showFolder();
335  }
336  }
337 
338  protected function getSubFolderForm(string $mode = 'create'): ilPropertyFormGUI
339  {
340  $form = new ilPropertyFormGUI();
341  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
342  $form->setFormAction($this->ctrl->getFormAction($this, 'performAddSubFolder'));
343  $this->ctrl->clearParameters($this);
344  if ('edit' === $mode) {
345  $form->addCommandButton('performRenameSubFolder', $this->lng->txt('save'));
346  $form->setTitle($this->lng->txt('mail_rename_folder'));
347  } else {
348  $form->addCommandButton('performAddSubFolder', $this->lng->txt('save'));
349  $form->setTitle($this->lng->txt('mail_add_folder'));
350  }
351  $form->addCommandButton('showFolder', $this->lng->txt('cancel'));
352 
353  $title = new ilTextInputGUI($this->lng->txt('title'), 'subfolder_title');
354  $title->setRequired(true);
355  $form->addItem($title);
356 
357  return $form;
358  }
359 
360  protected function performAddSubFolder(): void
361  {
362  $form = $this->getSubFolderForm();
363  $isFormValid = $form->checkInput();
364  $form->setValuesByPost();
365  if (!$isFormValid) {
366  $this->addSubFolder($form);
367  return;
368  }
369 
370  $newFolderId = $this->mbox->addFolder($this->currentFolderId, $form->getInput('subfolder_title'));
371  if ($newFolderId > 0) {
372  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_folder_created'), true);
373  $this->ctrl->setParameterByClass(ilMailGUI::class, 'mobj_id', $newFolderId);
374  $this->ctrl->redirectByClass(ilMailGUI::class);
375  }
376 
377  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_folder_exists'));
378  $this->addSubFolder($form);
379  }
380 
381  protected function addSubFolder(ilPropertyFormGUI $form = null): void
382  {
383  if (null === $form) {
384  $form = $this->getSubFolderForm();
385  }
386 
387  $this->tpl->setTitle($this->lng->txt('mail'));
388  $this->tpl->setContent($form->getHTML());
389  $this->tpl->printToStdout();
390  }
391 
392  protected function performRenameSubFolder(): void
393  {
394  $form = $this->getSubFolderForm('edit');
395  $isFormValid = $form->checkInput();
396  $form->setValuesByPost();
397  if (!$isFormValid) {
398  $this->renameSubFolder($form);
399  return;
400  }
401 
402  $folderData = $this->mbox->getFolderData($this->currentFolderId);
403  if ($folderData === null) {
404  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_operation_on_invalid_folder'), true);
405  $this->ctrl->setParameterByClass(ilMailGUI::class, 'mobj_id', $this->mbox->getInboxFolder());
406  $this->ctrl->redirectByClass(ilMailGUI::class);
407  }
408 
409  if ($folderData['title'] === $form->getInput('subfolder_title')) {
410  $this->showFolder();
411  return;
412  }
413 
414  if ($this->mbox->renameFolder($this->currentFolderId, $form->getInput('subfolder_title'))) {
415  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_folder_name_changed'), true);
416  $this->ctrl->setParameterByClass(ilMailGUI::class, 'mobj_id', $this->currentFolderId);
417  $this->ctrl->redirectByClass(ilMailGUI::class);
418  }
419 
420  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_folder_exists'));
421  $this->renameSubFolder($form);
422  }
423 
424  protected function renameSubFolder(ilPropertyFormGUI $form = null): void
425  {
426  if (null === $form) {
427  $form = $this->getSubFolderForm('edit');
428  $form->setValuesByArray(
429  ['subfolder_title' => $this->mbox->getFolderData($this->currentFolderId)['title'] ?? '']
430  );
431  }
432 
433  $this->tpl->setTitle($this->lng->txt('mail'));
434  $this->tpl->setContent($form->getHTML());
435  $this->tpl->printToStdout();
436  }
437 
441  protected function getMailIdsFromRequest(bool $ignoreHttpGet = false): array
442  {
443  $mailIds = [];
444  if ($this->http->wrapper()->post()->has('mail_id')) {
445  $mailIds = $this->http->wrapper()->post()->retrieve(
446  'mail_id',
447  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
448  );
449  }
450 
451  if ($mailIds === [] && !$ignoreHttpGet) {
452  $mailId = 0;
453  if ($this->http->wrapper()->query()->has('mail_id')) {
454  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
455  }
456  if (is_numeric($mailId)) {
457  $mailIds = [$mailId];
458  }
459  }
460 
461  return array_filter(array_map('intval', $mailIds));
462  }
463 
464  protected function markMailsRead(): void
465  {
466  $mailIds = $this->getMailIdsFromRequest();
467  if ($mailIds !== []) {
468  $this->umail->markRead($mailIds);
469  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'));
470  } else {
471  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
472  }
473 
474  $this->showFolder();
475  }
476 
477  protected function markMailsUnread(): void
478  {
479  $mailIds = $this->getMailIdsFromRequest();
480  if ($mailIds !== []) {
481  $this->umail->markUnread($mailIds);
482  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'));
483  } else {
484  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
485  }
486 
487  $this->showFolder();
488  }
489 
490  protected function moveSingleMail(): void
491  {
492  $mailIds = $this->getMailIdsFromRequest();
493  if (1 !== count($mailIds)) {
494  $this->showMail();
495  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
496  return;
497  }
498 
499  $newFolderId = 0;
500  if ($this->http->wrapper()->query()->has('folder_id')) {
501  $newFolderId = $this->http->wrapper()->query()->retrieve(
502  'folder_id',
503  $this->refinery->kindlyTo()->int()
504  );
505  }
506  $redirectFolderId = $newFolderId;
507 
508  foreach ($mailIds as $mailId) {
509  $mailData = $this->umail->getMail($mailId);
510  if (isset($mailData['folder_id']) &&
511  is_numeric($mailData['folder_id']) &&
512  (int) $mailData['folder_id'] > 0
513  ) {
514  $redirectFolderId = (int) $mailData['folder_id'];
515  break;
516  }
517  }
518 
519  if ($this->umail->moveMailsToFolder($mailIds, $newFolderId)) {
520  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_moved'), true);
521  $this->ctrl->setParameter($this, 'mobj_id', $redirectFolderId);
522  $this->ctrl->redirect($this, 'showFolder');
523  } else {
524  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_move_error'));
525  $this->showMail();
526  }
527  }
528 
529  protected function moveMails(): void
530  {
531  $mailIds = $this->getMailIdsFromRequest();
532  if ($mailIds === []) {
533  $this->showFolder();
534  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
535  return;
536  }
537 
538  $folderId = $this->parseFolderIdFromCommand($this->ctrl->getCmd());
539  if ($this->umail->moveMailsToFolder($mailIds, $folderId)) {
540  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_moved'), true);
541  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
542  $this->ctrl->redirect($this, 'showFolder');
543  } else {
544  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_move_error'));
545  $this->showFolder();
546  }
547  }
548 
549  protected function deleteMails(): void
550  {
551  $trashFolderId = $this->mbox->getTrashFolder();
552  $mailIds = $this->getMailIdsFromRequest();
553 
554  if ($trashFolderId === $this->currentFolderId) {
555  if ($mailIds === []) {
556  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
557  $this->errorDelete = true;
558  }
559  } elseif ($mailIds === []) {
560  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
561  } elseif ($this->umail->moveMailsToFolder($mailIds, $trashFolderId)) {
562  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_moved_to_trash'), true);
563  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
564  $this->ctrl->redirect($this, 'showFolder');
565  } else {
566  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_move_error'));
567  }
568 
569  $this->showFolder();
570  }
571 
572  protected function confirmDeleteMails(): void
573  {
574  $mailIds = $this->getMailIdsFromRequest();
575  if ($mailIds === []) {
576  $this->showFolder();
577  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one'));
578  return;
579  }
580 
581  if ($this->mbox->getTrashFolder() === $this->currentFolderId) {
582  $this->umail->deleteMails($mailIds);
583  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_deleted'), true);
584  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
585  $this->ctrl->redirect($this, 'showFolder');
586  }
587 
588  $this->showFolder();
589  }
590 
591  protected function showMail(): void
592  {
593  $mailId = 0;
594  if ($this->http->wrapper()->query()->has('mail_id')) {
595  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
596  }
597 
598  if ($mailId <= 0) {
599  $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
600  }
601 
602  $mailData = $this->umail->getMail($mailId);
603  if ($mailData === null) {
604  $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
605  }
606 
607  $this->umail->markRead([$mailId]);
608 
609  $this->tpl->setTitle($this->lng->txt('mail_mails_of'));
610 
611  $this->tabs->clearTargets();
612  $this->ctrl->setParameter($this, 'mobj_id', $mailData['folder_id']);
613  $this->tabs->setBackTarget(
614  $this->lng->txt('back_to_folder'),
615  $this->ctrl->getFormAction($this, 'showFolder')
616  );
617  $this->ctrl->clearParameters($this);
618 
619  $this->ctrl->setParameter($this, 'mail_id', $mailId);
620  $this->ctrl->setParameter($this, 'mobj_id', $mailData['folder_id']);
621  $this->toolbar->setFormAction($this->ctrl->getFormAction($this, 'showMail'));
622  $this->ctrl->clearParameters($this);
623 
624  $form = new ilPropertyFormGUI();
625  $form->setId('MailContent');
626  $form->setPreventDoubleSubmission(false);
627  $form->setTableWidth('100%');
628  $this->ctrl->setParameter($this, 'mobj_id', $mailData['folder_id']);
629  $this->ctrl->setParameter($this, 'mail_id', $mailId);
630  $form->setFormAction($this->ctrl->getFormAction($this, 'showMail'));
631  $this->ctrl->clearParameters($this);
632  $form->setTitle($this->lng->txt('mail_mails_of'));
633 
635  $sender = ilObjectFactory::getInstanceByObjId($mailData['sender_id'], false);
636  $replyBtn = null;
637  if ($sender instanceof ilObjUser && $sender->getId() !== 0 && !$sender->isAnonymous()) {
638  $this->ctrl->setParameterByClass(
639  ilMailFormGUI::class,
640  'mobj_id',
641  $mailData['folder_id']
642  );
643  $this->ctrl->setParameterByClass(ilMailFormGUI::class, 'mail_id', $mailId);
644  $this->ctrl->setParameterByClass(ilMailFormGUI::class, 'type', ilMailFormGUI::MAIL_FORM_TYPE_REPLY);
645  $replyBtn = $this->ui_factory->button()->primary(
646  $this->lng->txt('reply'),
647  $this->ctrl->getLinkTargetByClass(ilMailFormGUI::class)
648  );
649  $this->toolbar->addStickyItem($replyBtn);
650  $this->ctrl->clearParametersByClass(ilMailFormGUI::class);
651  }
652 
653  $this->ctrl->setParameterByClass(ilMailFormGUI::class, 'mobj_id', $mailData['folder_id']);
654  $this->ctrl->setParameterByClass(ilMailFormGUI::class, 'mail_id', $mailId);
655  $this->ctrl->setParameterByClass(ilMailFormGUI::class, 'type', ilMailFormGUI::MAIL_FORM_TYPE_FORWARD);
656  if ($replyBtn === null) {
657  $fwdBtn = $this->ui_factory->button()->primary(
658  $this->lng->txt('forward'),
659  $this->ctrl->getLinkTargetByClass(ilMailFormGUI::class)
660  );
661  $this->toolbar->addStickyItem($fwdBtn);
662  } else {
663  $fwdBtn = $this->ui_factory->button()->standard(
664  $this->lng->txt('forward'),
665  $this->ctrl->getLinkTargetByClass(ilMailFormGUI::class)
666  );
667  $this->toolbar->addComponent($fwdBtn);
668  }
669  $this->ctrl->clearParametersByClass(ilMailFormGUI::class);
670 
671  if ($sender && $sender->getId() && !$sender->isAnonymous()) {
672  $linked_fullname = $sender->getPublicName();
673  $picture = ilUtil::img(
674  $sender->getPersonalPicturePath('xsmall'),
675  $sender->getPublicName(),
676  '',
677  '',
678  0,
679  '',
680  'ilMailAvatar'
681  );
682 
683  if (in_array(ilObjUser::_lookupPref($sender->getId(), 'public_profile'), ['y', 'g'])) {
684  $this->ctrl->setParameter($this, 'mail_id', $mailId);
685  $this->ctrl->setParameter($this, 'mobj_id', $mailData['folder_id']);
686  $this->ctrl->setParameter($this, 'user', $sender->getId());
687  $linked_fullname = '<br /><a class="mailusername" href="' . $this->ctrl->getLinkTarget(
688  $this,
689  'showUser'
690  ) . '" title="' . $linked_fullname . '">' . $linked_fullname . '</a>';
691  $this->ctrl->clearParameters($this);
692  }
693 
694  $from = new ilCustomInputGUI($this->lng->txt('from') . ':');
695  $from->setHtml($picture . ' ' . $linked_fullname);
696  } elseif (!$sender || !$sender->getId()) {
697  $from = new ilCustomInputGUI($this->lng->txt('from') . ':');
698  $from->setHtml(trim(($mailData['import_name'] ?? '') . ' (' . $this->lng->txt('user_deleted') . ')'));
699  } else {
700  $from = new ilCustomInputGUI($this->lng->txt('from') . ':');
701  $from->setHtml(
702  ilUtil::img(
703  ilUtil::getImagePath('logo/HeaderIconAvatar.svg'),
705  '',
706  '',
707  0,
708  '',
709  'ilMailAvatar'
710  ) .
711  '<br />' . ilMail::_getIliasMailerName()
712  );
713  }
714  $form->addItem($from);
715 
716  $to = new ilCustomInputGUI($this->lng->txt('mail_to') . ':');
717  $to->setHtml(ilUtil::htmlencodePlainString(
718  $this->umail->formatNamesForOutput($mailData['rcp_to'] ?? ''),
719  false
720  ));
721  $form->addItem($to);
722 
723  if ($mailData['rcp_cc']) {
724  $cc = new ilCustomInputGUI($this->lng->txt('mail_cc') . ':');
725  $cc->setHtml(ilUtil::htmlencodePlainString(
726  $this->umail->formatNamesForOutput($mailData['rcp_cc'] ?? ''),
727  false
728  ));
729  $form->addItem($cc);
730  }
731 
732  if ($mailData['rcp_bcc']) {
733  $bcc = new ilCustomInputGUI($this->lng->txt('mail_bcc') . ':');
734  $bcc->setHtml(ilUtil::htmlencodePlainString(
735  $this->umail->formatNamesForOutput($mailData['rcp_bcc'] ?? ''),
736  false
737  ));
738  $form->addItem($bcc);
739  }
740 
741  $subject = new ilCustomInputGUI($this->lng->txt('subject') . ':');
742  $subject->setHtml(ilUtil::htmlencodePlainString($mailData['m_subject'] ?? '', true));
743  $form->addItem($subject);
744 
745  $date = new ilCustomInputGUI($this->lng->txt('date') . ':');
746  $date->setHtml(ilDatePresentation::formatDate(
747  new ilDateTime($mailData['send_time'], IL_CAL_DATETIME)
748  ));
749  $form->addItem($date);
750 
751  $message = new ilCustomInputGUI($this->lng->txt('message') . ':');
752  $message->setHtml(ilUtil::htmlencodePlainString($mailData['m_message'] ?? '', true));
753  $form->addItem($message);
754 
755  if ($mailData['attachments']) {
756  $att = new ilCustomInputGUI($this->lng->txt('attachments') . ':');
757 
758  $radiog = new ilRadioGroupInputGUI('', 'filename');
759  foreach ($mailData['attachments'] as $file) {
760  $radiog->addOption(new ilRadioOption($file, md5($file)));
761  }
762 
763  $att->setHtml($radiog->render());
764  $form->addCommandButton('deliverFile', $this->lng->txt('download'));
765  $form->addItem($att);
766  }
767 
768  $isTrashFolder = false;
769  if ($this->mbox->getTrashFolder() === $mailData['folder_id']) {
770  $isTrashFolder = true;
771  }
772 
773  $currentFolderData = $this->mbox->getFolderData((int) $mailData['folder_id']);
774  if ($currentFolderData === null) {
775  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('mail_operation_on_invalid_folder'), true);
776  $this->ctrl->setParameterByClass(ilMailGUI::class, 'mobj_id', $this->mbox->getInboxFolder());
777  $this->ctrl->redirectByClass(ilMailGUI::class);
778  }
779 
780  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
781  $this->tabs->addTab(
782  'current_folder',
783  $currentFolderData['type'] === 'user_folder' ? $currentFolderData['title'] : $this->lng->txt(
784  'mail_' . $currentFolderData['title']
785  ),
786  $this->ctrl->getLinkTarget($this, 'showFolder')
787  );
788  $this->ctrl->clearParameters($this);
789  $this->tabs->activateTab('current_folder');
790 
791  $move_links = [];
792  $folders = $this->mbox->getSubFolders();
793  foreach ($folders as $folder) {
794  if (($folder['type'] !== 'trash' || !$isTrashFolder) &&
795  $folder['obj_id'] !== $mailData['folder_id']) {
796  $folder_name = $folder['title'];
797  if ($folder['type'] !== 'user_folder') {
798  $folder_name = $this->lng->txt('mail_' . $folder['title']);
799  }
800 
801  $move_links[] = $this->ui_factory->button()->shy(
802  sprintf(
803  $this->lng->txt('mail_move_to_folder_x'),
804  $folder_name
805  ) . ($folder['type'] === 'trash' ? ' (' . $this->lng->txt('delete') . ')' : ''),
806  '#',
807  )->withOnLoadCode(static fn($id): string => "
808  document.getElementById('$id').addEventListener('click', function(e) {
809  const frm = this.closest('form'),
810  action = new URL(frm.action),
811  action_params = new URLSearchParams(action.search);
812 
813  action_params.delete('cmd');
814  action_params.append('cmd', 'moveSingleMail');
815  action_params.delete('folder_id');
816  action_params.append('folder_id', '" . $folder['obj_id'] . "');
817 
818  action.search = action_params.toString();
819 
820  frm.action = action.href;
821  frm.submit();
822 
823  e.preventDefault();
824  e.stopPropagation();
825 
826  return false;
827  });");
828  }
829  }
830 
831  if ($isTrashFolder) {
832  $deleteBtn = $this->ui_factory->button()
833  ->standard($this->lng->txt('delete'), '#')
834  ->withOnLoadCode(static fn($id): string => "
835  document.getElementById('$id').addEventListener('click', function() {
836  const frm = this.closest('form'),
837  action = new URL(frm.action),
838  action_params = new URLSearchParams(action.search);
839 
840  action_params.delete('cmd');
841  action_params.append('cmd', 'deleteMails');
842 
843  action.search = action_params.toString();
844 
845  frm.action = action.href;
846  frm.submit();
847  return false;
848  });
849  ");
850  $this->toolbar->addComponent($deleteBtn);
851  }
852 
853  if ($move_links !== []) {
854  $this->toolbar->addComponent(
855  $this->ui_factory->dropdown()->standard($move_links)
856  ->withLabel($this->lng->txt('mail_move_to_folder_btn_label'))
857  );
858  }
859 
860  $this->toolbar->addSeparator();
861 
862  $this->ctrl->setParameter($this, 'mail_id', $mailId);
863  $this->ctrl->setParameter($this, 'mobj_id', $mailData['folder_id']);
864  $print_url = $this->ctrl->getLinkTarget($this, 'printMail');
865  $this->ctrl->clearParameters($this);
866  $print_btn = $this->ui_factory->button()
867  ->standard($this->lng->txt('print'), '#')
868  ->withOnLoadCode(static fn($id): string => "
869  document.getElementById('$id').addEventListener('click', function() {
870  const frm = this.closest('form'),
871  action = frm.action;
872 
873  frm.action = '$print_url';
874  frm.target = '_blank';
875  frm.submit();
876 
877  frm.action = action;
878  frm.removeAttribute('target');
879 
880  return false;
881  });
882  ");
883  $this->toolbar->addComponent($print_btn);
884 
885  $prevMail = $this->umail->getPreviousMail($mailId);
886  $nextMail = $this->umail->getNextMail($mailId);
887  if (is_array($prevMail) || is_array($nextMail)) {
888  $this->toolbar->addSeparator();
889 
890  if ($prevMail && $prevMail['mail_id']) {
891  $this->ctrl->setParameter($this, 'mail_id', $prevMail['mail_id']);
892  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
893  $prevBtn = $this->ui_factory->button()
894  ->standard(
895  $this->lng->txt('previous'),
896  $this->ctrl->getLinkTarget($this, 'showMail')
897  );
898  $this->toolbar->addComponent($prevBtn);
899  $this->ctrl->clearParameters($this);
900  }
901 
902  if ($nextMail && $nextMail['mail_id']) {
903  $this->ctrl->setParameter($this, 'mail_id', $nextMail['mail_id']);
904  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
905  $nextBtn = $this->ui_factory->button()
906  ->standard(
907  $this->lng->txt('next'),
908  $this->ctrl->getLinkTarget($this, 'showMail')
909  );
910  $this->toolbar->addComponent($nextBtn);
911  $this->ctrl->clearParameters($this);
912  }
913  }
914 
915  $this->tpl->setContent($form->getHTML());
916  $this->tpl->printToStdout();
917  }
918 
919  protected function printMail(): void
920  {
921  $tplprint = new ilTemplate('tpl.mail_print.html', true, true, 'Services/Mail');
922 
923  $mailId = 0;
924  if ($this->http->wrapper()->query()->has('mail_id')) {
925  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
926  }
927  $mailData = $this->umail->getMail($mailId);
928 
929  $sender = ilObjectFactory::getInstanceByObjId($mailData['sender_id'], false);
930 
931  $tplprint->setVariable('TXT_FROM', $this->lng->txt('from'));
932  if ($sender instanceof ilObjUser && $sender->getId() !== 0 && !$sender->isAnonymous()) {
933  $tplprint->setVariable('FROM', $sender->getPublicName());
934  } elseif (!$sender instanceof ilObjUser || 0 === $sender->getId()) {
935  $tplprint->setVariable(
936  'FROM',
937  trim(($mailData['import_name'] ?? '') . ' (' . $this->lng->txt('user_deleted') . ')')
938  );
939  } else {
940  $tplprint->setVariable('FROM', ilMail::_getIliasMailerName());
941  }
942 
943  $tplprint->setVariable('TXT_TO', $this->lng->txt('mail_to'));
944  $tplprint->setVariable('TO', $mailData['rcp_to']);
945 
946  if ($mailData['rcp_cc']) {
947  $tplprint->setCurrentBlock('cc');
948  $tplprint->setVariable('TXT_CC', $this->lng->txt('mail_cc'));
949  $tplprint->setVariable('CC', $mailData['rcp_cc']);
950  $tplprint->parseCurrentBlock();
951  }
952 
953  if ($mailData['rcp_bcc']) {
954  $tplprint->setCurrentBlock('bcc');
955  $tplprint->setVariable('TXT_BCC', $this->lng->txt('mail_bcc'));
956  $tplprint->setVariable('BCC', $mailData['rcp_bcc']);
957  $tplprint->parseCurrentBlock();
958  }
959 
960  $tplprint->setVariable('TXT_SUBJECT', $this->lng->txt('subject'));
961  $tplprint->setVariable('SUBJECT', htmlspecialchars($mailData['m_subject']));
962 
963  $tplprint->setVariable('TXT_DATE', $this->lng->txt('date'));
964  $tplprint->setVariable(
965  'DATE',
966  ilDatePresentation::formatDate(new ilDateTime($mailData['send_time'], IL_CAL_DATETIME))
967  );
968 
969  $tplprint->setVariable('TXT_MESSAGE', $this->lng->txt('message'));
970  $tplprint->setVariable('MAIL_MESSAGE', nl2br(htmlspecialchars($mailData['m_message'])));
971 
972  $tplprint->show();
973  }
974 
975  protected function deliverFile(): void
976  {
977  $mailId = 0;
978  if ($this->http->wrapper()->query()->has('mail_id')) {
979  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
980  }
981 
982  if ($mailId <= 0) {
983  $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
984  }
985 
986  $filename = '';
987  if ($this->http->wrapper()->post()->has('filename')) {
988  $filename = $this->http->wrapper()->post()->retrieve('filename', $this->refinery->kindlyTo()->string());
989  }
990 
991  if (is_string(ilSession::get('filename')) && ilSession::get('filename') !== '') {
992  $filename = ilSession::get('filename');
993  ilSession::set('filename', null);
994  }
995 
996  try {
997  if ($mailId > 0 && $filename !== '') {
998  while (str_contains((string) $filename, '..')) {
999  $filename = str_replace('..', '', $filename);
1000  }
1001 
1002  $mailFileData = new ilFileDataMail($this->user->getId());
1003  try {
1004  $file = $mailFileData->getAttachmentPathAndFilenameByMd5Hash($filename, (int) $mailId);
1005  ilFileDelivery::deliverFileLegacy($file['path'], $file['filename']);
1006  } catch (OutOfBoundsException $e) {
1007  throw new ilMailException('mail_error_reading_attachment', $e->getCode(), $e);
1008  }
1009  } else {
1010  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_attachment'));
1011  $this->showMail();
1012  }
1013  } catch (Exception $e) {
1014  $this->tpl->setOnScreenMessage('failure', $this->lng->txt($e->getMessage()), true);
1015  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
1016  $this->ctrl->redirect($this);
1017  }
1018  }
1019 
1020  protected function deliverAttachments(): void
1021  {
1022  try {
1023  $mailId = 0;
1024  if ($this->http->wrapper()->query()->has('mail_id')) {
1025  $mailId = $this->http->wrapper()->query()->retrieve('mail_id', $this->refinery->kindlyTo()->int());
1026  }
1027 
1028  $mailData = $this->umail->getMail((int) $mailId);
1029  if (null === $mailData || [] === (array) $mailData['attachments']) {
1030  throw new ilMailException('mail_error_reading_attachment');
1031  }
1032 
1033  $type = '';
1034  if ($this->http->wrapper()->query()->has('type')) {
1035  $type = $this->http->wrapper()->query()->retrieve('type', $this->refinery->kindlyTo()->string());
1036  }
1037 
1038  $mailFileData = new ilFileDataMail($this->user->getId());
1039  if (count($mailData['attachments']) === 1) {
1040  $attachment = current($mailData['attachments']);
1041 
1042  try {
1043  if ('draft' === $type) {
1044  if (!$mailFileData->checkFilesExist([$attachment])) {
1045  throw new OutOfBoundsException('');
1046  }
1047  $pathToFile = $mailFileData->getAbsoluteAttachmentPoolPathByFilename($attachment);
1048  $fileName = $attachment;
1049  } else {
1050  $file = $mailFileData->getAttachmentPathAndFilenameByMd5Hash(
1051  md5($attachment),
1052  (int) $mailId
1053  );
1054  $pathToFile = $file['path'];
1055  $fileName = $file['filename'];
1056  }
1057  ilFileDelivery::deliverFileLegacy($pathToFile, $fileName);
1058  } catch (OutOfBoundsException $e) {
1059  throw new ilMailException('mail_error_reading_attachment', $e->getCode(), $e);
1060  }
1061  } else {
1062  $mailFileData->deliverAttachmentsAsZip(
1063  $mailData['m_subject'],
1064  (int) $mailId,
1065  $mailData['attachments'],
1066  'draft' === $type
1067  );
1068  }
1069  } catch (Exception $e) {
1070  $this->tpl->setOnScreenMessage('failure', $this->lng->txt($e->getMessage()), true);
1071  $this->ctrl->setParameter($this, 'mobj_id', $this->currentFolderId);
1072  $this->ctrl->redirect($this);
1073  }
1074  }
1075 
1077  {
1078  $table = new ilMailFolderTableGUI(
1079  $this,
1080  $this->currentFolderId,
1081  'showFolder',
1082  $this->currentFolderId === $this->mbox->getTrashFolder(),
1083  $this->currentFolderId === $this->mbox->getSentFolder(),
1084  $this->currentFolderId === $this->mbox->getDraftsFolder()
1085  );
1086 
1087  return $table;
1088  }
1089 
1090  protected function applyFilter(): void
1091  {
1092  $table = $this->getMailFolderTable();
1093  $table->resetOffset();
1094  $table->writeFilterToSession();
1095 
1096  $this->showFolder();
1097  }
1098 
1099  protected function resetFilter(): void
1100  {
1101  $table = $this->getMailFolderTable();
1102  $table->resetOffset();
1103  $table->resetFilter();
1104 
1105  $this->showFolder();
1106  }
1107 }
deleteSubFolder(bool $a_show_confirm=true)
getAttachmentPathAndFilenameByMd5Hash(string $md5FileHash, int $mailId)
Interface GlobalHttpState.
static get(string $a_var)
getMailIdsFromRequest(bool $ignoreHttpGet=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An entity that renders components to a string output.
Definition: Renderer.php:30
readonly GlobalHttpState $http
readonly ilCtrlInterface $ctrl
const IL_CAL_DATETIME
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class handles all operations on files (attachments) in directory ilias_data/mail.
readonly ilTabsGUI $tabs
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
static _getIliasMailerName()
readonly ilGlobalTemplateInterface $tpl
static _lookupPref(int $a_usr_id, string $a_keyword)
final const MAIL_FORM_TYPE_REPLY
readonly Factory $ui_factory
static img(string $a_src, ?string $a_alt=null, $a_width="", $a_height="", $a_border=0, $a_id="", $a_class="")
Build img tag.
addSubFolder(ilPropertyFormGUI $form=null)
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
static htmlencodePlainString(string $a_str, bool $a_make_links_clickable, bool $a_detect_goto_links=false)
Encodes a plain text string into HTML for display in a browser.
global $DIC
Definition: feed.php:28
GUI class for public user profile presentation.
parseFolderIdFromCommand(string $command)
static http()
Fetches the global http state from ILIAS.
This class represents a property in a property form.
readonly ilObjUser $user
readonly ilLanguage $lng
getSubFolderForm(string $mode='create')
Mail Box class Base class for creating and handling mail boxes.
addSubFolderCommands(bool $isUserSubFolder=false)
renameSubFolder(ilPropertyFormGUI $form=null)
showFolder(bool $oneConfirmationDialogueRendered=false)
parseCommand(string $originalCommand)
readonly Refinery $refinery
$filename
Definition: buildRTE.php:78
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
Error Handling & global info handling.
final const MAIL_FORM_TYPE_FORWARD
readonly Renderer $ui_renderer
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
readonly ilToolbarGUI $toolbar
$message
Definition: xapiexit.php:32
readonly ilErrorHandling $error
static set(string $a_var, $a_val)
Set a value.
static _lookupLogin(int $a_user_id)