ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilMailFormGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23use ILIAS\Refinery\Factory as Refinery;
36use ILIAS\Data\Factory as DataFactory;
40
46{
47 use FileDataRCHandling;
48
49 final public const string MAIL_FORM_TYPE_ATTACH = 'attach';
50 final public const string MAIL_FORM_TYPE_SEARCH_RESULT = 'search_res';
51 final public const string MAIL_FORM_TYPE_NEW = 'new';
52 final public const string MAIL_FORM_TYPE_ROLE = 'role';
53 final public const string MAIL_FORM_TYPE_REPLY = 'reply';
54 final public const string MAIL_FORM_TYPE_ADDRESS = 'address';
55 final public const string MAIL_FORM_TYPE_FORWARD = 'forward';
56 final public const string MAIL_FORM_TYPE_DRAFT = 'draft';
57 final public const string MAIL_FORM_TYPE_OUTBOX = 'outbox';
58 final public const string MAIL_FORM_MODE_REGULAR_MAIL = 'regular_mail';
59 final public const string MAIL_FORM_MODE_SERIAL_LETTER = 'serial_letter';
60
62 private readonly ilCtrlInterface $ctrl;
63 private readonly ilLanguage $lng;
64 private readonly ilObjUser $user;
65 private readonly ilTabsGUI $tabs;
66 private readonly ilToolbarGUI $toolbar;
67 private readonly ilFormatMail $umail;
68 private readonly ilMailbox $mbox;
69 private readonly ilFileDataMail $mfile;
70 private readonly GlobalHttpState $http;
71 private readonly Refinery $refinery;
72 private ?array $request_attachments = null;
74 private readonly ilMailBodyPurifier $purifier;
75 private string $mail_form_type = '';
76 private readonly Factory $ui_factory;
77 private readonly Renderer $ui_renderer;
78 private readonly \Psr\Http\Message\ServerRequestInterface $request;
82 private readonly ilFileDataMail $fdm;
84 private readonly ilSetting $settings;
85 private readonly \ILIAS\User\Search\Search $user_search;
86 private readonly ClockFactory $clock;
87
88 public function __construct(
90 ?ilMailBodyPurifier $body_purifier = null
91 ) {
92 global $DIC;
93
94 $this->template_service = $template_service ?? $DIC->mail()->textTemplates();
95 $this->tpl = $DIC->ui()->mainTemplate();
96 $this->ctrl = $DIC->ctrl();
97 $this->lng = $DIC->language();
98 $this->user = $DIC->user();
99 $this->tabs = $DIC->tabs();
100 $this->toolbar = $DIC->toolbar();
101 $this->http = $DIC->http();
102 $this->refinery = $DIC->refinery();
103 $this->umail = new ilFormatMail($this->user->getId());
104 $this->mfile = new ilFileDataMail($this->user->getId());
105 $this->mbox = new ilMailbox($this->user->getId());
106 $this->purifier = $body_purifier ?? new ilMailBodyPurifier();
107 $this->ui_factory = $DIC->ui()->factory();
108 $this->request = $DIC->http()->request();
109 $this->ui_renderer = $DIC->ui()->renderer();
110 $this->post = new ArrayBasedRequestWrapper($this->request->getParsedBody());
111 $this->query = new ArrayBasedRequestWrapper($this->request->getQueryParams());
112 $this->upload_handler = new ilMailFormUploadHandlerGUI();
113 $this->storage = $DIC->resourceStorage();
114 $this->fdm = new ilFileDataMail($this->user->getId());
115 $this->settings = $DIC->settings();
117 $user_api = $DIC['user'];
118 $this->user_search = $user_api->getSearch();
119 $this->clock = (new DataFactory())->clock();
120
121 $mail_obj_id = $this->getBodyParam(
122 'mobj_id',
123 $this->refinery->kindlyTo()->int(),
124 $this->getQueryParam(
125 'mobj_id',
126 $this->refinery->kindlyTo()->int(),
127 0
128 )
129 );
130
131 if ($mail_obj_id === 0) {
132 $mail_obj_id = $this->mbox->getInboxFolder();
133 }
134
135 $this->ctrl->setParameter($this, 'mobj_id', $mail_obj_id);
136 }
137
138 private function getQueryParam(string $name, Transformation $trafo, $default = null)
139 {
140 if ($this->http->wrapper()->query()->has($name)) {
141 return $this->http->wrapper()->query()->retrieve(
142 $name,
143 $trafo
144 );
145 }
146
147 return $default;
148 }
149
150 private function getBodyParam(string $name, Transformation $trafo, $default = null)
151 {
152 if ($this->http->wrapper()->post()->has($name)) {
153 return $this->http->wrapper()->post()->retrieve(
154 $name,
155 $trafo
156 );
157 }
158
159 return $default;
160 }
161
162 public function executeCommand(): void
163 {
164 $forward_class = $this->ctrl->getNextClass($this) ?? '';
165 switch (strtolower($forward_class)) {
166 case strtolower(ILIAS\User\Search\EndpointGUI::class):
167 $gui = $this->user_search->getEndpointGUI(
169 );
170 $this->ctrl->forwardCommand($gui);
171 break;
172
173 case strtolower(ilMailAttachmentGUI::class):
174 $this->ctrl->setReturn($this, 'returnFromAttachments');
175 $gui = new ilMailAttachmentGUI();
176 $gui->consume();
177 $this->ctrl->forwardCommand($gui);
178 break;
179
180 case strtolower(ilMailSearchGUI::class):
181 $this->ctrl->setReturn($this, 'searchResults');
182 $this->ctrl->forwardCommand(new ilMailSearchGUI());
183 break;
184
185 case strtolower(ilMailSearchCoursesGUI::class):
186 $this->ctrl->setReturn($this, 'searchResults');
187 $this->ctrl->forwardCommand(new ilMailSearchCoursesGUI());
188 break;
189
190 case strtolower(ilMailingListsGUI::class):
191 $this->ctrl->setReturn($this, 'searchResults');
192 $this->ctrl->forwardCommand(new ilMailingListsGUI());
193 break;
194
195 case strtolower(ilMailSearchGroupsGUI::class):
196 $this->ctrl->setReturn($this, 'searchResults');
197 $this->ctrl->forwardCommand(new ilMailSearchGroupsGUI());
198 break;
199
200 case strtolower(ilMailFormUploadHandlerGUI::class):
201 $this->ctrl->forwardCommand($this->upload_handler);
202 break;
203
204 default:
205 if (!($cmd = $this->ctrl->getCmd())) {
206 $cmd = 'showForm';
207 }
208
209 $this->$cmd();
210 break;
211 }
212 }
213
218 protected function decodeAttachmentFiles(array $files): array
219 {
220 $decoded_files = [];
221 foreach ($files as $value) {
222 if (is_file($this->mfile->getMailPath() . '/' . $this->user->getId() . '_' . urldecode($value))) {
223 $decoded_files[] = urldecode($value);
224 }
225 }
226
227 return $decoded_files;
228 }
229
230 public function saveMessageToOutbox(array $form_values, Form $form): void
231 {
232 $files = [];
233 if (count($form_values['attachments']) > 0) {
234 $files = $this->handleAttachments($form_values['attachments']);
235 }
236
237 $rcp_to = '';
238 $rcp_cc = '';
239 $rcp_bcc = '';
240 if ($form_values['rcp_to'] !== []) {
241 $rcp_to = $form_values['rcp_to'][0];
242 }
243 if ($form_values['rcp_cc'] !== []) {
244 $rcp_cc = $form_values['rcp_cc'][0];
245 }
246 if ($form_values['rcp_bcc'] !== []) {
247 $rcp_bcc = $form_values['rcp_bcc'][0];
248 }
249
250 $errors = $this->umail->validateRecipients(
251 $rcp_to,
252 $rcp_cc,
253 $rcp_bcc,
254 );
255 if ($errors) {
256 $this->showSubmissionErrors($errors);
257 $this->showForm();
258 $this->http->close();
259 }
260
261 $message = ilUtil::securePlainString($this->getBodyParam('m_message', $this->refinery->kindlyTo()->string(), ''));
262 $mail_body = new ilMailBody($message, $this->purifier);
263 $sanitized_message = $mail_body->getContent();
264
265 $outbox_folder_id = $this->mbox->getOutboxFolder();
266 if (ilSession::get('outbox')) {
267 $outbox_id = (int) ilSession::get('outbox');
268 ilSession::clear('outbox');
269 }
270
271 $this->umail->scheduledMail(
272 $outbox_folder_id,
273 $this->user->getId(),
276 $rcp_to,
277 $rcp_cc,
278 $rcp_bcc,
279 ilUtil::securePlainString($form_values['m_subject'] ?? $this->lng->txt('mail_no_subject')),
280 $sanitized_message,
281 $files,
282 $form_values['use_placeholders'],
283 $outbox_id ?? null
284 ),
285 $form_values['use_schedule']['m_schedule']
286 ),
289 );
290
291 if (ilSession::get('draft')) {
292 $draft_id = (int) ilSession::get('draft');
293 ilSession::clear('draft');
294 $this->umail->deleteMails([$draft_id]);
295 }
296
297 $this->ctrl->setParameterByClass(ilMailFolderGUI::class, 'mobj_id', $outbox_folder_id);
298 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_scheduled'), true);
299
302 } else {
303 $this->ctrl->redirectByClass([ilMailGUI::class, ilMailFolderGUI::class]);
304 }
305
306 $this->showForm();
307 }
308
309 public function sendMessage(): void
310 {
311 $form = $this->buildForm()->withRequest($this->request);
312 $result = $form->getInputGroup()->getContent();
313
314 if (!$result->isOK()) {
315 $this->showForm($form);
316 return;
317 }
318
319 $value = $result->value()[0];
320
321 $schedule_date = $value['use_schedule']['m_schedule'] ?? null;
322 if ($schedule_date instanceof DateTimeImmutable &&
323 $schedule_date > $this->clock->local(new DateTimeZone($this->user->getTimeZone()))->now()) {
324 $this->saveMessageToOutbox($value, $form);
325 return;
326 }
327
328 $files = [];
329 if (count($value['attachments']) > 0) {
330 $files = $this->handleAttachments($value['attachments']);
331 }
332
333 $mailer = $this->umail
334 ->withContextId(ilMailFormCall::getContextId() ?: '')
335 ->withContextParameters(ilMailFormCall::getContextParameters());
336
337 $mailer->setSaveInSentbox(true);
338
339 $mailer->autoresponder()->enableAutoresponder();
340
341 $rcp_to = '';
342 $rcp_cc = '';
343 $rcp_bcc = '';
344 if (!empty($value['rcp_to'])) {
345 $rcp_to = implode(',', $value['rcp_to']);
346 }
347 if (!empty($value['rcp_cc'])) {
348 $rcp_cc = implode(',', $value['rcp_cc']);
349 }
350 if (!empty($value['rcp_bcc'])) {
351 $rcp_bcc = implode(',', $value['rcp_bcc']);
352 }
353
354 if ($errors = $mailer->enqueue(
355 $rcp_to,
356 $rcp_cc,
357 $rcp_bcc,
358 ilUtil::securePlainString($value['m_subject']),
359 (new ilMailBody($value['m_message'], $this->purifier))->getContent(),
360 $files,
361 $value['use_placeholders']
362 )) {
363 $mailer->autoresponder()->disableAutoresponder();
364
365 $this->showSubmissionErrors($errors);
366 $this->showForm($form);
367
368 $this->http->close();
369 } else {
370 $mailer->autoresponder()->disableAutoresponder();
371
372 $mailer->persistToStage(
373 $this->user->getId(),
374 '',
375 '',
376 '',
377 '',
378 '',
379 null
380 );
381
382 $mail_id = null;
383 if (ilSession::get('outbox')) {
384 $mail_id = (int) ilSession::get('outbox');
385 ilSession::clear('outbox');
386 } elseif (ilSession::get('draft')) {
387 $mail_id = (int) ilSession::get('draft');
388 ilSession::clear('draft');
389 }
390
391 if ($mail_id) {
392 $mailer->deleteMails([$mail_id]);
393 }
394
395 $this->ctrl->setParameterByClass(ilMailGUI::class, 'type', 'message_sent');
396
398 $this->tpl->setOnScreenMessage('success', $this->lng->txt('mail_message_send'), true);
399 $this->ctrl->redirectToURL(ilMailFormCall::getRefererRedirectUrl());
400 } else {
401 $this->ctrl->redirectByClass(ilMailGUI::class);
402 }
403 }
404 $mailer->autoresponder()->disableAutoresponder();
405
406 $this->showForm();
407 }
408
409 public function saveDraft(): void
410 {
411 $form = $this->buildForm()->withRequest($this->request);
412 $result = $form->getInputGroup()->getContent();
413
414 if (!$result->isOK()) {
415 $this->showForm($form);
416 return;
417 }
418
419 $value = $result->value()[0];
420
421 if ($value['m_subject'] === '') {
422 $value['m_subject'] = $this->lng->txt('mail_no_subject');
423 }
424 $files = [];
425 if (count($value['attachments']) > 0) {
426 $files = $this->handleAttachments($value['attachments']);
427 }
428
429 $draft_folder_id = $this->mbox->getDraftsFolder();
430
431 $rcp_to = !empty($value['rcp_to']) ? implode(',', $value['rcp_to']) : '';
432 $rcp_cc = !empty($value['rcp_cc']) ? implode(',', $value['rcp_cc']) : '';
433 $rcp_bcc = !empty($value['rcp_bcc']) ? implode(',', $value['rcp_bcc']) : '';
434
435 if ($errors = $this->umail->validateRecipients($rcp_to, $rcp_cc, $rcp_bcc)) {
436 $this->request_attachments = $files;
437 $this->showSubmissionErrors($errors);
438 $this->showForm($form);
439 return;
440 }
441
442 if (ilSession::get('draft')) {
443 $draft_id = (int) ilSession::get('draft');
444 ilSession::clear('draft');
445 } else {
446 $draft_id = $this->umail->getNewDraftId($draft_folder_id);
447 }
448
449 $this->umail->updateDraft(
450 $draft_folder_id,
451 $files,
452 $rcp_to,
453 $rcp_cc,
454 $rcp_bcc,
455 ilUtil::securePlainString($value['m_subject']),
456 $value['m_message'],
457 $draft_id,
458 $value['use_schedule']['m_schedule'] ?? null,
459 $value['use_placeholders'],
462 );
463
464 if (ilSession::get('outbox')) {
465 $outbox_id = (int) ilSession::get('outbox');
466 ilSession::clear('outbox');
467 $this->umail->deleteMails([$outbox_id]);
468 }
469
470 $this->ctrl->setParameterByClass(ilMailFolderGUI::class, 'mobj_id', $draft_folder_id);
471 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_saved'), true);
472
475 } else {
476 $this->ctrl->redirectByClass([ilMailGUI::class, ilMailFolderGUI::class]);
477 }
478
479 $this->showForm();
480 }
481
482 public function searchUsers(bool $save = true): void
483 {
484 $this->tpl->setTitle($this->lng->txt('mail_new'));
485
486 if ($save) {
487 $this->saveMailBeforeSearch();
488 }
489
490 $form = new ilPropertyFormGUI();
491 $form->setId('search_rcp');
492 $form->setTitle($this->lng->txt('search_recipients'));
493 $form->setFormAction($this->ctrl->getFormAction($this, 'search'));
494
495 $inp = new ilTextInputGUI($this->lng->txt('search_for'), 'search');
496 $inp->setSize(30);
497 $data_source_url = $this->ctrl->getLinkTarget($this, 'lookupRecipientAsync', '', true);
498 $inp->setDataSource($data_source_url);
499
500 $search_query = trim((string) ilSession::get('mail_search_search'));
501 if ($search_query !== '') {
502 $inp->setValue(ilLegacyFormElementsUtil::prepareFormOutput($search_query, true));
503 }
504 $form->addItem($inp);
505
506 $form->addCommandButton('search', $this->lng->txt('search'));
507 $form->addCommandButton('cancelSearch', $this->lng->txt('cancel'));
508
509 $this->tpl->setContent($form->getHTML());
510 $this->tpl->printToStdout();
511 }
512
513 public function searchCoursesTo(): void
514 {
515 $this->saveMailBeforeSearch();
516
517 if (ilSession::get('search_crs')) {
518 $this->ctrl->setParameterByClass('ilmailsearchcoursesgui', 'cmd', 'showMembers');
519 }
520
521 $this->ctrl->setParameterByClass(ilMailSearchCoursesGUI::class, 'ref', 'mail');
522 $this->ctrl->redirectByClass(ilMailSearchCoursesGUI::class);
523 }
524
525 public function searchGroupsTo(): void
526 {
527 $this->saveMailBeforeSearch();
528
529 $this->ctrl->setParameterByClass(ilMailSearchGroupsGUI::class, 'ref', 'mail');
530 $this->ctrl->redirectByClass(ilMailSearchGroupsGUI::class);
531 }
532
533 public function search(): void
534 {
536 'mail_search_search',
537 ilUtil::securePlainString($this->getBodyParam('search', $this->refinery->kindlyTo()->string(), ''))
538 );
539
540 if (trim(ilSession::get('mail_search_search') ?? '') === '') {
541 $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_insert_query'));
542 $this->searchUsers(false);
543 } elseif (strlen(trim(ilSession::get('mail_search_search') ?? '')) < 3) {
544 $this->lng->loadLanguageModule('search');
545 $this->tpl->setOnScreenMessage('info', $this->lng->txt('search_minimum_three'));
546 $this->searchUsers(false);
547 } else {
548 $this->ctrl->setParameterByClass(
549 ilMailSearchGUI::class,
550 'search',
551 urlencode(ilSession::get('mail_search_search') ?? '')
552 );
553 $this->ctrl->redirectByClass(ilMailSearchGUI::class);
554 }
555 }
556
557 public function cancelSearch(): void
558 {
559 ilSession::clear('mail_search');
560 $this->searchResults();
561 }
562
563 public function editAttachments(): void
564 {
565 $this->saveMailBeforeSearch();
566
567 $this->ctrl->setParameterByClass(ilMailAttachmentGUI::class, 'ref', 'mail');
568 $this->ctrl->redirectByClass(ilMailAttachmentGUI::class);
569 }
570
571 public function returnFromAttachments(): void
572 {
573 $this->mail_form_type = self::MAIL_FORM_TYPE_ATTACH;
574 $this->showForm();
575 }
576
577 public function searchResults(): void
578 {
579 $this->mail_form_type = self::MAIL_FORM_TYPE_SEARCH_RESULT;
580 $this->showForm();
581 }
582
583 public function mailUser(): void
584 {
585 $this->mail_form_type = self::MAIL_FORM_TYPE_NEW;
586 $this->showForm();
587 }
588
589 public function mailRole(): void
590 {
591 $this->mail_form_type = self::MAIL_FORM_TYPE_ROLE;
592 $this->showForm();
593 }
594
595 public function replyMail(): void
596 {
597 $this->mail_form_type = self::MAIL_FORM_TYPE_REPLY;
598 $this->showForm();
599 }
600
601 public function mailAttachment(): void
602 {
603 $this->mail_form_type = self::MAIL_FORM_TYPE_ATTACH;
604 $this->showForm();
605 }
606
607 protected function getTemplateDataById(): void
608 {
609 if (!$this->http->wrapper()->query()->has('template_id')) {
610 $this->http->close();
611 }
612
613 try {
614 $template = $this->template_service->loadTemplateForId(
615 $this->http->wrapper()->query()->retrieve('template_id', $this->refinery->kindlyTo()->int())
616 );
618
619 $this->http->saveResponse(
620 $this->http->response()
621 ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
622 ->withBody(Streams::ofString(json_encode([
623 'm_subject' => $template->getSubject(),
624 'm_message' => $this->umail->appendSignature($template->getMessage()),
625 ], JSON_THROW_ON_ERROR)))
626 );
627 } catch (Exception) {
628 }
629
630 $this->http->sendResponse();
631 $this->http->close();
632 }
633
634 public function showForm(?Form $form = null): void
635 {
636 $this->tpl->addBlockFile(
637 'ADM_CONTENT',
638 'adm_content',
639 'tpl.mail_new.html',
640 'components/ILIAS/Mail'
641 );
642 $this->tpl->setTitle($this->lng->txt('mail_new'));
643
644 $this->lng->loadLanguageModule('crs');
645
647 $this->tabs->setBackTarget(
648 $this->lng->txt('back'),
649 $this->ctrl->getLinkTarget($this, 'cancelMail')
650 );
651 }
652
653 $mail_data = [];
654 $mail_data['rcp_to'] = '';
655 $mail_data['rcp_cc'] = '';
656 $mail_data['rcp_bcc'] = '';
657 $mail_data['attachments'] = [];
658 $mail_data['m_subject'] = '';
659 $mail_data['m_message'] = '';
660
661 $mail_id = $this->getQueryParam('mail_id', $this->refinery->kindlyTo()->int(), 0);
662 $type = $this->getQueryParam('type', $this->refinery->kindlyTo()->string(), '');
663 if ($this->mail_form_type !== '') {
664 $type = $this->mail_form_type;
665 }
666
667 switch ($type) {
669 $mail_data = $this->umail->getMail($mail_id);
670
671 $mail_data['m_subject'] = $this->umail->formatReplySubject($mail_data['m_subject'] ?? '');
672 $mail_data['m_message'] = $this->umail->prependSignature(
673 $this->umail->formatReplyMessage($mail_data['m_message'] ?? '')
674 );
675 $mail_data['attachments'] = [];
676 $mail_data['rcp_cc'] = '';
677 $mail_data['rcp_to'] = $this->umail->formatReplyRecipient();
678 break;
679
681 $mail_data = $this->umail->retrieveFromStage();
682 if (ilSession::get('mail_search_results_to')) {
683 $mail_data = $this->umail->appendSearchResult(
684 $this->refinery->kindlyTo()->listOf(
685 $this->refinery->kindlyTo()->string()
686 )->transform(ilSession::get('mail_search_results_to')),
687 'to'
688 );
689 }
690 if (ilSession::get('mail_search_results_cc')) {
691 $mail_data = $this->umail->appendSearchResult(
692 $this->refinery->kindlyTo()->listOf(
693 $this->refinery->kindlyTo()->string()
694 )->transform(ilSession::get('mail_search_results_cc')),
695 'cc'
696 );
697 }
698 if (ilSession::get('mail_search_results_bcc')) {
699 $mail_data = $this->umail->appendSearchResult(
700 $this->refinery->kindlyTo()->listOf(
701 $this->refinery->kindlyTo()->string()
702 )->transform(ilSession::get('mail_search_results_bcc')),
703 'bc'
704 );
705 }
706
707 ilSession::clear('mail_search_results_to');
708 ilSession::clear('mail_search_results_cc');
709 ilSession::clear('mail_search_results_bcc');
710 break;
711
713 ilSession::set('draft', $mail_id);
714 $mail_data = $this->umail->getMail($mail_id);
715
716 if (!is_null($mail_data['attachments']) || !empty($mail_data['attachments'])) {
717 $mail_data['attachments'] = $this->filesFromLegacyToIRSS($mail_data);
718 }
719
720 ilMailFormCall::setContextId($mail_data['tpl_ctx_id']);
721 ilMailFormCall::setContextParameters($mail_data['tpl_ctx_params']);
722 break;
723
725 ilSession::set('outbox', $mail_id);
726 $mail_data = $this->umail->getMail($mail_id);
727 ilMailFormCall::setContextId($mail_data['tpl_ctx_id']);
728 ilMailFormCall::setContextParameters($mail_data['tpl_ctx_params']);
729 break;
730
732 $mail_data = $this->umail->getMail($mail_id);
733 $mail_data['rcp_to'] = $mail_data['rcp_cc'] = $mail_data['rcp_bcc'] = '';
734 $mail_data['m_subject'] = $this->umail->formatForwardSubject($mail_data['m_subject'] ?? '');
735 $mail_data['m_message'] = $this->umail->prependSignature($mail_data['m_message'] ?? '');
736 if (is_array($mail_data['attachments']) && count($mail_data['attachments']) && $error = $this->mfile->adoptAttachments(
737 $mail_data['attachments'],
738 $mail_id
739 )) {
740 $this->tpl->setOnScreenMessage('info', $error);
741 }
742
743 if (!is_null($mail_data['attachments']) || ($mail_data['attachments'] != '')) {
744 $mail_data['attachments'] = $this->filesFromLegacyToIRSS($mail_data);
745 }
746 break;
747
749 ilSession::clear('draft');
750 ilSession::clear('outbox');
751 // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
752 $to = ilUtil::securePlainString($this->getQueryParam('rcp_to', $this->refinery->kindlyTo()->string(), ''));
753 if ($to === '' && ilSession::get('rcp_to')) {
754 $to = ilSession::get('rcp_to');
755 }
756 $mail_data['rcp_to'] = $to;
757
758 $cc = ilUtil::securePlainString($this->getQueryParam('rcp_cc', $this->refinery->kindlyTo()->string(), ''));
759 if ($cc === '' && ilSession::get('rcp_cc')) {
760 $cc = ilSession::get('rcp_cc');
761 }
762 $mail_data['rcp_cc'] = $cc;
763
764 $bcc = ilUtil::securePlainString($this->getQueryParam('rcp_bcc', $this->refinery->kindlyTo()->string(), ''));
765 if ($bcc === '' && ilSession::get('rcp_bcc')) {
766 $bcc = ilSession::get('rcp_bcc');
767 }
768 $mail_data['rcp_bcc'] = $bcc;
769
770 $mail_data['m_message'] = '';
771 if (($sig = ilMailFormCall::getSignature()) !== '') {
772 $mail_data['m_message'] = $sig;
773 $mail_data['m_message'] .= chr(13)
774 . chr(10)
775 . chr(13)
776 . chr(10);
777 }
778 $mail_data['m_message'] .= $this->umail->appendSignature('');
779
780 ilSession::set('rcp_to', '');
781 ilSession::set('rcp_cc', '');
782 ilSession::set('rcp_bcc', '');
783 break;
784
786 $roles = [];
787 if ($this->http->wrapper()->post()->has('roles')) {
788 $roles = $this->http->wrapper()->post()->retrieve(
789 'roles',
790 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
791 );
792 } elseif (is_array(ilSession::get('mail_roles'))) {
793 $roles = $this->refinery->kindlyTo()->listOf(
794 $this->refinery->kindlyTo()->string()
795 )->transform(ilSession::get('mail_roles'));
796 }
797
798 // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
799 $mail_data['rcp_to'] = ilUtil::securePlainString(
800 implode(',', $roles)
801 );
802
803 $mail_data['m_message'] = '';
804 if (($sig = ilMailFormCall::getSignature()) !== '') {
805 $mail_data['m_message'] = $sig;
806 $mail_data['m_message'] .= chr(13)
807 . chr(10)
808 . chr(13)
809 . chr(10);
810 }
811
812 $additional_msg_text = '';
813 if ($this->http->wrapper()->post()->has('additional_message_text')) {
814 $additional_msg_text = ilUtil::securePlainString($this->http->wrapper()->post()->retrieve(
815 'additional_message_text',
816 $this->refinery->kindlyTo()->string()
817 ));
818 }
819
820 $mail_data['m_message'] .= $additional_msg_text
821 . chr(13)
822 . chr(10)
823 . $this->umail->appendSignature('');
824 ilSession::set('mail_roles', []);
825 break;
826
828 $rcp = '';
829 if ($this->http->wrapper()->query()->has('rcp')) {
830 $rcp = $this->http->wrapper()->query()->retrieve('rcp', $this->refinery->kindlyTo()->string());
831 }
832 $mail_data['rcp_to'] = urldecode((string) $rcp);
833 break;
835 $mail_data = $this->umail->retrieveFromStage();
836 break;
837 default:
838 $mail_data = $this->http->request()->getParsedBody();
839 foreach ($mail_data as $key => $value) {
840 if (is_string($value)) {
841 // Note: For security reasons, ILIAS only allows Plain text strings in E-Mails.
842 $mail_data[$key] = ilUtil::securePlainString($value);
843 }
844 }
845
846 if ($this->request_attachments) {
847 $mail_data['attachments'] = $this->request_attachments;
848 }
849 break;
850 }
851
852 $this->tpl->parseCurrentBlock();
853
854 $form ??= $this->buildForm($mail_data);
855 $this->addToolbarButtons($form);
856
857 $this->tpl->setVariable('FORM', $this->ui_renderer->render($form));
858 $this->tpl->addJavaScript('assets/js/ilMailComposeFunctions.js');
859 $this->tpl->printToStdout();
860 }
861
862 public function lookupRecipientAsync(): void
863 {
864 $search = trim((string) $this->getBodyParam(
865 'term',
866 $this->refinery->kindlyTo()->string(),
867 $this->getQueryParam(
868 'term',
869 $this->refinery->kindlyTo()->string(),
870 ''
871 )
872 ));
873
874 $result = [];
875
876 if (ilStr::strLen($search) < 3) {
877 $this->http->saveResponse(
878 $this->http->response()
879 ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
880 ->withBody(Streams::ofString(json_encode($result, JSON_THROW_ON_ERROR)))
881 );
882
883 $this->http->sendResponse();
884 $this->http->close();
885 }
886
887 // #14768
888 $quoted = ilUtil::stripSlashes($search);
889 $quoted = str_replace(['%', '_'], ['\%', '\_'], $quoted);
890
891 $form = new ilMailForm();
892 $result = $form->getRecipientAsync('%' . $quoted . '%', ilUtil::stripSlashes($search));
893
894 $this->http->saveResponse(
895 $this->http->response()
896 ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
897 ->withBody(Streams::ofString(json_encode($result, JSON_THROW_ON_ERROR)))
898 );
899 $this->http->sendResponse();
900 $this->http->close();
901 }
902
903 public function cancelMail(): void
904 {
907 }
908
909 $this->showForm();
910 }
911
915 private function saveMailBeforeSearch(?array $input_results = null): void
916 {
917 if (empty($input_results)) {
918 $form = $this->buildForm()->withRequest($this->request);
919 $result = $form->getInputGroup()->getInputs()[0]->getInputs();
920 } else {
921 $result = $input_results;
922 }
923
924 $resource_collection_id = null;
925 if (!empty($result['attachments']->getValue())) {
926 $files = $this->handleAttachments($result['attachments']->getValue());
927 $resource_collection_id = $this->getIdforCollection($files);
928 }
929
930 $rcp_to = implode(',', $result['rcp_to']->getValue() ?? []);
931 $rcp_cc = implode(',', $result['rcp_cc']->getValue() ?? []);
932 $rcp_bcc = implode(',', $result['rcp_bcc']->getValue() ?? []);
933
934 $this->umail->persistToStage(
935 $this->user->getId(),
936 $rcp_to,
937 $rcp_cc,
938 $rcp_bcc,
939 ilUtil::securePlainString($result['m_subject']->getValue()),
940 ilUtil::securePlainString($result['m_message']->getValue()),
941 $resource_collection_id,
942 (bool) $result['use_placeholders']->getValue(),
945 );
946 }
947
948 public function searchMailingListsTo(): void
949 {
950 $this->saveMailBeforeSearch();
951
952 $this->ctrl->setParameterByClass(ilMailingListsGUI::class, 'ref', 'mail');
953 $this->ctrl->redirectByClass(ilMailingListsGUI::class);
954 }
955
959 protected function showSubmissionErrors(array $errors): void
960 {
961 $formatter = new ilMailErrorFormatter($this->lng);
962 $formatted_errors = $formatter->format($errors);
963
964 if ($formatted_errors !== '') {
965 $this->tpl->setOnScreenMessage('failure', $formatted_errors);
966 }
967 }
968
969 protected function buildForm(?array $mail_data = null): Form
970 {
971 return $this->ui_factory->input()->container()->form()->standard(
972 $this->ctrl->getFormAction($this, 'sendMessage'),
973 $this->buildFormElements($mail_data)
975 $this->ctrl->getFormAction($this, 'saveDraft'),
976 $this->lng->txt('save_message')
977 )->withSubmitLabel($this->lng->txt('send_mail'));
978 }
979
980 private function getUserSearchConfigurator(): \ILIAS\User\Search\EndpointConfigurator
981 {
983 }
984
985 protected function buildFormElements(?array $mail_data): array
986 {
987 $ff = $this->ui_factory->input()->field();
988
989 $rcp_to = $this->user_search->getInput(
990 $this->lng->txt('mail_to'),
991 $this->getUserSearchConfigurator()
992 )->withRequired(true, $this->refinery->logical()->sequential([
993 $this->refinery->logical()->not($this->refinery->null()),
994 $this->refinery->string()->hasMinLength(1)
995 ])->withProblemBuilder(function ($txt) {
996 return $txt('mail_add_recipient');
997 }));
998 $rcp_cc = $this->user_search->getInput(
999 $this->lng->txt('mail_cc'),
1001 );
1002 $rcp_bcc = $this->user_search->getInput(
1003 $this->lng->txt('mail_bcc'),
1005 );
1006
1007 if (!is_null($mail_data)) {
1008 if (isset($mail_data['rcp_to']) && $mail_data['rcp_to'] != '') {
1009 $rcp_to = $rcp_to->withValue(explode(',', $mail_data['rcp_to']) ?? (array) $mail_data['rcp_to']);
1010 }
1011 if (isset($mail_data['rcp_cc']) && $mail_data['rcp_cc'] != '') {
1012 $rcp_cc = $rcp_cc->withValue(explode(',', $mail_data['rcp_cc']) ?? (array) $mail_data['rcp_cc']);
1013 }
1014 if (isset($mail_data['rcp_bcc']) && $mail_data['rcp_bcc'] != '') {
1015 $rcp_bcc = $rcp_bcc->withValue(explode(',', $mail_data['rcp_bcc']) ?? (array) $mail_data['rcp_bcc']);
1016 }
1017 }
1018
1019 $has_files = !empty($mail_data['attachments']);
1020 $attachments = $ff->file(
1021 $this->upload_handler,
1022 $this->lng->txt('attachments')
1023 )->withMaxFiles(10);
1024
1025 if (isset($mail_data['attachments']) && $has_files) {
1026 if ($mail_data['attachments'] instanceof \ILIAS\ResourceStorage\Identification\ResourceCollectionIdentification) {
1027 $mail_data['attachments'] = $this->FilesFromIRSSToLegacy($mail_data['attachments']);
1028 }
1029 $attachments = $attachments->withValue($mail_data['attachments'] ?? []);
1030 }
1031
1032 $template_chb = null;
1033 $signal = null;
1034 $use_placeholder_value = false;
1035 $context = new ilMailTemplateGenericContext();
1037 $context_id = ilMailFormCall::getContextId();
1038
1039 try {
1041 $use_placeholder_value = true;
1042
1043 $templates = $this->template_service->loadTemplatesForContextId($context->getId());
1044 if (!empty($templates)) {
1045 $options = [];
1046
1047 $tmpl_value = '';
1048 $signal_generator = new ILIAS\UI\Implementation\Component\SignalGenerator();
1049 $signal = $signal_generator->create();
1050 foreach ($templates as $template) {
1051 $options[$template->getTplId()] = $template->getTitle();
1052 $signal->addOption($template->getTplId() . '_subject', urlencode($template->getSubject()));
1053 $signal->addOption($template->getTplId() . '_message', urlencode($template->getMessage()));
1054
1055 if (!isset($mail_data['template_id']) && $template->isDefault()) {
1056 $tmpl_value = $template->getTplId();
1057 $mail_data['m_subject'] = $template->getSubject();
1058 $mail_data['m_message'] = $this->umail->appendSignature($template->getMessage());
1059 }
1060 }
1061 if (isset($mail_data['template_id'])) {
1062 $tmpl_value = (int) $mail_data['template_id'];
1063 }
1064 asort($options);
1065
1066 $template_chb = $ff
1067 ->select(
1068 $this->lng->txt('mail_template_client'),
1069 $options,
1070 $this->lng->txt('mail_template_client_info')
1071 )
1072 ->withValue($tmpl_value)
1073 ->withOnUpdate($signal);
1074 }
1075 } catch (Exception) {
1076 ilLoggerFactory::getLogger('mail')->error(sprintf(
1077 '%s has been called with invalid context id: %s.',
1078 __METHOD__,
1079 $context_id
1080 ));
1081 }
1082 } else {
1083 $use_placeholder_value = $mail_data['use_placeholders'] ?? false;
1084 }
1085
1086 $m_subject = $ff
1087 ->text($this->lng->txt('subject'))
1088 ->withRequired(
1089 true,
1090 $this->refinery->logical()->sequential([
1091 $this->refinery->logical()->not($this->refinery->null()),
1092 $this->refinery->string()->hasMinLength(1)
1093 ])->withProblemBuilder(function ($txt) {
1094 return $txt('mail_add_subject');
1095 })
1096 )
1097 ->withMaxLength(200)
1098 ->withValue($mail_data['m_subject'] ?? '');
1099
1100 $m_message = $ff->markdown(
1102 $this->lng->txt('message_content')
1103 )->withValue($mail_data['m_message'] ?? '');
1104
1105 $use_placeholders = $ff->hidden()->withValue($use_placeholder_value ? '1' : '0');
1106
1107 $placeholders = [];
1109 if ($mode === self::MAIL_FORM_MODE_SERIAL_LETTER && $context) {
1110 foreach ($context->getPlaceholders() as $value) {
1111 $placeholders[$value['placeholder']] = $value['label'];
1112 }
1113 if (!empty($placeholders)) {
1114 $m_message = $m_message
1115 ->withMustacheVariables(
1116 $placeholders,
1117 $this->lng->txt('mail_nacc_use_placeholder') . '<br />'
1118 . sprintf($this->lng->txt('placeholders_advise'), '<br />')
1119 )
1120 ;
1121 }
1122 }
1123
1124 $use_placeholders = $use_placeholders->withAdditionalTransformation(
1125 $this->refinery->kindlyTo()->bool()
1126 );
1127
1128 if ($signal !== null) {
1129 $m_subject = $m_subject->withAdditionalOnLoadCode(
1130 function ($id) use ($signal) {
1131 return "
1132 $(document).on('{$signal}', function (event, signalData) {
1133 let subject = document.getElementById('{$id}');
1134 let child = subject.querySelector('.c-input__field input');
1135 let triggerer = signalData.triggerer[0];
1136 let tplId = triggerer.querySelector('select').value;
1137 if (tplId != '') {
1138 child.value = decodeURIComponent(signalData.options[tplId + '_subject'].replace(/\+/g, ' '));
1139 }
1140 });
1141 ";
1142 }
1143 );
1144 $m_message = $m_message->withAdditionalOnLoadCode(
1145 function ($id) use ($signal) {
1146 return "
1147 $(document).on('{$signal}', function (event, signalData) {
1148 let message = document.getElementById('{$id}');
1149 let child = message.querySelector('.c-input__field textarea');
1150 let triggerer = signalData.triggerer[0];
1151 let tplId = triggerer.querySelector('select').value;
1152 if (tplId != '') {
1153 child.value = decodeURIComponent(signalData.options[tplId + '_message'].replace(/\+/g, ' '));
1154 }
1155 });
1156 ";
1157 }
1158 );
1159 }
1160
1161 $elements = [
1162 'rcp_to' => $rcp_to,
1163 'rcp_cc' => $rcp_cc,
1164 'rcp_bcc' => $rcp_bcc,
1165 'm_subject' => $m_subject,
1166 'attachments' => $attachments
1167 ];
1168 if ($template_chb !== null) {
1169 $elements[] = $template_chb;
1170 }
1171 $elements['m_message'] = $m_message;
1172
1173 $schedule_date_time_value = null;
1174 $current_time = $this->clock->local(new DateTimeZone($this->user->getTimeZone()))->now();
1175 $schedule_date_time_input = $ff
1176 ->dateTime($this->lng->txt('mail_schedule_scheduled_datetime'))
1177 ->withUseTime(true)
1178 ->withTimezone($this->user->getTimezone())
1180 $this->refinery->custom()->constraint(
1181 function (DateTimeImmutable $v) use ($current_time) {
1182 return $v > $current_time;
1183 },
1184 $this->lng->txt('mail_schedule_error_past_datetime')
1185 )
1186 );
1187
1188 if (isset($mail_data['schedule_datetime'])) {
1189 $schedule_time = new DateTimeImmutable(
1190 (string) $mail_data['schedule_datetime'],
1191 new DateTimeZone($mail_data['schedule_timezone'] ?? '')
1192 );
1193 $schedule_time->setTimezone(new DateTimeZone($this->user->getTimeZone()));
1194 $schedule_date_time_value = $schedule_time > $current_time ? $schedule_time : null;
1195 }
1196
1197 $use_schedule_input = $ff->optionalGroup(
1198 ['m_schedule' => $schedule_date_time_input],
1199 $this->lng->txt('mail_message_scheduled')
1200 )->withAdditionalTransformation(
1201 $this->refinery->custom()->constraint(
1202 function (?array $v) {
1203 return $v === null || (isset($v['m_schedule']) && $v['m_schedule'] instanceof DateTimeImmutable);
1204 },
1205 $this->lng->txt('mail_schedule_error_no_datetime')
1206 )
1207 );
1208 if ($schedule_date_time_value !== null) {
1209 $use_schedule_input = $use_schedule_input->withValue(['m_schedule' => $schedule_date_time_value]);
1210 } else {
1211 $use_schedule_input = $use_schedule_input->withValue(null);
1212 }
1213
1214 $elements['use_schedule'] = $use_schedule_input;
1215 $elements['use_placeholders'] = $use_placeholders;
1216
1217 $section = $ff->section(
1218 $elements,
1219 $this->lng->txt('compose')
1220 );
1221
1222 return [
1223 $section
1224 ];
1225 }
1226
1227 protected function addToolbarButtons(Form $form): void
1228 {
1229 $bf = $this->ui_factory->button();
1230
1231 $result = $form->getInputGroup()->getInputs()[0]->getInputs();
1232 $use_placeholders = (bool) $result['use_placeholders']->getValue();
1233 $action = $this->ctrl->getFormAction($this, 'toggleMailMode');
1234 $url_builder = new UrlBuilder(new URI(ILIAS_HTTP_PATH . '/' . $action));
1235 [$url_builder, $mail_mode_parameter] = $url_builder->acquireParameter(['mail', 'form'], 'mail_mode');
1236
1237 $btn = $this->ui_factory->viewControl()->mode(
1238 [
1239 $this->lng->txt(self::MAIL_FORM_MODE_REGULAR_MAIL) => (string) $url_builder->withParameter(
1240 $mail_mode_parameter,
1241 self::MAIL_FORM_MODE_REGULAR_MAIL
1242 )->buildURI(),
1243 $this->lng->txt(self::MAIL_FORM_MODE_SERIAL_LETTER) => (string) $url_builder->withParameter(
1244 $mail_mode_parameter,
1245 self::MAIL_FORM_MODE_SERIAL_LETTER
1246 )->buildURI(),
1247 ],
1248 'mail_mode_switch_label'
1249 )->withActive(
1250 $this->lng->txt($use_placeholders ? self::MAIL_FORM_MODE_SERIAL_LETTER : self::MAIL_FORM_MODE_REGULAR_MAIL)
1251 );
1252
1253 $this->toolbar->addComponent($btn);
1254 $this->toolbar->addSeparator();
1255
1256 $this->tpl->addOnLoadCode(
1257 "document.getElementById('{$this->toolbar->getId()}')
1258 .querySelector('div[aria-label=\"" . $this->lng->txt('mail_mode_switch_label') . "\"]')
1259 .querySelectorAll('button[data-action]').forEach(function(button) {
1260 button.addEventListener('click', function(event) {
1261 event.preventDefault();
1262 event.stopPropagation();
1263 event.stopImmediatePropagation();
1264
1265 let mailform = document.querySelector('form.c-form');
1266 let action = button.getAttribute('data-action');
1267 if (action && mailform) {
1268 let submitBtn = mailform.querySelector('button[type=\"submit\"]');
1269 if (submitBtn) {
1270 submitBtn.formAction = action;
1271 mailform.requestSubmit(btn);
1272 } else {
1273 mailform.action = action;
1274 mailform.submit();
1275 }
1276 }
1277 return false;
1278 }, true);
1279 });"
1280 );
1281
1282 $action = $this->ctrl->getFormAction($this, 'searchUsers');
1283 $btn = $bf->standard(
1284 $this->lng->txt('search_recipients'),
1285 ''
1286 )->withAdditionalOnLoadCode(
1287 function ($id) use ($action) {
1288 return "document.getElementById('{$id}').addEventListener('click', function (event) {
1289 let mailform = document.querySelector('form.c-form');
1290 let btn = mailform.querySelector('button');
1291 btn.formAction = '{$action}';
1292 mailform.requestSubmit(btn);
1293 });";
1294 }
1295 );
1296
1297 $this->toolbar->addComponent($btn);
1298
1299 $action = $this->ctrl->getFormAction($this, 'searchCoursesTo');
1300 $btn = $bf->standard(
1301 $this->lng->txt('mail_my_courses'),
1302 ''
1303 )->withAdditionalOnLoadCode(
1304 function ($id) use ($action) {
1305 return "document.getElementById('{$id}').addEventListener('click', function (event) {
1306 let mailform = document.querySelector('form.c-form');
1307 let btn = mailform.querySelector('button');
1308 btn.formAction = '{$action}';
1309 mailform.requestSubmit(btn);
1310 });";
1311 }
1312 );
1313 $this->toolbar->addComponent($btn);
1314
1315 $action = $this->ctrl->getFormAction($this, 'searchGroupsTo');
1316 $btn = $bf->standard(
1317 $this->lng->txt('mail_my_groups'),
1318 ''
1319 )->withAdditionalOnLoadCode(
1320 function ($id) use ($action) {
1321 return "document.getElementById('{$id}').addEventListener('click', function (event) {
1322 let mailform = document.querySelector('form.c-form');
1323 let btn = mailform.querySelector('button');
1324 btn.formAction = '{$action}';
1325 mailform.requestSubmit(btn);
1326 });";
1327 }
1328 );
1329 $this->toolbar->addComponent($btn);
1330
1331 if (count(ilBuddyList::getInstanceByGlobalUser()->getLinkedRelations()) > 0) {
1332 $action = $this->ctrl->getFormAction($this, 'searchMailingListsTo');
1333 $btn = $bf->standard(
1334 $this->lng->txt('mail_my_mailing_lists'),
1335 ''
1336 )->withAdditionalOnLoadCode(
1337 function ($id) use ($action) {
1338 return "document.getElementById('{$id}').addEventListener('click', function (event) {
1339 let mailform = document.querySelector('form.c-form');
1340 let btn = mailform.querySelector('button');
1341 btn.formAction = '{$action}';
1342 mailform.requestSubmit(btn);
1343 });";
1344 }
1345 );
1346 $this->toolbar->addComponent($btn);
1347 }
1348
1349 $this->toolbar->addSeparator();
1350
1351 $action = $this->ctrl->getFormAction($this, 'editAttachments');
1352 $btn = $bf->standard(
1353 $this->lng->txt('edit_attachments'),
1354 ''
1355 )->withAdditionalOnLoadCode(
1356 function ($id) use ($action) {
1357 return "document.getElementById('{$id}').addEventListener('click', function (event) {
1358 let mailform = document.querySelector('form.c-form');
1359 let btn = mailform.querySelector('button');
1360 btn.formAction = '{$action}';
1361 mailform.requestSubmit(btn);
1362 });";
1363 }
1364 );
1365 $this->toolbar->addComponent($btn);
1366 }
1367
1368 private function toggleMailMode(): never
1369 {
1370 $form = $this->buildForm()->withRequest($this->request);
1371
1372 $mode = $this->getQueryParam(
1373 'mail_form_mail_mode',
1374 $this->refinery->kindlyTo()->string(),
1375 self::MAIL_FORM_MODE_REGULAR_MAIL
1376 );
1377
1378 $result = null;
1379 if (!ilMailFormCall::getContextId() && in_array(
1380 $mode,
1381 [self::MAIL_FORM_MODE_REGULAR_MAIL, self::MAIL_FORM_MODE_SERIAL_LETTER],
1382 true
1383 )) {
1384 $result = $form->getInputGroup()->getInputs()[0]->getInputs();
1385 $result['use_placeholders'] = $result['use_placeholders']->withValue(
1386 $mode === self::MAIL_FORM_MODE_SERIAL_LETTER ? '1' : '0'
1387 );
1388 } elseif ($mode === self::MAIL_FORM_MODE_REGULAR_MAIL && ilMailFormCall::getContextId()) {
1389 $this->tpl->setOnScreenMessage(
1390 $this->tpl::MESSAGE_TYPE_INFO,
1391 sprintf(
1392 $this->lng->txt('mail_mode_switch_locked'),
1393 $this->lng->txt('regular_mail')
1394 ),
1395 true
1396 );
1397 }
1398
1399 $this->saveMailBeforeSearch($result ?? null);
1400
1401 $this->ctrl->redirect($this, 'searchResults');
1402 }
1403}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Definition: Streams.php:32
@phpstan-type AutoCompleteUserItem array{label: string, value: string} @phpstan-type AutoCompleteResu...
@phpstan-import-type AutoCompleteUserRecord from RecipientSearchProvider
Definition: Search.php:27
@phpstan-import-type AutoCompleteUserRecord from RecipientSearchProvider
static getInstanceByGlobalUser(?ilObjUser $user=null)
language handling
static prepareFormOutput($a_str, bool $a_strip=false)
static getLogger(string $a_component_id)
Get component logger.
static setContextId(?string $id)
static setContextParameters(array $parameters)
@ilCtrl_Calls ilMailFormGUI: ilMailAttachmentGUI, ilMailSearchGUI, ilMailSearchCoursesGUI,...
final const string MAIL_FORM_TYPE_DRAFT
final const string MAIL_FORM_TYPE_NEW
readonly ilFormatMail $umail
saveMessageToOutbox(array $form_values, Form $form)
readonly ilFileDataMail $mfile
final const string MAIL_FORM_TYPE_ATTACH
buildForm(?array $mail_data=null)
readonly ilObjUser $user
saveMailBeforeSearch(?array $input_results=null)
readonly Renderer $ui_renderer
readonly Psr Http Message ServerRequestInterface $request
final const string MAIL_FORM_TYPE_ADDRESS
final const string MAIL_FORM_TYPE_FORWARD
final const string MAIL_FORM_TYPE_SEARCH_RESULT
readonly ilSetting $settings
readonly ArrayBasedRequestWrapper $query
showSubmissionErrors(array $errors)
ilMailTemplateService $template_service
final const string MAIL_FORM_MODE_SERIAL_LETTER
readonly ilMailbox $mbox
getQueryParam(string $name, Transformation $trafo, $default=null)
readonly GlobalHttpState $http
final const string MAIL_FORM_TYPE_REPLY
final const string MAIL_FORM_TYPE_OUTBOX
showForm(?Form $form=null)
searchUsers(bool $save=true)
readonly ArrayBasedRequestWrapper $post
readonly ILIAS ResourceStorage Services $storage
readonly ilCtrlInterface $ctrl
readonly ilMailFormUploadHandlerGUI $upload_handler
readonly ILIAS User Search Search $user_search
final const string MAIL_FORM_MODE_REGULAR_MAIL
readonly ilMailBodyPurifier $purifier
readonly ClockFactory $clock
readonly ilFileDataMail $fdm
readonly Refinery $refinery
readonly ilTabsGUI $tabs
decodeAttachmentFiles(array $files)
getBodyParam(string $name, Transformation $trafo, $default=null)
addToolbarButtons(Form $form)
readonly ilGlobalTemplateInterface $tpl
buildFormElements(?array $mail_data)
final const string MAIL_FORM_TYPE_ROLE
readonly ilToolbarGUI $toolbar
readonly Factory $ui_factory
readonly ilLanguage $lng
User class.
This class represents a property form user interface.
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
ILIAS Setting Class.
static strLen(string $a_string)
Definition: class.ilStr.php:60
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static securePlainString(string $a_str)
static redirect(string $a_script)
Interface GlobalHttpState.
Interface ResponseHeader.
A transformation is a function from one datatype to another.
getInputs()
Get the inputs contained in the container.
This describes commonalities between all forms.
Definition: Form.php:34
withAdditionalFormAction(string $action, string $label)
Get a form container like this, but provide an additional form action which will be displayed as an a...
This is how the factory for UI elements looks.
Definition: Factory.php:38
An entity that renders components to a string output.
Definition: Renderer.php:31
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.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
withAdditionalTransformation(Transformation $trafo)
@inheritDoc
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
getValue()
Get the value that is displayed in the input client side.
Definition: Group.php:49
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $DIC
Definition: shib_login.php:26