19declare(strict_types=1);
32 use FileDataRCHandling;
60 private int $a_user_id,
71 private ?Closure $usr_id_by_login_callable =
null,
73 private ?
int $mail_admin_node_ref_id =
null,
74 private ?
int $mail_obj_ref_id =
null,
85 $this->event_handler = $event_handler ??
$DIC->event();
86 $this->db = $db ??
$DIC->database();
87 $this->
lng =
$lng ?? $DIC->language();
88 $this->actor = $actor ??
$DIC->user();
89 $this->mail_file_data = $mail_file_data ??
new ilFileDataMail($a_user_id);
90 $this->mail_options = $mail_options ??
new ilMailOptions($a_user_id);
91 $this->mailbox = $mailbox ??
new ilMailbox($a_user_id);
93 $this->sender_factory = $sender_factory ??
$DIC->mail()->mime()->senderFactory();
94 $this->usr_id_by_login_callable = $usr_id_by_login_callable ?? (
static fn(
string $login):
int => (
int)
ilObjUser::_lookupId($login));
95 $this->auto_responder_service = $auto_responder_service ??
$DIC->mail()->autoresponder();
96 $this->user_id = $a_user_id;
97 if ($this->mail_obj_ref_id ===
null) {
100 $this->
lng->loadLanguageModule(
'mail');
101 $this->table_mail =
'mail';
102 $this->table_mail_saved =
'mail_saved';
104 $this->placeholder_resolver = $placeholder_resolver ??
$DIC->mail()->placeholderResolver();
105 $this->placeholder_to_empty_resolver = $placeholder_to_empty_resolver ??
$DIC->mail()->placeholderToEmptyResolver();
113 return $this->auto_responder_service;
118 $clone = clone $this;
127 $clone = clone $this;
129 $clone->context_parameters = $parameters;
139 public function existsRecipient(
string $new_recipient,
string $existing_recipients): bool
145 $diffed_addresses = $list->value();
147 return $diffed_addresses === [];
167 return $this->mail_obj_ref_id;
172 $recipients = trim($recipients);
173 if ($recipients ===
'') {
174 return $this->
lng->txt(
'not_available');
179 $recipients = array_filter(array_map(
'trim', explode(
',', $recipients)));
180 foreach ($recipients as $recipient) {
182 if (is_int($usr_id) && $usr_id > 0) {
184 if ($pp ===
'g' || ($pp ===
'y' && !$this->actor->isAnonymous())) {
187 $names[] = $user->getFullname() .
' [' . $recipient .
']';
193 $names[] = $recipient;
196 return implode(
', ', $names);
201 $this->db->setLimit(1, 0);
203 $query = implode(
' ', [
204 "SELECT b.* FROM $this->table_mail a",
205 "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
206 'AND b.user_id = a.user_id AND b.send_time > a.send_time',
207 'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time ASC',
209 $res = $this->db->queryF(
211 [
'integer',
'integer'],
212 [$this->user_id, $mail_id]
222 $this->db->setLimit(1, 0);
224 $query = implode(
' ', [
225 "SELECT b.* FROM $this->table_mail a",
226 "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
227 'AND b.user_id = a.user_id AND b.send_time < a.send_time',
228 'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time DESC',
230 $res = $this->db->queryF(
232 [
'integer',
'integer'],
233 [$this->user_id, $mail_id]
246 'SELECT sender_id, m_subject, mail_id, m_status, send_time, import_name ' .
247 "FROM $this->table_mail " .
248 'LEFT JOIN object_data ON obj_id = sender_id ' .
249 'WHERE user_id = %s AND folder_id = %s ' .
250 'AND ((sender_id > 0 AND sender_id IS NOT NULL AND obj_id IS NOT NULL) ' .
251 'OR (sender_id = 0 OR sender_id IS NULL))';
253 if (isset($filter[
'status']) && $filter[
'status'] !==
'') {
254 $query .=
' AND m_status = ' . $this->db->quote($filter[
'status'],
'text');
257 $query .=
' ORDER BY send_time DESC';
259 $res = $this->db->queryF(
261 [
'integer',
'integer'],
262 [$this->user_id, $a_folder_id]
265 while ($row = $this->db->fetchAssoc(
$res)) {
269 return array_filter($mails);
274 $res = $this->db->queryF(
275 "SELECT COUNT(*) FROM $this->table_mail WHERE user_id = %s AND folder_id = %s",
276 [
'integer',
'integer'],
277 [$this->user_id, $folder_id]
280 return $this->db->numRows(
$res);
293 $res = $this->db->queryF(
294 "SELECT * FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
295 [
'integer',
'integer'],
296 [$this->user_id, $mail_id]
312 $query =
"UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
314 $types[] =
'integer';
318 if ($mail_ids !== []) {
319 $query .=
' AND ' . $this->db->in(
'mail_id', $mail_ids,
false,
'integer');
322 $this->db->manipulateF($query, $types, $values);
333 $query =
"UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
335 $types[] =
'integer';
336 $values[] =
'unread';
339 if ($mail_ids !== []) {
340 $query .=
' AND ' . $this->db->in(
'mail_id', $mail_ids,
false,
'integer');
343 $this->db->manipulateF($query, $types, $values);
354 $mail_ids = array_filter(array_map(intval(...), $mail_ids));
356 if ([] === $mail_ids) {
361 "UPDATE $this->table_mail " .
362 'INNER JOIN mail_obj_data ' .
363 'ON mail_obj_data.obj_id = %s AND mail_obj_data.user_id = %s ' .
364 "SET $this->table_mail.folder_id = mail_obj_data.obj_id " .
365 "WHERE $this->table_mail.user_id = %s";
366 $types[] =
'integer';
367 $types[] =
'integer';
368 $types[] =
'integer';
369 $values[] = $folder_id;
373 $query .=
' AND ' . $this->db->in(
'mail_id', $mail_ids,
false,
'integer');
375 $affected_rows = $this->db->manipulateF($query, $types, $values);
377 return $affected_rows > 0;
385 $mail_ids = array_filter(array_map(
'intval', $mail_ids));
386 foreach ($mail_ids as
$id) {
387 $this->db->manipulateF(
388 "DELETE FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
389 [
'integer',
'integer'],
390 [$this->user_id,
$id]
392 $this->mail_file_data->deassignAttachmentFromDirectory(
$id);
398 if (!is_array($row) || empty($row)) {
402 if (isset($row[
'attachments']) && is_string($row[
'attachments']) && str_contains($row[
'attachments'],
'{')) {
403 $unserialized_attachments = unserialize($row[
'attachments'], [
'allowed_classes' =>
false]);
404 $row[
'attachments'] = is_array($unserialized_attachments) ? $unserialized_attachments :
null;
405 } elseif (isset($row[
'attachments']) && is_string($row[
'attachments']) && $row[
'attachments'] !==
'') {
408 $row[
'attachments'] =
null;
411 if (isset($row[
'tpl_ctx_params']) && is_string($row[
'tpl_ctx_params'])) {
412 $decoded = json_decode($row[
'tpl_ctx_params'],
true, 512, JSON_THROW_ON_ERROR);
413 $row[
'tpl_ctx_params'] = (array) ($decoded ?? []);
415 $row[
'tpl_ctx_params'] = [];
418 if (isset($row[
'mail_id'])) {
419 $row[
'mail_id'] = (
int) $row[
'mail_id'];
422 if (isset($row[
'user_id'])) {
423 $row[
'user_id'] = (
int) $row[
'user_id'];
426 if (isset($row[
'folder_id'])) {
427 $row[
'folder_id'] = (
int) $row[
'folder_id'];
430 if (isset($row[
'sender_id'])) {
431 $row[
'sender_id'] = (
int) $row[
'sender_id'];
434 if (isset($row[
'use_placeholders'])) {
435 $row[
'use_placeholders'] = (bool) $row[
'use_placeholders'];
438 $null_to_string_properties = [
'm_subject',
'm_message',
'rcp_to',
'rcp_cc',
'rcp_bcc'];
439 foreach ($null_to_string_properties as $null_to_string_property) {
440 if (!isset($row[$null_to_string_property])) {
441 $row[$null_to_string_property] =
'';
450 $next_id = $this->db->nextId($this->table_mail);
451 $this->db->insert($this->table_mail, [
452 'mail_id' => [
'integer', $next_id],
453 'user_id' => [
'integer', $this->user_id],
454 'folder_id' => [
'integer', $folder_id],
455 'sender_id' => [
'integer', $this->user_id],
466 array $a_attachments,
473 ?DateTimeImmutable $schedule_time =
null,
474 bool $a_use_placeholders =
false,
475 ?
string $a_tpl_context_id =
null,
476 array $a_tpl_context_params = []
481 'folder_id' => [
'integer', $a_folder_id],
482 'attachments' => [
'clob', serialize($a_attachments)],
483 'send_time' => [
'timestamp', date(
'Y-m-d H:i:s')],
484 'rcp_to' => [
'clob', $a_rcp_to],
485 'rcp_cc' => [
'clob', $a_rcp_cc],
486 'rcp_bcc' => [
'clob', $a_rcp_bcc],
487 'm_status' => [
'text',
'read'],
488 'm_subject' => [
'text', $a_m_subject],
489 'm_message' => [
'clob', $a_m_message],
490 'use_placeholders' => [
'integer', (
int) $a_use_placeholders],
491 'tpl_ctx_id' => [
'text', $a_tpl_context_id],
492 'tpl_ctx_params' => [
'blob', json_encode($a_tpl_context_params, JSON_THROW_ON_ERROR)],
493 'schedule_datetime' => [
ilDBConstants::T_TIMESTAMP, $schedule_time?->format(
'Y-m-d H:i:s')],
494 'schedule_timezone' => [
ilDBConstants::T_TEXT, $schedule_time?->getTimezone()->getName()],
497 'mail_id' => [
'integer', $a_draft_id],
511 ?
string $template_context_id =
null,
512 array $template_context_parameters = []
514 $message = $mail_data->getMailDeliveryData()->getMessage();
516 $message = $this->replacePlaceholders($mail_data->
getMailDeliveryData()->getMessage(), $sender_usr_id);
518 $message = str_ireplace([
'<br />',
'<br>',
'<br/>'],
"\n", $message);
532 'tpl_ctx_params' => [
ilDBConstants::T_BLOB, json_encode($template_context_parameters, JSON_THROW_ON_ERROR)],
538 $outbox_id = $this->db->nextId($this->table_mail);
540 $this->db->insert($this->table_mail, $mail_values);
543 $this->db->update($this->table_mail, $mail_values, [
562 bool $use_placeholders =
false,
563 ?
string $template_contenxt_id =
null,
564 array $template_context_parameters = []
566 $usr_id = $usr_id ?: $this->user_id;
568 if ($use_placeholders) {
569 $message = $this->replacePlaceholders($message, $usr_id);
572 $message = str_ireplace([
'<br />',
'<br>',
'<br/>'],
"\n", $message);
574 $next_id = $this->db->nextId($this->table_mail);
575 $this->db->insert($this->table_mail, [
576 'mail_id' => [
'integer', $next_id],
577 'user_id' => [
'integer', $usr_id],
578 'folder_id' => [
'integer', $folder_id],
579 'sender_id' => [
'integer', $sender_usr_id],
580 'attachments' => [
'clob', serialize($attachments)],
581 'send_time' => [
'timestamp', date(
'Y-m-d H:i:s')],
582 'rcp_to' => [
'clob', $to],
583 'rcp_cc' => [
'clob', $cc],
584 'rcp_bcc' => [
'clob', $bcc],
585 'm_status' => [
'text', $status],
586 'm_subject' => [
'text', $subject],
587 'm_message' => [
'clob', $message],
588 'tpl_ctx_id' => [
'text', $template_contenxt_id],
589 'tpl_ctx_params' => [
'blob', json_encode($template_context_parameters, JSON_THROW_ON_ERROR)],
592 $sender_equals_reveiver = $usr_id === $this->mailbox->getUsrId();
593 $is_sent_folder_of_sender =
false;
594 if ($sender_equals_reveiver) {
595 $current_folder_id = $this->getSubjectSentFolderId();
596 $is_sent_folder_of_sender = $folder_id === $current_folder_id;
599 $raise_event = !$sender_equals_reveiver || !$is_sent_folder_of_sender;
602 $this->event_handler->raise(
'components/ILIAS/Mail',
'sentInternalMail', [
604 'subject' => $subject,
606 'from_usr_id' => $sender_usr_id,
607 'to_usr_id' => $usr_id,
622 if ($this->context_id) {
628 $user = $usr_id > 0 ? $this->getUserInstanceById($usr_id) : null;
629 $message = $this->placeholder_resolver->resolve(
633 $this->context_parameters
635 }
catch (Exception
$e) {
636 $this->
logger->error(sprintf(
637 '%s has been called with invalid context: %s / %s',
640 $e->getTraceAsString()
649 return $this->placeholder_to_empty_resolver->resolve($message);
654 $this->auto_responder_service->emptyAutoresponderData();
655 $to_usr_ids = $this->getUserIds([$mail_data->
getTo()]);
656 $this->
logger->debug(sprintf(
657 'Parsed TO user ids from given recipients for serial letter notification: %s',
658 implode(
', ', $to_usr_ids)
661 $other_usr_ids = $this->getUserIds([$mail_data->
getCc(), $mail_data->
getBcc()]);
662 $cc_bcc_recipients = array_map(
663 $this->createRecipient(...),
666 $this->
logger->debug(sprintf(
667 'Parsed CC/BCC user ids from given recipients for serial letter notification: %s',
668 implode(
', ', $other_usr_ids)
672 $this->sendMailWithReplacedPlaceholder($mail_data, $to_usr_ids);
673 $this->sendMailWithReplacedEmptyPlaceholder($mail_data, $cc_bcc_recipients);
675 $this->sendMailWithoutReplacedPlaceholder($mail_data, $to_usr_ids, $cc_bcc_recipients);
678 $this->auto_responder_service->disableAutoresponder();
679 $this->auto_responder_service->handleAutoresponderMails($this->user_id);
692 $recipient = $this->createRecipient(
$user_id);
694 $this->sendChanneledMails(
709 $this->sendChanneledMails(
712 $this->replacePlaceholdersEmpty($mail_data->getMessage()),
723 array $cc_bcc_recipients
725 $to_recipients = array_map(
726 $this->createRecipient(...),
730 $this->sendChanneledMails(
732 array_merge($to_recipients, $cc_bcc_recipients),
745 $usr_id_to_external_email_addresses_map = [];
747 foreach ($recipients as $recipient) {
748 if (!$recipient->isUser()) {
749 $this->
logger->critical(sprintf(
750 'Skipped recipient with id %s (User not found)',
751 $recipient->getUserId()
756 $can_read_internal = $recipient->evaluateInternalMailReadability();
757 if ($this->isSystemMail() && !$can_read_internal->isOk()) {
758 $this->
logger->debug(sprintf(
759 'Skipped recipient with id %s and reason: %s',
760 $recipient->getUserId(),
761 is_string($can_read_internal->error()) ? $can_read_internal->error() : $can_read_internal->error()->getMessage()
766 if ($recipient->isUserActive() && !$recipient->isUserExpired()) {
767 if (!$can_read_internal->isOk() || $recipient->userWantsToReceiveExternalMails()) {
768 $email_addresses = $recipient->getExternalMailAddress();
769 $usr_id_to_external_email_addresses_map[$recipient->getUserId()] = $email_addresses;
771 if ($recipient->onlyToExternalMailAddress()) {
772 $this->
logger->debug(sprintf(
773 'Recipient with id %s will only receive external emails sent to: %s',
774 $recipient->getUserId(),
775 implode(
', ', $email_addresses)
780 $this->
logger->debug(sprintf(
781 'Recipient with id %s will additionally receive external emails ' .
782 '(because the user wants to receive it externally, or the user cannot did not accept ' .
783 'the legal documents) sent to: %s',
784 $recipient->getUserId(),
785 implode(
', ', $email_addresses)
788 $this->
logger->debug(sprintf(
789 'Recipient with id %s does not want to receive external emails',
790 $recipient->getUserId()
794 $this->
logger->debug(sprintf(
795 'Recipient with id %s is inactive or expired and will not receive external emails',
796 $recipient->getUserId()
800 $mbox = clone $this->mailbox;
801 $mbox->setUsrId($recipient->getUserId());
802 $recipient_inbox_id = $mbox->getInboxFolder();
804 $internal_mail_id = $this->sendInternalMail(
814 $recipient->getUserId()
817 $this->auto_responder_service->enqueueAutoresponderIfEnabled(
818 $recipient->getUserId(),
819 $recipient->getMailOptions(),
820 $this->getMailOptionsByUserId($this->user_id),
824 $this->mail_file_data->assignAttachmentsToDirectory($internal_mail_id, $mail_data->
getInternalMailId());
828 $this->delegateExternalEmails(
832 $usr_id_to_external_email_addresses_map
844 array $usr_id_to_external_email_addresses_map
846 if (count($usr_id_to_external_email_addresses_map) === 1) {
847 $usr_id_to_external_email_addresses_map = array_values($usr_id_to_external_email_addresses_map);
848 $first_addresses = current($usr_id_to_external_email_addresses_map);
851 implode(
',', $first_addresses),
858 } elseif (count($usr_id_to_external_email_addresses_map) > 1) {
859 $flattened_email_addresses = iterator_to_array(
new RecursiveIteratorIterator(
new RecursiveArrayIterator(
860 $usr_id_to_external_email_addresses_map
863 $flattened_email_addresses = array_unique($flattened_email_addresses);
866 $remaining_addresses =
'';
867 foreach ($flattened_email_addresses as $email_address) {
869 if ($remaining_addresses !==
'') {
873 $recipients_line_length =
ilStr::strLen($remaining_addresses) +
875 if ($recipients_line_length >= $this->max_recipient_character_length) {
879 $remaining_addresses,
885 $remaining_addresses =
'';
889 $remaining_addresses .= ($sep . $email_address);
892 if ($remaining_addresses !==
'') {
896 $remaining_addresses,
911 $parsed_usr_ids = [];
913 $joined_recipients = implode(
',', array_filter(array_map(
'trim', $recipients)));
915 $addresses = $this->parseAddresses($joined_recipients);
916 foreach ($addresses as $address) {
917 $address_type = $this->mail_address_type_factory->getByPrefix($address);
918 $parsed_usr_ids[] = $address_type->resolve();
921 return array_unique(array_merge(...$parsed_usr_ids));
927 private function checkMail(
string $to,
string $cc,
string $bcc,
string $subject): array
932 $subject =>
'mail_add_subject',
933 $to =>
'mail_add_recipient',
935 foreach ($checks as $string => $error) {
936 if ($string ===
'') {
943 $errors[] =
new ilMailError(
'mail_subject_too_long');
957 $addresses = $this->parseAddresses($recipients);
958 foreach ($addresses as $address) {
959 $address_type = $this->mail_address_type_factory->getByPrefix($address);
960 if (!$address_type->validate($this->user_id)) {
961 $errors[] = $address_type->getErrors();
964 }
catch (Exception
$e) {
965 $position = strpos(
$e->getMessage(),
':');
967 ($position ===
false) ?
$e->getMessage() : substr(
$e->getMessage(), $position + 2),
973 return array_merge(...$errors);
987 bool $a_use_placeholders =
false,
988 ?
string $a_tpl_context_id =
null,
989 ?array $a_tpl_ctx_params = []
991 if (!is_null($a_attachments)) {
992 $a_attachments = $a_attachments->serialize();
995 $this->table_mail_saved,
997 'user_id' => [
'integer', $this->user_id],
1000 'attachments' => [
'text', $a_attachments],
1001 'rcp_to' => [
'clob', $a_rcp_to],
1002 'rcp_cc' => [
'clob', $a_rcp_cc],
1003 'rcp_bcc' => [
'clob', $a_rcp_bcc],
1004 'm_subject' => [
'text', $a_m_subject],
1005 'm_message' => [
'clob', $a_m_message],
1006 'use_placeholders' => [
'integer', (
int) $a_use_placeholders],
1007 'tpl_ctx_id' => [
'text', $a_tpl_context_id],
1008 'tpl_ctx_params' => [
'blob', json_encode((array) $a_tpl_ctx_params, JSON_THROW_ON_ERROR)],
1012 $this->retrieveFromStage();
1019 $res = $this->db->queryF(
1020 "SELECT * FROM $this->table_mail_saved WHERE user_id = %s",
1025 $this->mail_data = $this->fetchMailData($this->db->fetchAssoc(
$res));
1026 if (!is_array($this->mail_data)) {
1027 $this->persistToStage($this->user_id,
'',
'',
'',
'',
'',
null,
false);
1030 return $this->mail_data;
1042 string $a_m_subject,
1043 string $a_m_message,
1044 array $a_attachment,
1045 bool $a_use_placeholders =
false
1050 $a_m_subject = $sanitizer->transform($a_m_subject);
1051 $a_m_message = $sanitizer->transform($a_m_message);
1054 'New mail system task:' .
1055 ' To: ' . $a_rcp_to .
1056 ' | CC: ' . $a_rcp_cc .
1057 ' | BCC: ' . $a_rcp_bcc .
1058 ' | Subject: ' . $a_m_subject .
1059 ' | Attachments: ' . print_r($a_attachment,
true)
1062 if ($a_attachment && !$this->mail_file_data->checkFilesExist($a_attachment)) {
1063 return [
new ilMailError(
'mail_attachment_file_not_exist', [implode(
', ', $a_attachment)])];
1066 $errors = $this->checkMail($a_rcp_to, $a_rcp_cc, $a_rcp_bcc, $a_m_subject);
1067 if ($errors !== []) {
1071 $errors = $this->validateRecipients($a_rcp_to, $a_rcp_cc, $a_rcp_bcc);
1072 if ($errors !== []) {
1076 $rcp_to = $a_rcp_to;
1077 $rcp_cc = $a_rcp_cc;
1078 $rcp_bcc = $a_rcp_bcc;
1080 $number_of_external_addresses = $this->getCountRecipients($rcp_to, $rcp_cc, $rcp_bcc);
1082 $number_of_external_addresses > 0 &&
1083 !$this->isSystemMail() &&
1084 !
$DIC->rbac()->system()->checkAccessOfUser($this->user_id,
'smtp_mail', $this->mail_obj_ref_id)
1086 return [
new ilMailError(
'mail_no_permissions_write_smtp')];
1089 if ($this->appendInstallationSignature()) {
1090 $a_m_message .= self::_getInstallationSignature();
1103 return $this->sendMail($mail_data);
1106 $task_factory =
$DIC->backgroundTasks()->taskFactory();
1107 $task_manager =
$DIC->backgroundTasks()->taskManager();
1110 $bucket->setUserId($this->user_id);
1112 $task = $task_factory->createTask(ilMailDeliveryJob::class, [
1119 serialize($a_attachment),
1120 $a_use_placeholders,
1121 $this->getSaveInSentbox(),
1122 (
string) $this->context_id,
1123 serialize(array_merge(
1124 $this->context_parameters,
1126 'auto_responder' => $this->auto_responder_service->isAutoresponderEnabled()
1130 $interaction = $task_factory->createTask(ilMailDeliveryJobUserInteraction::class, [
1135 $bucket->setTask($interaction);
1136 $bucket->setTitle($this->
lng->txt(
'mail_bg_task_title'));
1137 $bucket->setDescription(sprintf($this->
lng->txt(
'mail_bg_task_desc'), $a_m_subject));
1139 $this->
logger->info(
'Delegated delivery to background task');
1140 $task_manager->run($bucket);
1156 $internal_message_id = $this->saveInSentbox(
1157 $mail_data->getAttachments(),
1158 $mail_data->getTo(),
1159 $mail_data->getCc(),
1160 $mail_data->getBcc(),
1161 $mail_data->getSubject(),
1162 $mail_data->getMessage()
1167 $this->mail_file_data->assignAttachmentsToDirectory($internal_message_id, $internal_message_id);
1168 $this->mail_file_data->saveFiles($internal_message_id, $mail_data->
getAttachments());
1171 $num_external_email_addresses = $this->getCountRecipients(
1172 $mail_data->
getTo(),
1173 $mail_data->
getCc(),
1177 if ($num_external_email_addresses > 0) {
1178 $external_mail_recipients_to = $this->getEmailRecipients($mail_data->
getTo());
1179 $external_mail_recipients_cc = $this->getEmailRecipients($mail_data->
getCc());
1180 $external_eail_recipients_bcc = $this->getEmailRecipients($mail_data->
getBcc());
1183 'Parsed external email addresses from given recipients /' .
1184 ' To: ' . $external_mail_recipients_to .
1185 ' | CC: ' . $external_mail_recipients_cc .
1186 ' | BCC: ' . $external_eail_recipients_bcc .
1190 $this->sendMimeMail(
1191 $external_mail_recipients_to,
1192 $external_mail_recipients_cc,
1193 $external_eail_recipients_bcc,
1196 $this->replacePlaceholders($mail_data->
getMessage(), 0) :
1201 $this->
logger->debug(
'No external email addresses given in recipient string');
1205 if (!$this->distributeMail($mail_data)) {
1206 $errors[
'mail_send_error'] =
new ilMailError(
'mail_send_error');
1209 if (!$this->getSaveInSentbox()) {
1210 $this->deleteMails([$internal_message_id]);
1213 if ($this->isSystemMail()) {
1214 $random =
new Random\Randomizer();
1215 if ($random->getInt(0, 50) === 2) {
1218 $this->mail_file_data
1223 return array_values($errors);
1233 $errors = array_merge($errors, $this->checkRecipients($to));
1234 $errors = array_merge($errors, $this->checkRecipients($cc));
1235 $errors = array_merge($errors, $this->checkRecipients($bcc));
1237 if ($errors !== []) {
1238 return array_merge([
new ilMailError(
'mail_following_rcp_not_valid')], $errors);
1241 return [
new ilMailError(
'mail_generic_rcp_error', [
$e->getMessage()])];
1249 $send_folder_id = 0;
1250 if (!$this->isSystemMail()) {
1251 $send_folder_id = $this->mailbox->getSentFolder();
1254 return $send_folder_id;
1268 return $this->sendInternalMail(
1269 $this->getSubjectSentFolderId(),
1294 $mailer->
From($this->sender_factory->getSenderByUsrId($this->user_id));
1299 (
string) ($this->context_parameters[self::PROP_CONTEXT_SUBJECT_PREFIX] ??
'')
1302 if (!$this->isSystemMail()) {
1303 $message .= $this->signature_service->user($this->user_id);
1307 function (
string $message):
string {
1308 return $this->
refinery->string()->markdown()->toHTML()->
transform($message) ??
'';
1320 foreach ($attachments as $attachment) {
1322 $this->mail_file_data->getAbsoluteAttachmentPoolPathByFilename($attachment),
1334 if (!is_null($attachments)) {
1335 $attachments = $attachments->
serialize();
1339 $this->table_mail_saved,
1341 'attachments' => [
'text', $attachments],
1344 'user_id' => [
'integer', $this->user_id],
1355 if ($addresses !==
'') {
1356 $this->
logger->debug(sprintf(
1357 'Started parsing of recipient string: %s',
1362 $parser = $this->mail_address_parser_factory->getParser($addresses);
1363 $parsed_addresses = $parser->parse();
1365 if ($addresses !==
'') {
1366 $this->
logger->debug(sprintf(
1367 'Parsed addresses: %s',
1368 implode(
',', array_map(
static fn(
ilMailAddress $address):
string => (
string) $address, $parsed_addresses))
1372 return $parsed_addresses;
1378 if ($only_external_addresses) {
1382 $this->usr_id_by_login_callable
1386 return count($addresses->value());
1390 string $to_recipients,
1391 string $cc_recipients,
1392 string $bcc_recipients,
1393 bool $only_external_addresses =
true
1396 $this->getCountRecipient($to_recipients, $only_external_addresses) +
1397 $this->getCountRecipient($cc_recipients, $only_external_addresses) +
1398 $this->getCountRecipient($bcc_recipients, $only_external_addresses)
1407 $this->usr_id_by_login_callable
1410 $email_recipients = array_map(
static fn(
ilMailAddress $address):
string => (
string) $address, $addresses->value());
1412 return implode(
',', $email_recipients);
1423 $lang->loadLanguageModule(
'mail');
1426 $lang->txt(
'mail_auto_generated_info'),
1435 $sender_factory =
$DIC->mail()->mime()->senderFactory();
1437 return $sender_factory->system()->getFromName();
1445 if ($a_flag ===
null) {
1446 return $this->append_installation_signature;
1449 $this->append_installation_signature = $a_flag;
1456 return $DIC->mail()->signature()->installation();
1463 $lang = ($a_language instanceof
ilLanguage) ? $a_language :
$DIC->language();
1464 $lang->loadLanguageModule(
'mail');
1467 $gender = $gender ?:
'n';
1470 if ($name[
'firstname'] ===
'') {
1471 return $lang->txt(
'mail_salutation_anonymous') .
',';
1475 $lang->txt(
'mail_salutation_' . $gender) .
' ' .
1476 ($name[
'title'] ? $name[
'title'] .
' ' :
'') .
1477 ($name[
'firstname'] ? $name[
'firstname'] .
' ' :
'') .
1478 $name[
'lastname'] .
',';
1483 if (!array_key_exists($usr_id, $this->user_instances_by_id_map)) {
1486 }
catch (Exception) {
1490 $this->user_instances_by_id_map[$usr_id] = $user;
1493 return $this->user_instances_by_id_map[$usr_id];
1501 $this->user_instances_by_id_map = $user_instances_by_id_map;
1506 if (!isset($this->mail_options_by_usr_id_map[$usr_id])) {
1507 $this->mail_options_by_usr_id_map[$usr_id] =
new ilMailOptions($usr_id);
1510 return $this->mail_options_by_usr_id_map[$usr_id];
1518 $this->mail_options_by_usr_id_map = $mail_options_by_usr_id_map;
1525 $this->getUserInstanceById(
$user_id),
1526 $this->getMailOptionsByUserId(
$user_id),
1527 $this->legal_documents
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Class ResourceCollectionIdentification.
withInternalMailId(int $internal_mail_id)
static getType()
Get context type.
static _getLanguage(string $a_lang_key='')
Get language object.
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static getMailObjectRefId()
static getTemplateContextById(string $a_id)
static _getIliasMailerName()
sendMimeMail(string $to, string $cc, string $bcc, string $subject, string $message, array $attachments)
int $max_recipient_character_length
getCountRecipient(string $recipients, bool $only_external_addresses=true)
withContextParameters(array $parameters)
sendMailWithoutReplacedPlaceholder(MailDeliveryData $mail_data, array $to_usr_ids, array $cc_bcc_recipients)
deleteMails(array $mail_ids)
parseAddresses(string $addresses)
Explode recipient string, allowed separators are ',' ';' ' '.
getUserIds(array $recipients)
getUserInstanceById(int $usr_id)
moveMailsToFolder(array $mail_ids, int $folder_id)
checkRecipients(string $recipients)
array $context_parameters
markUnread(array $mail_ids)
readonly ILIAS Refinery Factory $refinery
array $mail_options_by_usr_id_map
const string PROP_CONTEXT_SUBJECT_PREFIX
array $user_instances_by_id_map
formatNamesForOutput(string $recipients)
getCountRecipients(string $to_recipients, string $cc_recipients, string $bcc_recipients, bool $only_external_addresses=true)
bool $append_installation_signature
sendMailWithReplacedPlaceholder(MailDeliveryData $mail_data, array $to_usr_ids)
scheduledMail(int $folder_id, int $sender_usr_id, MailScheduleData $mail_data, ?string $template_context_id=null, array $template_context_parameters=[])
sendMailWithReplacedEmptyPlaceholder(MailDeliveryData $mail_data, array $recipients,)
deleteMailsOfFolder(int $folder_id)
appendInstallationSignature(?bool $a_flag=null)
validateRecipients(string $to, string $cc, string $bcc)
readonly Conductor $legal_documents
setMailOptionsByUserIdMap(array $mail_options_by_usr_id_map)
static getSalutation(int $a_usr_id, ?ilLanguage $a_language=null)
distributeMail(MailDeliveryData $mail_data)
static _getInstallationSignature()
sendInternalMail(int $folder_id, int $sender_usr_id, array $attachments, string $to, string $cc, string $bcc, string $status, string $subject, string $message, int $usr_id=0, bool $use_placeholders=false, ?string $template_contenxt_id=null, array $template_context_parameters=[])
__construct(private int $a_user_id, private ?ilMailAddressTypeFactory $mail_address_type_factory=null, private ilMailRfc822AddressParserFactory $mail_address_parser_factory=new ilMailRfc822AddressParserFactory(), private ?ilAppEventHandler $event_handler=null, private ?ilLogger $logger=null, private ?ilDBInterface $db=null, private ?ilLanguage $lng=null, private ?ilFileDataMail $mail_file_data=null, protected ?ilMailOptions $mail_options=null, private ?ilMailbox $mailbox=null, private ?ilMailMimeSenderFactory $sender_factory=null, private ?Closure $usr_id_by_login_callable=null, private ?AutoresponderService $auto_responder_service=null, private ?int $mail_admin_node_ref_id=null, private ?int $mail_obj_ref_id=null, private ?ilObjUser $actor=null, private ?ilMailTemplatePlaceholderResolver $placeholder_resolver=null, private ?ilMailTemplatePlaceholderToEmptyResolver $placeholder_to_empty_resolver=null, ?Conductor $legal_documents=null, ?MailSignatureService $signature_service=null,)
sendChanneledMails(MailDeliveryData $mail_data, array $recipients, string $message)
saveInSentbox(array $attachment, string $to, string $cc, string $bcc, string $subject, string $message)
withContextId(string $context_id)
existsRecipient(string $new_recipient, string $existing_recipients)
replacePlaceholders(string $message, int $usr_id=0)
markRead(array $mail_ids)
countMailsOfFolder(int $folder_id)
setUserInstanceById(array $user_instances_by_id_map)
getMailsOfFolder(int $a_folder_id, array $filter=[])
getEmailRecipients(string $recipients)
delegateExternalEmails(string $subject, array $attachments, string $message, array $usr_id_to_external_email_addresses_map)
checkMail(string $to, string $cc, string $bcc, string $subject)
replacePlaceholdersEmpty(string $message)
static _getAutoGeneratedMessageString(?ilLanguage $lang=null)
createRecipient(int $user_id)
getMailObjectReferenceId()
getPreviousMail(int $mail_id)
bool $append_user_signature
readMailObjectReferenceId()
getNextMail(int $mail_id)
saveAttachments(?ResourceCollectionIdentification $attachments)
enqueue(string $a_rcp_to, string $a_rcp_cc, string $a_rcp_bcc, string $a_m_subject, string $a_m_message, array $a_attachment, bool $a_use_placeholders=false)
Should be used to enqueue a 'mail'.
persistToStage(int $a_user_id, string $a_rcp_to, string $a_rcp_cc, string $a_rcp_bcc, string $a_m_subject, string $a_m_message, ?\ILIAS\ResourceStorage\Identification\ResourceCollectionIdentification $a_attachments=null, bool $a_use_placeholders=false, ?string $a_tpl_context_id=null, ?array $a_tpl_ctx_params=[])
updateDraft(int $a_folder_id, array $a_attachments, string $a_rcp_to, string $a_rcp_cc, string $a_rcp_bcc, string $a_m_subject, string $a_m_message, int $a_draft_id=0, ?DateTimeImmutable $schedule_time=null, bool $a_use_placeholders=false, ?string $a_tpl_context_id=null, array $a_tpl_context_params=[])
setSaveInSentbox(bool $save_in_sentbox)
fetchMailData(?array $row)
getNewDraftId(int $folder_id)
getMailOptionsByUserId(int $usr_id)
MailSignatureService $signature_service
sendMail(MailDeliveryData $mail_data)
This method is used to finally send internal messages and external emails To use the mail system as a...
From(ilMailMimeSender $sender)
static _lookupName(int $a_user_id)
static _lookupId(string|array $a_user_str)
static _lookupPref(int $a_usr_id, string $a_keyword)
static _lookupGender(int $a_user_id)
static strLen(string $a_string)
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const ILIAS_VERSION_NUMERIC
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
if(!file_exists('../ilias.ini.php'))