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