ILIAS  release_8 Revision v8.19-1-g4e8f2f9140c
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilMailFormGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 
33 {
34  public const MAIL_FORM_TYPE_ATTACH = 'attach';
35  public const MAIL_FORM_TYPE_SEARCH_RESULT = 'search_res';
36  public const MAIL_FORM_TYPE_NEW = 'new';
37  public const MAIL_FORM_TYPE_ROLE = 'role';
38  public const MAIL_FORM_TYPE_REPLY = 'reply';
39  public const MAIL_FORM_TYPE_ADDRESS = 'address';
40  public const MAIL_FORM_TYPE_FORWARD = 'forward';
41  public const MAIL_FORM_TYPE_DRAFT = 'draft';
42 
45  private ilLanguage $lng;
46  private ilObjUser $user;
47  private ilTabsGUI $tabs;
50  private ilMailbox $mbox;
54  private ?array $requestAttachments = null;
57  private string $mail_form_type = '';
58 
59  public function __construct(
60  ilMailTemplateService $templateService = null,
61  ilMailBodyPurifier $bodyPurifier = null
62  ) {
63  global $DIC;
64  $this->templateService = $templateService ?? $DIC['mail.texttemplates.service'];
65  $this->tpl = $DIC->ui()->mainTemplate();
66  $this->ctrl = $DIC->ctrl();
67  $this->lng = $DIC->language();
68  $this->user = $DIC->user();
69  $this->tabs = $DIC->tabs();
70  $this->toolbar = $DIC->toolbar();
71  $this->http = $DIC->http();
72  $this->refinery = $DIC->refinery();
73  $this->umail = new ilFormatMail($this->user->getId());
74  $this->mfile = new ilFileDataMail($this->user->getId());
75  $this->mbox = new ilMailbox($this->user->getId());
76  $this->purifier = $bodyPurifier ?? new ilMailBodyPurifier();
77 
78  $requestMailObjId = $this->getBodyParam(
79  'mobj_id',
80  $this->refinery->kindlyTo()->int(),
81  $this->getQueryParam(
82  'mobj_id',
83  $this->refinery->kindlyTo()->int(),
84  0
85  )
86  );
87 
88  if (0 === $requestMailObjId) {
89  $requestMailObjId = $this->mbox->getInboxFolder();
90  }
91 
92  $this->ctrl->setParameter($this, 'mobj_id', $requestMailObjId);
93  }
94 
95  private function getQueryParam(string $name, Transformation $trafo, $default = null)
96  {
97  if ($this->http->wrapper()->query()->has($name)) {
98  return $this->http->wrapper()->query()->retrieve(
99  $name,
100  $trafo
101  );
102  }
103 
104  return $default;
105  }
106 
107  private function getBodyParam(string $name, Transformation $trafo, $default = null)
108  {
109  if ($this->http->wrapper()->post()->has($name)) {
110  return $this->http->wrapper()->post()->retrieve(
111  $name,
112  $trafo
113  );
114  }
115 
116  return $default;
117  }
118 
119  public function executeCommand(): void
120  {
121  $forward_class = $this->ctrl->getNextClass($this);
122  switch (strtolower($forward_class)) {
123  case strtolower(ilMailAttachmentGUI::class):
124  $this->ctrl->setReturn($this, 'returnFromAttachments');
125  $this->ctrl->forwardCommand(new ilMailAttachmentGUI());
126  break;
127 
128  case strtolower(ilMailSearchGUI::class):
129  $this->ctrl->setReturn($this, 'searchResults');
130  $this->ctrl->forwardCommand(new ilMailSearchGUI());
131  break;
132 
133  case strtolower(ilMailSearchCoursesGUI::class):
134  $this->ctrl->setReturn($this, 'searchResults');
135  $this->ctrl->forwardCommand(new ilMailSearchCoursesGUI());
136  break;
137 
138  case strtolower(ilMailingListsGUI::class):
139  $this->ctrl->setReturn($this, 'searchResults');
140  $this->ctrl->forwardCommand(new ilMailingListsGUI());
141  break;
142 
143  case strtolower(ilMailSearchGroupsGUI::class):
144  $this->ctrl->setReturn($this, 'searchResults');
145  $this->ctrl->forwardCommand(new ilMailSearchGroupsGUI());
146  break;
147 
148  default:
149  if (!($cmd = $this->ctrl->getCmd())) {
150  $cmd = 'showForm';
151  }
152 
153  $this->$cmd();
154  break;
155  }
156  }
157 
162  protected function decodeAttachmentFiles(array $files): array
163  {
164  $decodedFiles = [];
165 
166  foreach ($files as $value) {
167  if (is_file($this->mfile->getMailPath() . '/' . $this->user->getId() . '_' . urldecode($value))) {
168  $decodedFiles[] = urldecode($value);
169  }
170  }
171 
172  return $decodedFiles;
173  }
174 
175  public function sendMessage(): void
176  {
177  $message = $this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), '');
178 
179  $mailBody = new ilMailBody($message, $this->purifier);
180 
181  $sanitizedMessage = $mailBody->getContent();
182 
183  $attachments = $this->getBodyParam(
184  'attachments',
185  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
186  []
187  );
188  $files = $this->decodeAttachmentFiles($attachments);
189 
190  $mailer = $this->umail
191  ->withContextId(ilMailFormCall::getContextId() ?: '')
192  ->withContextParameters(ilMailFormCall::getContextParameters());
193 
194  $mailer->setSaveInSentbox(true);
195 
196  if ($errors = $mailer->enqueue(
197  ilUtil::securePlainString($this->getBodyParam('rcp_to', $this->refinery->kindlyTo()->string(), '')),
198  ilUtil::securePlainString($this->getBodyParam('rcp_cc', $this->refinery->kindlyTo()->string(), '')),
199  ilUtil::securePlainString($this->getBodyParam('rcp_bcc', $this->refinery->kindlyTo()->string(), '')),
200  ilUtil::securePlainString($this->getBodyParam('m_subject', $this->refinery->kindlyTo()->string(), '')),
201  $sanitizedMessage,
202  $files,
203  $this->getBodyParam('use_placeholders', $this->refinery->kindlyTo()->bool(), false)
204  )) {
205  $this->requestAttachments = $files;
207  } else {
208  $mailer->persistToStage(
209  $this->user->getId(),
210  [],
211  '',
212  '',
213  '',
214  '',
215  ''
216  );
217 
218  $this->ctrl->setParameterByClass(ilMailGUI::class, 'type', 'message_sent');
219 
221  $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_message_send'), true);
222  $this->ctrl->redirectToURL(ilMailFormCall::getRefererRedirectUrl());
223  } else {
224  $this->ctrl->redirectByClass(ilMailGUI::class);
225  }
226  }
227 
228  $this->showForm();
229  }
230 
231  public function saveDraft(): void
232  {
233  $draftFolderId = $this->mbox->getDraftsFolder();
234 
235  $files = $this->decodeAttachmentFiles($this->getBodyParam(
236  'attachments',
237  $this->refinery->kindlyTo()->listOf(
238  $this->refinery->custom()->transformation($this->refinery->kindlyTo()->string())
239  ),
240  []
241  ));
242 
243  $rcp_to = ilUtil::securePlainString($this->getBodyParam('rcp_to', $this->refinery->kindlyTo()->string(), ''));
244  $rcp_cc = ilUtil::securePlainString($this->getBodyParam('rcp_cc', $this->refinery->kindlyTo()->string(), ''));
245  $rcp_bcc = ilUtil::securePlainString($this->getBodyParam('rcp_bcc', $this->refinery->kindlyTo()->string(), ''));
246 
247  if ($errors = $this->umail->validateRecipients(
248  $rcp_to,
249  $rcp_cc,
250  $rcp_bcc,
251  )) {
252  $this->requestAttachments = $files;
254  $this->showForm();
255  return;
256  }
257 
258  if (ilSession::get('draft')) {
259  $draftId = (int) ilSession::get('draft');
260  ilSession::clear('draft');
261  } else {
262  $draftId = $this->umail->getNewDraftId($draftFolderId);
263  }
264 
265  $this->umail->updateDraft(
266  $draftFolderId,
267  $files,
268  $rcp_to,
269  $rcp_cc,
270  $rcp_bcc,
272  $this->getBodyParam('m_subject', $this->refinery->kindlyTo()->string(), '')
273  ) ?: 'No Subject',
274  ilUtil::securePlainString($this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), '')),
275  $draftId,
276  $this->getBodyParam('use_placeholders', $this->refinery->kindlyTo()->bool(), false),
279  );
280 
281  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_saved'), true);
282 
285  } else {
286  $this->ctrl->redirectByClass([ilMailGUI::class, ilMailFolderGUI::class]);
287  }
288 
289  $this->showForm();
290  }
291 
292  public function searchUsers(bool $save = true): void
293  {
294  $this->tpl->setTitle($this->lng->txt('mail'));
295 
296  if ($save) {
297  $files = $this->getBodyParam(
298  'attachments',
299  $this->refinery->kindlyTo()->listOf(
300  $this->refinery->custom()->transformation(function ($elm): string {
301  $attachment = $this->refinery->kindlyTo()->string()->transform($elm);
302 
303  return urldecode($attachment);
304  })
305  ),
306  []
307  );
308 
309  // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
310  $this->umail->persistToStage(
311  $this->user->getId(),
312  $files,
313  ilUtil::securePlainString($this->getBodyParam('rcp_to', $this->refinery->kindlyTo()->string(), '')),
314  ilUtil::securePlainString($this->getBodyParam('rcp_cc', $this->refinery->kindlyTo()->string(), '')),
315  ilUtil::securePlainString($this->getBodyParam('rcp_bcc', $this->refinery->kindlyTo()->string(), '')),
316  ilUtil::securePlainString($this->getBodyParam('m_subject', $this->refinery->kindlyTo()->string(), '')),
317  ilUtil::securePlainString($this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), '')),
318  $this->getBodyParam('use_placeholders', $this->refinery->kindlyTo()->bool(), false),
321  );
322  }
323 
324  $form = new ilPropertyFormGUI();
325  $form->setId('search_rcp');
326  $form->setTitle($this->lng->txt('search_recipients'));
327  $form->setFormAction($this->ctrl->getFormAction($this, 'search'));
328 
329  $inp = new ilTextInputGUI($this->lng->txt('search_for'), 'search');
330  $inp->setSize(30);
331  $dsDataLink = $this->ctrl->getLinkTarget($this, 'lookupRecipientAsync', '', true);
332  $inp->setDataSource($dsDataLink);
333 
334  $searchQuery = trim((string) ilSession::get('mail_search_search'));
335  if ($searchQuery !== '') {
336  $inp->setValue(ilLegacyFormElementsUtil::prepareFormOutput($searchQuery, true));
337  }
338  $form->addItem($inp);
339 
340  $form->addCommandButton('search', $this->lng->txt('search'));
341  $form->addCommandButton('cancelSearch', $this->lng->txt('cancel'));
342 
343  $this->tpl->setContent($form->getHTML());
344  $this->tpl->printToStdout();
345  }
346 
347  public function searchCoursesTo(): void
348  {
349  $this->saveMailBeforeSearch();
350 
351  if (ilSession::get('search_crs')) {
352  $this->ctrl->setParameterByClass('ilmailsearchcoursesgui', 'cmd', 'showMembers');
353  }
354 
355  $this->ctrl->setParameterByClass(ilMailSearchCoursesGUI::class, 'ref', 'mail');
356  $this->ctrl->redirectByClass(ilMailSearchCoursesGUI::class);
357  }
358 
359  public function searchGroupsTo(): void
360  {
361  $this->saveMailBeforeSearch();
362 
363  $this->ctrl->setParameterByClass(ilMailSearchGroupsGUI::class, 'ref', 'mail');
364  $this->ctrl->redirectByClass(ilMailSearchGroupsGUI::class);
365  }
366 
367  public function search(): void
368  {
370  'mail_search_search',
371  ilUtil::securePlainString($this->getBodyParam('search', $this->refinery->kindlyTo()->string(), ''))
372  );
373 
374  if (trim(ilSession::get('mail_search_search')) === '') {
375  $this->tpl->setOnScreenMessage('info', $this->lng->txt("mail_insert_query"));
376  $this->searchUsers(false);
377  } elseif (strlen(trim(ilSession::get('mail_search_search'))) < 3) {
378  $this->lng->loadLanguageModule('search');
379  $this->tpl->setOnScreenMessage('info', $this->lng->txt('search_minimum_three'));
380  $this->searchUsers(false);
381  } else {
382  $this->ctrl->setParameterByClass(
383  ilMailSearchGUI::class,
384  'search',
385  urlencode(ilSession::get('mail_search_search'))
386  );
387  $this->ctrl->redirectByClass(ilMailSearchGUI::class);
388  }
389  }
390 
391  public function cancelSearch(): void
392  {
393  ilSession::clear('mail_search');
394  $this->searchResults();
395  }
396 
397  public function editAttachments(): void
398  {
399  $files = $this->getBodyParam(
400  'attachments',
401  $this->refinery->kindlyTo()->listOf(
402  $this->refinery->custom()->transformation(function ($elm): string {
403  $attachment = $this->refinery->kindlyTo()->string()->transform($elm);
404 
405  return urldecode($attachment);
406  })
407  ),
408  []
409  );
410 
411  // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
412  $this->umail->persistToStage(
413  $this->user->getId(),
414  $files,
415  ilUtil::securePlainString($this->getBodyParam('rcp_to', $this->refinery->kindlyTo()->string(), '')),
416  ilUtil::securePlainString($this->getBodyParam('rcp_cc', $this->refinery->kindlyTo()->string(), '')),
417  ilUtil::securePlainString($this->getBodyParam('rcp_bcc', $this->refinery->kindlyTo()->string(), '')),
418  ilUtil::securePlainString($this->getBodyParam('m_subject', $this->refinery->kindlyTo()->string(), '')),
419  ilUtil::securePlainString($this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), '')),
420  $this->getBodyParam('use_placeholders', $this->refinery->kindlyTo()->bool(), false),
423  );
424 
425  $this->ctrl->redirectByClass(ilMailAttachmentGUI::class);
426  }
427 
428  public function returnFromAttachments(): void
429  {
430  $this->mail_form_type = self::MAIL_FORM_TYPE_ATTACH;
431  $this->showForm();
432  }
433 
434  public function searchResults(): void
435  {
436  $this->mail_form_type = self::MAIL_FORM_TYPE_SEARCH_RESULT;
437  $this->showForm();
438  }
439 
440  public function mailUser(): void
441  {
442  $this->mail_form_type = self::MAIL_FORM_TYPE_NEW;
443  $this->showForm();
444  }
445 
446  public function mailRole(): void
447  {
448  $this->mail_form_type = self::MAIL_FORM_TYPE_ROLE;
449  $this->showForm();
450  }
451 
452  public function replyMail(): void
453  {
454  $this->mail_form_type = self::MAIL_FORM_TYPE_REPLY;
455  $this->showForm();
456  }
457 
458  public function mailAttachment(): void
459  {
460  $this->mail_form_type = self::MAIL_FORM_TYPE_ATTACH;
461  $this->showForm();
462  }
463 
464  protected function getTemplateDataById(): void
465  {
466  if (!$this->http->wrapper()->query()->has('template_id')) {
467  $this->http->close();
468  }
469 
470  try {
471  $template = $this->templateService->loadTemplateForId(
472  $this->http->wrapper()->query()->retrieve('template_id', $this->refinery->kindlyTo()->int())
473  );
475 
476  $this->http->saveResponse(
477  $this->http->response()
478  ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
479  ->withBody(Streams::ofString(json_encode([
480  'm_subject' => $template->getSubject(),
481  'm_message' => $this->umail->appendSignature($template->getMessage()),
482  ], JSON_THROW_ON_ERROR)))
483  );
484  } catch (Exception $e) {
485  }
486 
487  $this->http->sendResponse();
488  $this->http->close();
489  }
490 
491  public function showForm(): void
492  {
493  $this->tpl->addBlockFile(
494  'ADM_CONTENT',
495  'adm_content',
496  'tpl.mail_new.html',
497  'Services/Mail'
498  );
499  $this->tpl->setTitle($this->lng->txt('mail'));
500 
501  $this->lng->loadLanguageModule('crs');
502 
504  $this->tabs->setBackTarget(
505  $this->lng->txt('back'),
506  $this->ctrl->getLinkTarget($this, 'cancelMail')
507  );
508  }
509 
510  $mailData = [];
511  $mailData['rcp_to'] = '';
512  $mailData['rcp_cc'] = '';
513  $mailData['rcp_bcc'] = '';
514  $mailData['attachments'] = [];
515 
516  $mailId = $this->getQueryParam('mail_id', $this->refinery->kindlyTo()->int(), 0);
517  $type = $this->getQueryParam('type', $this->refinery->kindlyTo()->string(), '');
518  if ($this->mail_form_type !== '') {
519  $type = $this->mail_form_type;
520  }
521 
522  switch ($type) {
523  case self::MAIL_FORM_TYPE_REPLY:
524  $mailData = $this->umail->getMail($mailId);
525 
526  $mailData['m_subject'] = $this->umail->formatReplySubject($mailData['m_subject'] ?? '');
527  $mailData['m_message'] = $this->umail->prependSignature(
528  $this->umail->formatReplyMessage($mailData['m_message'] ?? '')
529  );
530  $mailData['attachments'] = [];
531  $mailData['rcp_cc'] = '';
532  $mailData['rcp_to'] = $this->umail->formatReplyRecipient();
533  break;
534 
535  case self::MAIL_FORM_TYPE_SEARCH_RESULT:
536  $mailData = $this->umail->retrieveFromStage();
537 
538  if (ilSession::get('mail_search_results_to')) {
539  $mailData = $this->umail->appendSearchResult(
540  $this->refinery->kindlyTo()->listOf(
541  $this->refinery->kindlyTo()->string()
542  )->transform(ilSession::get('mail_search_results_to')),
543  'to'
544  );
545  }
546  if (ilSession::get('mail_search_results_cc')) {
547  $mailData = $this->umail->appendSearchResult(
548  $this->refinery->kindlyTo()->listOf(
549  $this->refinery->kindlyTo()->string()
550  )->transform(ilSession::get('mail_search_results_cc')),
551  'cc'
552  );
553  }
554  if (ilSession::get('mail_search_results_bcc')) {
555  $mailData = $this->umail->appendSearchResult(
556  $this->refinery->kindlyTo()->listOf(
557  $this->refinery->kindlyTo()->string()
558  )->transform(ilSession::get('mail_search_results_bcc')),
559  'bc'
560  );
561  }
562 
563  ilSession::clear('mail_search_results_to');
564  ilSession::clear('mail_search_results_cc');
565  ilSession::clear('mail_search_results_bcc');
566  break;
567 
568  case self::MAIL_FORM_TYPE_ATTACH:
569  $mailData = $this->umail->retrieveFromStage();
570  break;
571 
572  case self::MAIL_FORM_TYPE_DRAFT:
573  ilSession::set('draft', $mailId);
574  $mailData = $this->umail->getMail($mailId);
575  ilMailFormCall::setContextId($mailData['tpl_ctx_id']);
576  ilMailFormCall::setContextParameters($mailData['tpl_ctx_params']);
577  break;
578 
579  case self::MAIL_FORM_TYPE_FORWARD:
580  $mailData = $this->umail->getMail($mailId);
581  $mailData['rcp_to'] = $mailData['rcp_cc'] = $mailData['rcp_bcc'] = '';
582  $mailData['m_subject'] = $this->umail->formatForwardSubject($mailData['m_subject'] ?? '');
583  $mailData['m_message'] = $this->umail->prependSignature($mailData['m_message'] ?? '');
584  if (is_array($mailData['attachments']) && count($mailData['attachments']) && $error = $this->mfile->adoptAttachments(
585  $mailData['attachments'],
586  $mailId
587  )) {
588  $this->tpl->setOnScreenMessage('info', $error);
589  }
590  break;
591 
592  case self::MAIL_FORM_TYPE_NEW:
593  // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
594  $to = ilUtil::securePlainString($this->getQueryParam('rcp_to', $this->refinery->kindlyTo()->string(), ''));
595  if ($to === '' && ilSession::get('rcp_to')) {
596  $to = ilSession::get('rcp_to');
597  }
598  $mailData['rcp_to'] = $to;
599 
600  $cc = ilUtil::securePlainString($this->getQueryParam('rcp_cc', $this->refinery->kindlyTo()->string(), ''));
601  if ($cc === '' && ilSession::get('rcp_cc')) {
602  $cc = ilSession::get('rcp_cc');
603  }
604  $mailData['rcp_cc'] = $cc;
605 
606  $bcc = ilUtil::securePlainString($this->getQueryParam('rcp_bcc', $this->refinery->kindlyTo()->string(), ''));
607  if ($bcc === '' && ilSession::get('rcp_bcc')) {
608  $bcc = ilSession::get('rcp_bcc');
609  }
610  $mailData['rcp_bcc'] = $bcc;
611 
612  $mailData['m_message'] = '';
613  if (($sig = ilMailFormCall::getSignature()) !== '') {
614  $mailData['m_message'] = $sig;
615  $mailData['m_message'] .= chr(13)
616  . chr(10)
617  . chr(13)
618  . chr(10);
619  }
620  $mailData['m_message'] .= $this->umail->appendSignature('');
621 
622  ilSession::set('rcp_to', '');
623  ilSession::set('rcp_cc', '');
624  ilSession::set('rcp_bcc', '');
625  break;
626 
627  case self::MAIL_FORM_TYPE_ROLE:
628  $roles = [];
629  if ($this->http->wrapper()->post()->has('roles')) {
630  $roles = $this->http->wrapper()->post()->retrieve(
631  'roles',
632  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
633  );
634  } elseif (is_array(ilSession::get('mail_roles'))) {
635  $roles = $this->refinery->kindlyTo()->listOf(
636  $this->refinery->kindlyTo()->string()
637  )->transform(ilSession::get('mail_roles'));
638  }
639 
640  // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
641  $mailData['rcp_to'] = ilUtil::securePlainString(
642  implode(',', $roles)
643  );
644 
645  $mailData['m_message'] = '';
646  if (($sig = ilMailFormCall::getSignature()) !== '') {
647  $mailData['m_message'] = $sig;
648  $mailData['m_message'] .= chr(13)
649  . chr(10)
650  . chr(13)
651  . chr(10);
652  }
653 
654  $additionalMessageText = '';
655  if ($this->http->wrapper()->post()->has('additional_message_text')) {
656  $additionalMessageText = ilUtil::securePlainString($this->http->wrapper()->post()->retrieve(
657  'additional_message_text',
658  $this->refinery->kindlyTo()->string()
659  ));
660  }
661 
662  $mailData['m_message'] .= $additionalMessageText
663  . chr(13)
664  . chr(10)
665  . $this->umail->appendSignature('');
666  ilSession::set('mail_roles', []);
667  break;
668 
669  case self::MAIL_FORM_TYPE_ADDRESS:
670  $rcp = '';
671  if ($this->http->wrapper()->query()->has('rcp')) {
672  $rcp = $this->http->wrapper()->query()->retrieve('rcp', $this->refinery->kindlyTo()->string());
673  }
674  $mailData['rcp_to'] = urldecode($rcp);
675  break;
676 
677  default:
678  $mailData = $this->http->request()->getParsedBody();
679  foreach ($mailData as $key => $value) {
680  if (is_string($value)) {
681  // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
682  $mailData[$key] = ilUtil::securePlainString($value);
683  }
684  }
685 
686  if ($this->requestAttachments) {
687  $mailData['attachments'] = $this->requestAttachments;
688  }
689  break;
690  }
691 
692  $form_gui = new ilPropertyFormGUI();
693  $form_gui->setTitle($this->lng->txt('compose'));
694  $form_gui->setId('mail_compose_form');
695  $form_gui->setName('mail_compose_form');
696  $form_gui->setFormAction($this->ctrl->getFormAction($this, 'sendMessage'));
697 
698  $this->tpl->setVariable('FORM_ID', $form_gui->getId());
699 
700  $btn = ilButton::getInstance();
701  $btn->setButtonType(ilButton::BUTTON_TYPE_SUBMIT);
702  $btn->setForm('form_' . $form_gui->getName())
703  ->setName('searchUsers')
704  ->setCaption('search_recipients');
705  $this->toolbar->addStickyItem($btn);
706 
707  $btn = ilButton::getInstance();
708  $btn->setButtonType(ilButton::BUTTON_TYPE_SUBMIT)
709  ->setName('searchCoursesTo')
710  ->setForm('form_' . $form_gui->getName())
711  ->setCaption('mail_my_courses');
712  $this->toolbar->addButtonInstance($btn);
713 
714  $btn = ilButton::getInstance();
715  $btn->setButtonType(ilButton::BUTTON_TYPE_SUBMIT)
716  ->setName('searchGroupsTo')
717  ->setForm('form_' . $form_gui->getName())
718  ->setCaption('mail_my_groups');
719  $this->toolbar->addButtonInstance($btn);
720 
721  if (count(ilBuddyList::getInstanceByGlobalUser()->getLinkedRelations()) > 0) {
722  $btn = ilButton::getInstance();
723  $btn->setButtonType(ilButton::BUTTON_TYPE_SUBMIT)
724  ->setName('searchMailingListsTo')
725  ->setForm('form_' . $form_gui->getName())
726  ->setCaption('mail_my_mailing_lists');
727  $this->toolbar->addButtonInstance($btn);
728  }
729 
730  $dsDataLink = $this->ctrl->getLinkTarget($this, 'lookupRecipientAsync', '', true);
731 
732  $inp = new ilTextInputGUI($this->lng->txt('mail_to'), 'rcp_to');
733  $inp->setMaxLength(null);
734  $inp->setRequired(true);
735  $inp->setSize(50);
736  $inp->setValue((string) ($mailData['rcp_to'] ?? ''));
737  $inp->setDataSource($dsDataLink, ',');
738  $form_gui->addItem($inp);
739 
740  $inp = new ilTextInputGUI($this->lng->txt('mail_cc'), 'rcp_cc');
741  $inp->setMaxLength(null);
742  $inp->setSize(50);
743  $inp->setValue((string) ($mailData['rcp_cc'] ?? ''));
744  $inp->setDataSource($dsDataLink, ',');
745  $form_gui->addItem($inp);
746 
747  $inp = new ilTextInputGUI($this->lng->txt('mail_bcc'), 'rcp_bcc');
748  $inp->setMaxLength(null);
749  $inp->setSize(50);
750  $inp->setValue($mailData['rcp_bcc'] ?? '');
751  $inp->setDataSource($dsDataLink, ',');
752  $form_gui->addItem($inp);
753 
754  $inp = new ilTextInputGUI($this->lng->txt('subject'), 'm_subject');
755  $inp->setSize(50);
756  $inp->setRequired(true);
757  $inp->setValue((string) ($mailData['m_subject'] ?? ''));
758  $form_gui->addItem($inp);
759 
761  $this->lng->txt(
762  isset($mailData['attachments']) && is_array($mailData['attachments']) ?
763  'edit' :
764  'add'
765  )
766  );
767  if (isset($mailData['attachments']) && is_array($mailData['attachments'])) {
768  foreach ($mailData['attachments'] as $data) {
769  if (is_file($this->mfile->getMailPath() . '/' . $this->user->getId() . '_' . $data)) {
770  $hidden = new ilHiddenInputGUI('attachments[]');
771  $form_gui->addItem($hidden);
772  $size = filesize($this->mfile->getMailPath() . '/' . $this->user->getId() . '_' . $data);
773  $label = $data . ' [' . ilUtil::formatSize($size) . ']';
774  $att->addItem($label);
775  $hidden->setValue(urlencode($data));
776  }
777  }
778  }
779  $form_gui->addItem($att);
780 
783  $context_id = ilMailFormCall::getContextId();
784 
785  $mailData['use_placeholders'] = true;
786 
787  try {
789 
790  $templates = $this->templateService->loadTemplatesForContextId($context->getId());
791  if (count($templates) > 0) {
792  $options = [];
793 
794  $template_chb = new ilMailTemplateSelectInputGUI(
795  $this->lng->txt('mail_template_client'),
796  'template_id',
797  $this->ctrl->getLinkTarget($this, 'getTemplateDataById', '', true),
798  ['m_subject' => false, 'm_message' => true]
799  );
800 
801  foreach ($templates as $template) {
802  $options[$template->getTplId()] = $template->getTitle();
803 
804  if (!isset($mailData['template_id']) && $template->isDefault()) {
805  $template_chb->setValue((string) $template->getTplId());
806  $form_gui->getItemByPostVar('m_subject')->setValue($template->getSubject());
807  $mailData['m_message'] = $template->getMessage() . $this->umail->appendSignature(
808  $mailData['m_message']
809  );
810  }
811  }
812  if (isset($mailData['template_id'])) {
813  $template_chb->setValue((string) ((int) $mailData['template_id']));
814  }
815  asort($options);
816 
817  $template_chb->setInfo($this->lng->txt('mail_template_client_info'));
818  $template_chb->setOptions(['' => $this->lng->txt('please_choose')] + $options);
819  $form_gui->addItem($template_chb);
820  }
821  } catch (Exception $e) {
822  ilLoggerFactory::getLogger('mail')->error(sprintf(
823  '%s has been called with invalid context id: %s.',
824  __METHOD__,
825  $context_id
826  ));
827  }
828  }
829 
830  $inp = new ilTextAreaInputGUI($this->lng->txt('message_content'), 'm_message');
831  $inp->setValue((string) ($mailData['m_message'] ?? ''));
832  $inp->setRequired(false);
833  $inp->setCols(60);
834  $inp->setRows(10);
835  $form_gui->addItem($inp);
836 
837  $chb = new ilCheckboxInputGUI(
838  $this->lng->txt('mail_serial_letter_placeholders'),
839  'use_placeholders'
840  );
841  $chb->setValue('1');
842  $chb->setChecked(isset($mailData['use_placeholders']) && $mailData['use_placeholders']);
843 
844  $placeholders = new ilManualPlaceholderInputGUI($this->lng->txt('mail_form_placeholders_label'), 'm_message');
845  $placeholders->setInstructionText($this->lng->txt('mail_nacc_use_placeholder'));
846  try {
847  $placeholders->setAdviseText(sprintf($this->lng->txt('placeholders_advise'), '<br />'));
848  } catch (Throwable $e) {
849  $placeholders->setAdviseText($this->lng->txt('placeholders_advise'));
850  }
851  foreach ($context->getPlaceholders() as $key => $value) {
852  $placeholders->addPlaceholder($value['placeholder'], $value['label']);
853  }
854  $chb->addSubItem($placeholders);
855  $form_gui->addItem($chb);
856 
857  $form_gui->addCommandButton('sendMessage', $this->lng->txt('send_mail'));
858  $form_gui->addCommandButton('saveDraft', $this->lng->txt('save_message'));
860  $form_gui->addCommandButton('cancelMail', $this->lng->txt('cancel'));
861  }
862 
863  $this->tpl->parseCurrentBlock();
864 
865  $this->tpl->setVariable('FORM', $form_gui->getHTML());
866 
867  $this->tpl->addJavaScript('Services/Mail/js/ilMailComposeFunctions.js');
868  $this->tpl->printToStdout();
869  }
870 
871  public function lookupRecipientAsync(): void
872  {
873  $search = trim($this->getBodyParam(
874  'term',
875  $this->refinery->kindlyTo()->string(),
876  $this->getQueryParam(
877  'term',
878  $this->refinery->kindlyTo()->string(),
879  ''
880  )
881  ));
882 
883  $result = [];
884 
885  if (ilStr::strLen($search) < 3) {
886  $this->http->saveResponse(
887  $this->http->response()
888  ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
889  ->withBody(Streams::ofString(json_encode($result, JSON_THROW_ON_ERROR)))
890  );
891 
892  $this->http->sendResponse();
893  $this->http->close();
894  }
895 
896  // #14768
897  $quoted = ilUtil::stripSlashes($search);
898  $quoted = str_replace(['%', '_'], ['\%', '\_'], $quoted);
899 
900  $mailFormObj = new ilMailForm();
901  $result = $mailFormObj->getRecipientAsync("%" . $quoted . "%", ilUtil::stripSlashes($search));
902 
903  $this->http->saveResponse(
904  $this->http->response()
905  ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
906  ->withBody(Streams::ofString(json_encode($result, JSON_THROW_ON_ERROR)))
907  );
908  $this->http->sendResponse();
909  $this->http->close();
910  }
911 
912  public function cancelMail(): void
913  {
916  }
917 
918  $this->showForm();
919  }
920 
921  protected function saveMailBeforeSearch(): void
922  {
923  $files = $this->getBodyParam(
924  'attachments',
925  $this->refinery->kindlyTo()->listOf(
926  $this->refinery->custom()->transformation(function ($elm): string {
927  $attachment = $this->refinery->kindlyTo()->string()->transform($elm);
928 
929  return urldecode($attachment);
930  })
931  ),
932  []
933  );
934 
935  $this->umail->persistToStage(
936  $this->user->getId(),
937  $files,
938  ilUtil::securePlainString($this->getBodyParam('rcp_to', $this->refinery->kindlyTo()->string(), '')),
939  ilUtil::securePlainString($this->getBodyParam('rcp_cc', $this->refinery->kindlyTo()->string(), '')),
940  ilUtil::securePlainString($this->getBodyParam('rcp_bcc', $this->refinery->kindlyTo()->string(), '')),
941  ilUtil::securePlainString($this->getBodyParam('m_subject', $this->refinery->kindlyTo()->string(), '')),
942  ilUtil::securePlainString($this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), '')),
943  $this->getBodyParam('use_placeholders', $this->refinery->kindlyTo()->bool(), false),
946  );
947  }
948 
949  public function searchMailingListsTo(): void
950  {
951  $this->saveMailBeforeSearch();
952 
953  $this->ctrl->setParameterByClass(ilMailingListsGUI::class, 'ref', 'mail');
954  $this->ctrl->redirectByClass(ilMailingListsGUI::class);
955  }
956 
960  protected function showSubmissionErrors(array $errors): void
961  {
962  $formatter = new ilMailErrorFormatter($this->lng);
963  $formattedErrors = $formatter->format($errors);
964 
965  if ($formattedErrors !== '') {
966  $this->tpl->setOnScreenMessage('failure', $formattedErrors);
967  }
968  }
969 }
Interface GlobalHttpState.
GlobalHttpState $http
static get(string $a_var)
decodeAttachmentFiles(array $files)
$context
Definition: webdav.php:29
static getInstanceByGlobalUser()
static getLogger(string $a_component_id)
Get component logger.
ilMailTemplateService $templateService
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$errors
Definition: imgupload.php:65
$type
This class handles all operations on files (attachments) in directory ilias_data/mail.
static getInstance()
Class ilMailErrorFormatter.
ilCtrlInterface $ctrl
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
Class ilMailTemplateService.
ilGlobalTemplateInterface $tpl
This class represents a checkbox property in a property form.
static prepareFormOutput($a_str, bool $a_strip=false)
ilMailBodyPurifier $purifier
Class ilManualPlaceholderInputGUI.
global $DIC
Definition: feed.php:28
static strLen(string $a_string)
Definition: class.ilStr.php:63
if($format !==null) $name
Definition: metadata.php:247
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
static securePlainString(string $a_str)
ilFileDataMail $mfile
const MAIL_FORM_TYPE_SEARCH_RESULT
searchUsers(bool $save=true)
Class ilMailTemplateSelectInputGUI.
Mail Box class Base class for creating and handling mail boxes.
static formatSize(int $size, string $a_mode='short', ?ilLanguage $a_lng=null)
Returns the specified file size value in a human friendly form.
string $key
Consumer key/client ID value.
Definition: System.php:193
getQueryParam(string $name, Transformation $trafo, $default=null)
static setContextParameters(array $parameters)
getBodyParam(string $name, Transformation $trafo, $default=null)
static redirect(string $a_script)
showSubmissionErrors(array $errors)
This class represents a text area property in a property form.
__construct(ilMailTemplateService $templateService=null, ilMailBodyPurifier $bodyPurifier=null)
ilFormatMail $umail
A transformation is a function from one datatype to another.
ilToolbarGUI $toolbar
static setContextId(?string $id)
$message
Definition: xapiexit.php:32
const BUTTON_TYPE_SUBMIT
The button submits the form data to the server.
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.