19declare(strict_types=1);
47 use FileDataRCHandling;
78 private readonly \Psr\Http\Message\ServerRequestInterface
$request;
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();
107 $this->ui_factory =
$DIC->ui()->factory();
108 $this->request =
$DIC->http()->request();
109 $this->ui_renderer =
$DIC->ui()->renderer();
113 $this->storage =
$DIC->resourceStorage();
117 $user_api =
$DIC[
'user'];
118 $this->user_search = $user_api->getSearch();
119 $this->clock = (
new DataFactory())->clock();
124 $this->getQueryParam(
126 $this->refinery->kindlyTo()->int(),
131 if ($mail_obj_id === 0) {
132 $mail_obj_id = $this->mbox->getInboxFolder();
135 $this->
ctrl->setParameter($this,
'mobj_id', $mail_obj_id);
140 if ($this->
http->wrapper()->query()->has($name)) {
141 return $this->
http->wrapper()->query()->retrieve(
152 if ($this->
http->wrapper()->post()->has($name)) {
153 return $this->
http->wrapper()->post()->retrieve(
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(
170 $this->
ctrl->forwardCommand($gui);
173 case strtolower(ilMailAttachmentGUI::class):
174 $this->
ctrl->setReturn($this,
'returnFromAttachments');
177 $this->
ctrl->forwardCommand($gui);
180 case strtolower(ilMailSearchGUI::class):
181 $this->
ctrl->setReturn($this,
'searchResults');
185 case strtolower(ilMailSearchCoursesGUI::class):
186 $this->
ctrl->setReturn($this,
'searchResults');
190 case strtolower(ilMailingListsGUI::class):
191 $this->
ctrl->setReturn($this,
'searchResults');
195 case strtolower(ilMailSearchGroupsGUI::class):
196 $this->
ctrl->setReturn($this,
'searchResults');
200 case strtolower(ilMailFormUploadHandlerGUI::class):
201 $this->
ctrl->forwardCommand($this->upload_handler);
205 if (!($cmd = $this->
ctrl->getCmd())) {
221 foreach ($files as $value) {
222 if (is_file($this->mfile->getMailPath() .
'/' . $this->user->getId() .
'_' . urldecode($value))) {
223 $decoded_files[] = urldecode($value);
227 return $decoded_files;
233 if (count($form_values[
'attachments']) > 0) {
234 $files = $this->handleAttachments($form_values[
'attachments']);
240 if ($form_values[
'rcp_to'] !== []) {
241 $rcp_to = $form_values[
'rcp_to'][0];
243 if ($form_values[
'rcp_cc'] !== []) {
244 $rcp_cc = $form_values[
'rcp_cc'][0];
246 if ($form_values[
'rcp_bcc'] !== []) {
247 $rcp_bcc = $form_values[
'rcp_bcc'][0];
250 $errors = $this->umail->validateRecipients(
258 $this->
http->close();
262 $mail_body =
new ilMailBody($message, $this->purifier);
263 $sanitized_message = $mail_body->getContent();
265 $outbox_folder_id = $this->mbox->getOutboxFolder();
271 $this->umail->scheduledMail(
273 $this->
user->getId(),
282 $form_values[
'use_placeholders'],
285 $form_values[
'use_schedule'][
'm_schedule']
294 $this->umail->deleteMails([$draft_id]);
297 $this->
ctrl->setParameterByClass(ilMailFolderGUI::class,
'mobj_id', $outbox_folder_id);
298 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'mail_scheduled'),
true);
303 $this->
ctrl->redirectByClass([ilMailGUI::class, ilMailFolderGUI::class]);
311 $form = $this->
buildForm()->withRequest($this->request);
312 $result = $form->getInputGroup()->getContent();
314 if (!$result->isOK()) {
319 $value = $result->value()[0];
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()) {
329 if (count($value[
'attachments']) > 0) {
330 $files = $this->handleAttachments($value[
'attachments']);
333 $mailer = $this->umail
337 $mailer->setSaveInSentbox(
true);
339 $mailer->autoresponder()->enableAutoresponder();
344 if (!empty($value[
'rcp_to'])) {
345 $rcp_to = implode(
',', $value[
'rcp_to']);
347 if (!empty($value[
'rcp_cc'])) {
348 $rcp_cc = implode(
',', $value[
'rcp_cc']);
350 if (!empty($value[
'rcp_bcc'])) {
351 $rcp_bcc = implode(
',', $value[
'rcp_bcc']);
354 if ($errors = $mailer->enqueue(
361 $value[
'use_placeholders']
363 $mailer->autoresponder()->disableAutoresponder();
368 $this->
http->close();
370 $mailer->autoresponder()->disableAutoresponder();
372 $mailer->persistToStage(
373 $this->
user->getId(),
392 $mailer->deleteMails([$mail_id]);
395 $this->
ctrl->setParameterByClass(ilMailGUI::class,
'type',
'message_sent');
398 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'mail_message_send'),
true);
401 $this->
ctrl->redirectByClass(ilMailGUI::class);
404 $mailer->autoresponder()->disableAutoresponder();
411 $form = $this->
buildForm()->withRequest($this->request);
412 $result = $form->getInputGroup()->getContent();
414 if (!$result->isOK()) {
419 $value = $result->value()[0];
421 if ($value[
'm_subject'] ===
'') {
422 $value[
'm_subject'] = $this->
lng->txt(
'mail_no_subject');
425 if (count($value[
'attachments']) > 0) {
426 $files = $this->handleAttachments($value[
'attachments']);
429 $draft_folder_id = $this->mbox->getDraftsFolder();
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']) :
'';
435 if ($errors = $this->umail->validateRecipients($rcp_to, $rcp_cc, $rcp_bcc)) {
436 $this->request_attachments = $files;
446 $draft_id = $this->umail->getNewDraftId($draft_folder_id);
449 $this->umail->updateDraft(
458 $value[
'use_schedule'][
'm_schedule'] ??
null,
459 $value[
'use_placeholders'],
467 $this->umail->deleteMails([$outbox_id]);
470 $this->
ctrl->setParameterByClass(ilMailFolderGUI::class,
'mobj_id', $draft_folder_id);
471 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'mail_saved'),
true);
476 $this->
ctrl->redirectByClass([ilMailGUI::class, ilMailFolderGUI::class]);
484 $this->tpl->setTitle($this->
lng->txt(
'mail_new'));
491 $form->setId(
'search_rcp');
492 $form->setTitle($this->
lng->txt(
'search_recipients'));
493 $form->setFormAction($this->
ctrl->getFormAction($this,
'search'));
497 $data_source_url = $this->
ctrl->getLinkTarget($this,
'lookupRecipientAsync',
'',
true);
498 $inp->setDataSource($data_source_url);
500 $search_query = trim((
string)
ilSession::get(
'mail_search_search'));
501 if ($search_query !==
'') {
504 $form->addItem($inp);
506 $form->addCommandButton(
'search', $this->
lng->txt(
'search'));
507 $form->addCommandButton(
'cancelSearch', $this->
lng->txt(
'cancel'));
509 $this->tpl->setContent($form->getHTML());
510 $this->tpl->printToStdout();
518 $this->
ctrl->setParameterByClass(
'ilmailsearchcoursesgui',
'cmd',
'showMembers');
521 $this->
ctrl->setParameterByClass(ilMailSearchCoursesGUI::class,
'ref',
'mail');
522 $this->
ctrl->redirectByClass(ilMailSearchCoursesGUI::class);
529 $this->
ctrl->setParameterByClass(ilMailSearchGroupsGUI::class,
'ref',
'mail');
530 $this->
ctrl->redirectByClass(ilMailSearchGroupsGUI::class);
536 'mail_search_search',
541 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'mail_insert_query'));
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'));
548 $this->
ctrl->setParameterByClass(
549 ilMailSearchGUI::class,
553 $this->
ctrl->redirectByClass(ilMailSearchGUI::class);
567 $this->
ctrl->setParameterByClass(ilMailAttachmentGUI::class,
'ref',
'mail');
568 $this->
ctrl->redirectByClass(ilMailAttachmentGUI::class);
609 if (!$this->
http->wrapper()->query()->has(
'template_id')) {
610 $this->
http->close();
614 $template = $this->template_service->loadTemplateForId(
615 $this->
http->wrapper()->query()->retrieve(
'template_id', $this->refinery->kindlyTo()->int())
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)))
627 }
catch (Exception) {
630 $this->
http->sendResponse();
631 $this->
http->close();
636 $this->tpl->addBlockFile(
640 'components/ILIAS/Mail'
642 $this->tpl->setTitle($this->
lng->txt(
'mail_new'));
644 $this->
lng->loadLanguageModule(
'crs');
647 $this->
tabs->setBackTarget(
648 $this->
lng->txt(
'back'),
649 $this->ctrl->getLinkTarget($this,
'cancelMail')
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'] =
'';
663 if ($this->mail_form_type !==
'') {
669 $mail_data = $this->umail->getMail($mail_id);
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'] ??
'')
675 $mail_data[
'attachments'] = [];
676 $mail_data[
'rcp_cc'] =
'';
677 $mail_data[
'rcp_to'] = $this->umail->formatReplyRecipient();
681 $mail_data = $this->umail->retrieveFromStage();
683 $mail_data = $this->umail->appendSearchResult(
684 $this->
refinery->kindlyTo()->listOf(
685 $this->refinery->kindlyTo()->string()
691 $mail_data = $this->umail->appendSearchResult(
692 $this->
refinery->kindlyTo()->listOf(
693 $this->refinery->kindlyTo()->string()
699 $mail_data = $this->umail->appendSearchResult(
700 $this->
refinery->kindlyTo()->listOf(
701 $this->refinery->kindlyTo()->string()
714 $mail_data = $this->umail->getMail($mail_id);
716 if (!is_null($mail_data[
'attachments']) || !empty($mail_data[
'attachments'])) {
717 $mail_data[
'attachments'] = $this->filesFromLegacyToIRSS($mail_data);
726 $mail_data = $this->umail->getMail($mail_id);
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'],
740 $this->tpl->setOnScreenMessage(
'info', $error);
743 if (!is_null($mail_data[
'attachments']) || ($mail_data[
'attachments'] !=
'')) {
744 $mail_data[
'attachments'] = $this->filesFromLegacyToIRSS($mail_data);
756 $mail_data[
'rcp_to'] = $to;
762 $mail_data[
'rcp_cc'] = $cc;
768 $mail_data[
'rcp_bcc'] = $bcc;
770 $mail_data[
'm_message'] =
'';
772 $mail_data[
'm_message'] = $sig;
773 $mail_data[
'm_message'] .= chr(13)
778 $mail_data[
'm_message'] .= $this->umail->appendSignature(
'');
787 if ($this->
http->wrapper()->post()->has(
'roles')) {
788 $roles = $this->
http->wrapper()->post()->retrieve(
790 $this->
refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
793 $roles = $this->
refinery->kindlyTo()->listOf(
794 $this->
refinery->kindlyTo()->string()
803 $mail_data[
'm_message'] =
'';
805 $mail_data[
'm_message'] = $sig;
806 $mail_data[
'm_message'] .= chr(13)
812 $additional_msg_text =
'';
813 if ($this->
http->wrapper()->post()->has(
'additional_message_text')) {
815 'additional_message_text',
816 $this->refinery->kindlyTo()->string()
820 $mail_data[
'm_message'] .= $additional_msg_text
823 . $this->umail->appendSignature(
'');
829 if ($this->
http->wrapper()->query()->has(
'rcp')) {
830 $rcp = $this->
http->wrapper()->query()->retrieve(
'rcp', $this->
refinery->kindlyTo()->string());
832 $mail_data[
'rcp_to'] = urldecode((
string) $rcp);
835 $mail_data = $this->umail->retrieveFromStage();
838 $mail_data = $this->
http->request()->getParsedBody();
839 foreach ($mail_data as $key => $value) {
840 if (is_string($value)) {
846 if ($this->request_attachments) {
852 $this->tpl->parseCurrentBlock();
857 $this->tpl->setVariable(
'FORM', $this->ui_renderer->render($form));
858 $this->tpl->addJavaScript(
'assets/js/ilMailComposeFunctions.js');
859 $this->tpl->printToStdout();
866 $this->
refinery->kindlyTo()->string(),
867 $this->getQueryParam(
869 $this->refinery->kindlyTo()->string(),
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)))
883 $this->
http->sendResponse();
884 $this->
http->close();
889 $quoted = str_replace([
'%',
'_'], [
'\%',
'\_'], $quoted);
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)))
899 $this->
http->sendResponse();
900 $this->
http->close();
917 if (empty($input_results)) {
918 $form = $this->
buildForm()->withRequest($this->request);
919 $result = $form->getInputGroup()->getInputs()[0]->getInputs();
921 $result = $input_results;
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);
930 $rcp_to = implode(
',', $result[
'rcp_to']->
getValue() ?? []);
931 $rcp_cc = implode(
',', $result[
'rcp_cc']->
getValue() ?? []);
932 $rcp_bcc = implode(
',', $result[
'rcp_bcc']->
getValue() ?? []);
934 $this->umail->persistToStage(
935 $this->
user->getId(),
941 $resource_collection_id,
942 (
bool) $result[
'use_placeholders']->getValue(),
952 $this->
ctrl->setParameterByClass(ilMailingListsGUI::class,
'ref',
'mail');
953 $this->
ctrl->redirectByClass(ilMailingListsGUI::class);
962 $formatted_errors = $formatter->format($errors);
964 if ($formatted_errors !==
'') {
965 $this->tpl->setOnScreenMessage(
'failure', $formatted_errors);
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'));
987 $ff = $this->ui_factory->input()->field();
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');
998 $rcp_cc = $this->user_search->getInput(
999 $this->
lng->txt(
'mail_cc'),
1002 $rcp_bcc = $this->user_search->getInput(
1003 $this->
lng->txt(
'mail_bcc'),
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']);
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']);
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']);
1019 $has_files = !empty($mail_data[
'attachments']);
1020 $attachments = $ff->file(
1021 $this->upload_handler,
1022 $this->
lng->txt(
'attachments')
1023 )->withMaxFiles(10);
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']);
1029 $attachments = $attachments->withValue($mail_data[
'attachments'] ?? []);
1032 $template_chb =
null;
1034 $use_placeholder_value =
false;
1041 $use_placeholder_value =
true;
1043 $templates = $this->template_service->loadTemplatesForContextId($context->getId());
1044 if (!empty($templates)) {
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()));
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());
1061 if (isset($mail_data[
'template_id'])) {
1062 $tmpl_value = (
int) $mail_data[
'template_id'];
1068 $this->
lng->txt(
'mail_template_client'),
1070 $this->lng->txt(
'mail_template_client_info')
1072 ->withValue($tmpl_value)
1073 ->withOnUpdate($signal);
1075 }
catch (Exception) {
1077 '%s has been called with invalid context id: %s.',
1083 $use_placeholder_value = $mail_data[
'use_placeholders'] ??
false;
1087 ->text($this->
lng->txt(
'subject'))
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');
1097 ->withMaxLength(200)
1098 ->withValue($mail_data[
'm_subject'] ??
'');
1100 $m_message = $ff->markdown(
1102 $this->
lng->txt(
'message_content')
1103 )->
withValue($mail_data[
'm_message'] ??
'');
1105 $use_placeholders = $ff->hidden()->withValue($use_placeholder_value ?
'1' :
'0');
1109 if ($mode === self::MAIL_FORM_MODE_SERIAL_LETTER && $context) {
1110 foreach ($context->getPlaceholders() as $value) {
1111 $placeholders[$value[
'placeholder']] = $value[
'label'];
1113 if (!empty($placeholders)) {
1114 $m_message = $m_message
1115 ->withMustacheVariables(
1117 $this->
lng->txt(
'mail_nacc_use_placeholder') .
'<br />'
1118 . sprintf($this->
lng->txt(
'placeholders_advise'),
'<br />')
1124 $use_placeholders = $use_placeholders->withAdditionalTransformation(
1125 $this->
refinery->kindlyTo()->bool()
1128 if ($signal !==
null) {
1129 $m_subject = $m_subject->withAdditionalOnLoadCode(
1130 function (
$id) use ($signal) {
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;
1138 child.value = decodeURIComponent(signalData.options[tplId + '_subject'].replace(/\+/g, ' '));
1144 $m_message = $m_message->withAdditionalOnLoadCode(
1145 function (
$id) use ($signal) {
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;
1153 child.value = decodeURIComponent(signalData.options[tplId + '_message'].replace(/\+/g, ' '));
1162 'rcp_to' => $rcp_to,
1163 'rcp_cc' => $rcp_cc,
1164 'rcp_bcc' => $rcp_bcc,
1165 'm_subject' => $m_subject,
1166 'attachments' => $attachments
1168 if ($template_chb !==
null) {
1169 $elements[] = $template_chb;
1171 $elements[
'm_message'] = $m_message;
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'))
1178 ->withTimezone($this->
user->getTimezone())
1180 $this->
refinery->custom()->constraint(
1181 function (DateTimeImmutable $v) use ($current_time) {
1182 return $v > $current_time;
1184 $this->
lng->txt(
'mail_schedule_error_past_datetime')
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'] ??
'')
1193 $schedule_time->setTimezone(
new DateTimeZone($this->
user->getTimeZone()));
1194 $schedule_date_time_value = $schedule_time > $current_time ? $schedule_time :
null;
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);
1205 $this->
lng->txt(
'mail_schedule_error_no_datetime')
1208 if ($schedule_date_time_value !==
null) {
1209 $use_schedule_input = $use_schedule_input->withValue([
'm_schedule' => $schedule_date_time_value]);
1211 $use_schedule_input = $use_schedule_input->withValue(
null);
1214 $elements[
'use_schedule'] = $use_schedule_input;
1215 $elements[
'use_placeholders'] = $use_placeholders;
1217 $section = $ff->section(
1219 $this->
lng->txt(
'compose')
1229 $bf = $this->ui_factory->button();
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');
1237 $btn = $this->ui_factory->viewControl()->mode(
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
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
1248 'mail_mode_switch_label'
1250 $this->
lng->txt($use_placeholders ? self::MAIL_FORM_MODE_SERIAL_LETTER : self::MAIL_FORM_MODE_REGULAR_MAIL)
1253 $this->
toolbar->addComponent($btn);
1254 $this->
toolbar->addSeparator();
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();
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\"]');
1270 submitBtn.formAction = action;
1271 mailform.requestSubmit(btn);
1273 mailform.action = action;
1282 $action = $this->
ctrl->getFormAction($this,
'searchUsers');
1283 $btn = $bf->standard(
1284 $this->
lng->txt(
'search_recipients'),
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);
1297 $this->
toolbar->addComponent($btn);
1299 $action = $this->
ctrl->getFormAction($this,
'searchCoursesTo');
1300 $btn = $bf->standard(
1301 $this->
lng->txt(
'mail_my_courses'),
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);
1313 $this->
toolbar->addComponent($btn);
1315 $action = $this->
ctrl->getFormAction($this,
'searchGroupsTo');
1316 $btn = $bf->standard(
1317 $this->
lng->txt(
'mail_my_groups'),
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);
1329 $this->
toolbar->addComponent($btn);
1332 $action = $this->
ctrl->getFormAction($this,
'searchMailingListsTo');
1333 $btn = $bf->standard(
1334 $this->
lng->txt(
'mail_my_mailing_lists'),
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);
1346 $this->
toolbar->addComponent($btn);
1349 $this->
toolbar->addSeparator();
1351 $action = $this->
ctrl->getFormAction($this,
'editAttachments');
1352 $btn = $bf->standard(
1353 $this->
lng->txt(
'edit_attachments'),
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);
1365 $this->
toolbar->addComponent($btn);
1370 $form = $this->
buildForm()->withRequest($this->request);
1373 'mail_form_mail_mode',
1374 $this->
refinery->kindlyTo()->string(),
1375 self::MAIL_FORM_MODE_REGULAR_MAIL
1381 [self::MAIL_FORM_MODE_REGULAR_MAIL, self::MAIL_FORM_MODE_SERIAL_LETTER],
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'
1389 $this->tpl->setOnScreenMessage(
1390 $this->tpl::MESSAGE_TYPE_INFO,
1392 $this->
lng->txt(
'mail_mode_switch_locked'),
1393 $this->lng->txt(
'regular_mail')
1401 $this->
ctrl->redirect($this,
'searchResults');
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Builds a Color from either hex- or rgb values.
The scope of this class is split ilias-conform URI's into components.
Stream factory which enables the user to create streams without the knowledge of the concrete class.
Class ArrayBasedRequestWrapper.
@phpstan-type AutoCompleteUserItem array{label: string, value: string} @phpstan-type AutoCompleteResu...
@phpstan-import-type AutoCompleteUserRecord from RecipientSearchProvider
@phpstan-import-type AutoCompleteUserRecord from RecipientSearchProvider
static getInstanceByGlobalUser(?ilObjUser $user=null)
static getLogger(string $a_component_id)
Get component logger.
static getTemplateContextById(string $a_id)
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
static strLen(string $a_string)
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.
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.
This is how the factory for UI elements looks.
An entity that renders components to a string output.
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
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.