ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilMail.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27
28class ilMail
29{
30 public const string ILIAS_HOST = 'ilias';
31 public const string PROP_CONTEXT_SUBJECT_PREFIX = 'subject_prefix';
32
34 public int $user_id;
35 private string $table_mail;
36 private string $table_mail_saved;
38 protected ?array $mail_data = [];
39 private bool $save_in_sentbox;
40 private bool $append_installation_signature = false;
41 private bool $append_user_signature = false;
42
43 private ?string $context_id = null;
44 private array $context_parameters = [];
45
47 private array $mail_options_by_usr_id_map = [];
48
50 private array $user_instances_by_id_map = [];
52 private readonly Conductor $legal_documents;
53
54 public function __construct(
55 private int $a_user_id,
56 private ?ilMailAddressTypeFactory $mail_address_type_factory = null,
57 private ilMailRfc822AddressParserFactory $mail_address_parser_factory = new ilMailRfc822AddressParserFactory(),
58 private ?ilAppEventHandler $event_handler = null,
59 private ?ilLogger $logger = null,
60 private ?ilDBInterface $db = null,
61 private ?ilLanguage $lng = null,
62 private ?ilFileDataMail $mail_file_data = null,
63 protected ?ilMailOptions $mail_options = null,
64 private ?ilMailbox $mailbox = null,
65 private ?ilMailMimeSenderFactory $sender_factory = null,
66 private ?Closure $usr_id_by_login_callable = null,
67 private ?AutoresponderService $auto_responder_service = null,
68 private ?int $mail_admin_node_ref_id = null,
69 private ?int $mail_obj_ref_id = null,
70 private ?ilObjUser $actor = null,
71 private ?ilMailTemplatePlaceholderResolver $placeholder_resolver = null,
72 private ?ilMailTemplatePlaceholderToEmptyResolver $placeholder_to_empty_resolver = null,
75 ) {
76 global $DIC;
77 $this->logger = $logger ?? ilLoggerFactory::getLogger('mail');
78 $this->mail_address_type_factory = $mail_address_type_factory ?? new ilMailAddressTypeFactory(null, $logger);
79 $this->event_handler = $event_handler ?? $DIC->event();
80 $this->db = $db ?? $DIC->database();
81 $this->lng = $lng ?? $DIC->language();
82 $this->actor = $actor ?? $DIC->user();
83 $this->mail_file_data = $mail_file_data ?? new ilFileDataMail($a_user_id);
84 $this->mail_options = $mail_options ?? new ilMailOptions($a_user_id);
85 $this->mailbox = $mailbox ?? new ilMailbox($a_user_id);
86
87 $this->sender_factory = $sender_factory ?? $DIC->mail()->mime()->senderFactory();
88 $this->usr_id_by_login_callable = $usr_id_by_login_callable ?? (static fn(string $login): int => (int) ilObjUser::_lookupId($login));
89 $this->auto_responder_service = $auto_responder_service ?? $DIC->mail()->autoresponder();
90 $this->user_id = $a_user_id;
91 if ($this->mail_obj_ref_id === null) {
93 }
94 $this->lng->loadLanguageModule('mail');
95 $this->table_mail = 'mail';
96 $this->table_mail_saved = 'mail_saved';
97 $this->setSaveInSentbox(false);
98 $this->placeholder_resolver = $placeholder_resolver ?? $DIC->mail()->placeholderResolver();
99 $this->placeholder_to_empty_resolver = $placeholder_to_empty_resolver ?? $DIC->mail()->placeholderToEmptyResolver();
100 $this->legal_documents = $legal_documents ?? $DIC['legalDocuments'];
101 $this->signature_service = $signature_service ?? $DIC->mail()->signature();
102 }
103
105 {
106 return $this->auto_responder_service;
107 }
108
109 public function withContextId(string $context_id): self
110 {
111 $clone = clone $this;
112
113 $clone->context_id = $context_id;
114
115 return $clone;
116 }
117
118 public function withContextParameters(array $parameters): self
119 {
120 $clone = clone $this;
121
122 $clone->context_parameters = $parameters;
123
124 return $clone;
125 }
126
127 private function isSystemMail(): bool
128 {
129 return $this->user_id === ANONYMOUS_USER_ID;
130 }
131
132 public function existsRecipient(string $new_recipient, string $existing_recipients): bool
133 {
134 $new_addresses = new ilMailAddressListImpl($this->parseAddresses($new_recipient));
135 $addresses = new ilMailAddressListImpl($this->parseAddresses($existing_recipients));
136 $list = new ilMailDiffAddressList($new_addresses, $addresses);
137
138 $diffed_addresses = $list->value();
139
140 return $diffed_addresses === [];
141 }
142
143 public function setSaveInSentbox(bool $save_in_sentbox): void
144 {
145 $this->save_in_sentbox = $save_in_sentbox;
146 }
147
148 public function getSaveInSentbox(): bool
149 {
151 }
152
153 private function readMailObjectReferenceId(): void
154 {
155 $this->mail_obj_ref_id = ilMailGlobalServices::getMailObjectRefId();
156 }
157
158 public function getMailObjectReferenceId(): int
159 {
160 return $this->mail_obj_ref_id;
161 }
162
163 public function formatNamesForOutput(string $recipients): string
164 {
165 $recipients = trim($recipients);
166 if ($recipients === '') {
167 return $this->lng->txt('not_available');
168 }
169
170 $names = [];
171
172 $recipients = array_filter(array_map('trim', explode(',', $recipients)));
173 foreach ($recipients as $recipient) {
174 $usr_id = ilObjUser::_lookupId($recipient);
175 if (is_int($usr_id) && $usr_id > 0) {
176 $pp = ilObjUser::_lookupPref($usr_id, 'public_profile');
177 if ($pp === 'g' || ($pp === 'y' && !$this->actor->isAnonymous())) {
178 $user = $this->getUserInstanceById($usr_id);
179 if ($user) {
180 $names[] = $user->getFullname() . ' [' . $recipient . ']';
181 continue;
182 }
183 }
184 }
185
186 $names[] = $recipient;
187 }
188
189 return implode(', ', $names);
190 }
191
192 public function getPreviousMail(int $mail_id): ?array
193 {
194 $this->db->setLimit(1, 0);
195
196 $query = implode(' ', [
197 "SELECT b.* FROM $this->table_mail a",
198 "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
199 'AND b.user_id = a.user_id AND b.send_time > a.send_time',
200 'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time ASC',
201 ]);
202 $res = $this->db->queryF(
203 $query,
204 ['integer', 'integer'],
205 [$this->user_id, $mail_id]
206 );
207
208 $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
209
210 return $this->mail_data;
211 }
212
213 public function getNextMail(int $mail_id): ?array
214 {
215 $this->db->setLimit(1, 0);
216
217 $query = implode(' ', [
218 "SELECT b.* FROM $this->table_mail a",
219 "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
220 'AND b.user_id = a.user_id AND b.send_time < a.send_time',
221 'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time DESC',
222 ]);
223 $res = $this->db->queryF(
224 $query,
225 ['integer', 'integer'],
226 [$this->user_id, $mail_id]
227 );
228
229 $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
230
231 return $this->mail_data;
232 }
233
234 public function getMailsOfFolder(int $a_folder_id, array $filter = []): array
235 {
236 $mails = [];
237
238 $query =
239 'SELECT sender_id, m_subject, mail_id, m_status, send_time, import_name ' .
240 "FROM $this->table_mail " .
241 'LEFT JOIN object_data ON obj_id = sender_id ' .
242 'WHERE user_id = %s AND folder_id = %s ' .
243 'AND ((sender_id > 0 AND sender_id IS NOT NULL AND obj_id IS NOT NULL) ' .
244 'OR (sender_id = 0 OR sender_id IS NULL))';
245
246 if (isset($filter['status']) && $filter['status'] !== '') {
247 $query .= ' AND m_status = ' . $this->db->quote($filter['status'], 'text');
248 }
249
250 $query .= ' ORDER BY send_time DESC';
251
252 $res = $this->db->queryF(
253 $query,
254 ['integer', 'integer'],
255 [$this->user_id, $a_folder_id]
256 );
257
258 while ($row = $this->db->fetchAssoc($res)) {
259 $mails[] = $this->fetchMailData($row);
260 }
261
262 return array_filter($mails);
263 }
264
265 public function countMailsOfFolder(int $folder_id): int
266 {
267 $res = $this->db->queryF(
268 "SELECT COUNT(*) FROM $this->table_mail WHERE user_id = %s AND folder_id = %s",
269 ['integer', 'integer'],
270 [$this->user_id, $folder_id]
271 );
272
273 return $this->db->numRows($res);
274 }
275
276 public function deleteMailsOfFolder(int $folder_id): void
277 {
278 $mails = $this->getMailsOfFolder($folder_id);
279 foreach ($mails as $mail_data) {
280 $this->deleteMails([$mail_data['mail_id']]);
281 }
282 }
283
284 public function getMail(int $mail_id): ?array
285 {
286 $res = $this->db->queryF(
287 "SELECT * FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
288 ['integer', 'integer'],
289 [$this->user_id, $mail_id]
290 );
291
292 $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
293
294 return $this->mail_data;
295 }
296
300 public function markRead(array $mail_ids): void
301 {
302 $values = [];
303 $types = [];
304
305 $query = "UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
306 $types[] = 'text';
307 $types[] = 'integer';
308 $values[] = 'read';
309 $values[] = $this->user_id;
310
311 if ($mail_ids !== []) {
312 $query .= ' AND ' . $this->db->in('mail_id', $mail_ids, false, 'integer');
313 }
314
315 $this->db->manipulateF($query, $types, $values);
316 }
317
321 public function markUnread(array $mail_ids): void
322 {
323 $values = [];
324 $types = [];
325
326 $query = "UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
327 $types[] = 'text';
328 $types[] = 'integer';
329 $values[] = 'unread';
330 $values[] = $this->user_id;
331
332 if ($mail_ids !== []) {
333 $query .= ' AND ' . $this->db->in('mail_id', $mail_ids, false, 'integer');
334 }
335
336 $this->db->manipulateF($query, $types, $values);
337 }
338
342 public function moveMailsToFolder(array $mail_ids, int $folder_id): bool
343 {
344 $values = [];
345 $types = [];
346
347 $mail_ids = array_filter(array_map(intval(...), $mail_ids));
348
349 if ([] === $mail_ids) {
350 return false;
351 }
352
353 $query =
354 "UPDATE $this->table_mail " .
355 'INNER JOIN mail_obj_data ' .
356 'ON mail_obj_data.obj_id = %s AND mail_obj_data.user_id = %s ' .
357 "SET $this->table_mail.folder_id = mail_obj_data.obj_id " .
358 "WHERE $this->table_mail.user_id = %s";
359 $types[] = 'integer';
360 $types[] = 'integer';
361 $types[] = 'integer';
362 $values[] = $folder_id;
363 $values[] = $this->user_id;
364 $values[] = $this->user_id;
365
366 $query .= ' AND ' . $this->db->in('mail_id', $mail_ids, false, 'integer');
367
368 $affected_rows = $this->db->manipulateF($query, $types, $values);
369
370 return $affected_rows > 0;
371 }
372
376 public function deleteMails(array $mail_ids): void
377 {
378 $mail_ids = array_filter(array_map('intval', $mail_ids));
379 foreach ($mail_ids as $id) {
380 $this->db->manipulateF(
381 "DELETE FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
382 ['integer', 'integer'],
383 [$this->user_id, $id]
384 );
385 $this->mail_file_data->deassignAttachmentFromDirectory($id);
386 }
387 }
388
389 private function fetchMailData(?array $row): ?array
390 {
391 if (!is_array($row) || empty($row)) {
392 return null;
393 }
394
395 if (isset($row['attachments'])) {
396 $unserialized = unserialize(stripslashes((string) $row['attachments']), ['allowed_classes' => false]);
397 $row['attachments'] = is_array($unserialized) ? $unserialized : [];
398 } else {
399 $row['attachments'] = [];
400 }
401
402 if (isset($row['tpl_ctx_params']) && is_string($row['tpl_ctx_params'])) {
403 $decoded = json_decode($row['tpl_ctx_params'], true, 512, JSON_THROW_ON_ERROR);
404 $row['tpl_ctx_params'] = (array) ($decoded ?? []);
405 } else {
406 $row['tpl_ctx_params'] = [];
407 }
408
409 if (isset($row['mail_id'])) {
410 $row['mail_id'] = (int) $row['mail_id'];
411 }
412
413 if (isset($row['user_id'])) {
414 $row['user_id'] = (int) $row['user_id'];
415 }
416
417 if (isset($row['folder_id'])) {
418 $row['folder_id'] = (int) $row['folder_id'];
419 }
420
421 if (isset($row['sender_id'])) {
422 $row['sender_id'] = (int) $row['sender_id'];
423 }
424
425 if (isset($row['use_placeholders'])) {
426 $row['use_placeholders'] = (bool) $row['use_placeholders'];
427 }
428
429 $null_to_string_properties = ['m_subject', 'm_message', 'rcp_to', 'rcp_cc', 'rcp_bcc'];
430 foreach ($null_to_string_properties as $null_to_string_property) {
431 if (!isset($row[$null_to_string_property])) {
432 $row[$null_to_string_property] = '';
433 }
434 }
435
436 return $row;
437 }
438
439 public function getNewDraftId(int $folder_id): int
440 {
441 $next_id = $this->db->nextId($this->table_mail);
442 $this->db->insert($this->table_mail, [
443 'mail_id' => ['integer', $next_id],
444 'user_id' => ['integer', $this->user_id],
445 'folder_id' => ['integer', $folder_id],
446 'sender_id' => ['integer', $this->user_id],
447 ]);
448
449 return $next_id;
450 }
451
455 public function updateDraft(
456 int $a_folder_id,
457 array $a_attachments,
458 string $a_rcp_to,
459 string $a_rcp_cc,
460 string $a_rcp_bcc,
461 string $a_m_subject,
462 string $a_m_message,
463 int $a_draft_id = 0,
464 bool $a_use_placeholders = false,
465 ?string $a_tpl_context_id = null,
466 array $a_tpl_context_params = []
467 ): int {
468 $this->db->update(
469 $this->table_mail,
470 [
471 'folder_id' => ['integer', $a_folder_id],
472 'attachments' => ['clob', serialize($a_attachments)],
473 'send_time' => ['timestamp', date('Y-m-d H:i:s')],
474 'rcp_to' => ['clob', $a_rcp_to],
475 'rcp_cc' => ['clob', $a_rcp_cc],
476 'rcp_bcc' => ['clob', $a_rcp_bcc],
477 'm_status' => ['text', 'read'],
478 'm_subject' => ['text', $a_m_subject],
479 'm_message' => ['clob', $a_m_message],
480 'use_placeholders' => ['integer', (int) $a_use_placeholders],
481 'tpl_ctx_id' => ['text', $a_tpl_context_id],
482 'tpl_ctx_params' => ['blob', json_encode($a_tpl_context_params, JSON_THROW_ON_ERROR)],
483 ],
484 [
485 'mail_id' => ['integer', $a_draft_id],
486 ]
487 );
488
489 return $a_draft_id;
490 }
491
492 private function sendInternalMail(
493 int $folder_id,
494 int $sender_usr_id,
495 array $attachments,
496 string $to,
497 string $cc,
498 string $bcc,
499 string $status,
500 string $subject,
501 string $message,
502 int $usr_id = 0,
503 bool $use_placeholders = false,
504 ?string $template_contenxt_id = null,
505 array $template_context_parameters = []
506 ): int {
507 $usr_id = $usr_id ?: $this->user_id;
508
509 if ($use_placeholders) {
510 $message = $this->replacePlaceholders($message, $usr_id);
511 }
512 $message = str_ireplace(['<br />', '<br>', '<br/>'], "\n", $message);
513
514 $next_id = $this->db->nextId($this->table_mail);
515 $this->db->insert($this->table_mail, [
516 'mail_id' => ['integer', $next_id],
517 'user_id' => ['integer', $usr_id],
518 'folder_id' => ['integer', $folder_id],
519 'sender_id' => ['integer', $sender_usr_id],
520 'attachments' => ['clob', serialize($attachments)],
521 'send_time' => ['timestamp', date('Y-m-d H:i:s')],
522 'rcp_to' => ['clob', $to],
523 'rcp_cc' => ['clob', $cc],
524 'rcp_bcc' => ['clob', $bcc],
525 'm_status' => ['text', $status],
526 'm_subject' => ['text', $subject],
527 'm_message' => ['clob', $message],
528 'tpl_ctx_id' => ['text', $template_contenxt_id],
529 'tpl_ctx_params' => ['blob', json_encode($template_context_parameters, JSON_THROW_ON_ERROR)],
530 ]);
531
532 $sender_equals_reveiver = $usr_id === $this->mailbox->getUsrId();
533 $is_sent_folder_of_sender = false;
534 if ($sender_equals_reveiver) {
535 $current_folder_id = $this->getSubjectSentFolderId();
536 $is_sent_folder_of_sender = $folder_id === $current_folder_id;
537 }
538
539 $raise_event = !$sender_equals_reveiver || !$is_sent_folder_of_sender;
540
541 if ($raise_event) {
542 $this->event_handler->raise('components/ILIAS/Mail', 'sentInternalMail', [
543 'id' => $next_id,
544 'subject' => $subject,
545 'body' => $message,
546 'from_usr_id' => $sender_usr_id,
547 'to_usr_id' => $usr_id,
548 'rcp_to' => $to,
549 'rcp_cc' => $cc,
550 'rcp_bcc' => $bcc,
551 ]);
552 }
553
554 return $next_id;
555 }
556
557 private function replacePlaceholders(
558 string $message,
559 int $usr_id = 0
560 ): string {
561 try {
562 if ($this->context_id) {
564 } else {
566 }
567
568 $user = $usr_id > 0 ? $this->getUserInstanceById($usr_id) : null;
569 $message = $this->placeholder_resolver->resolve(
570 $context,
571 $message,
572 $user,
573 $this->context_parameters
574 );
575 } catch (Exception $e) {
576 $this->logger->error(sprintf(
577 '%s has been called with invalid context: %s / %s',
578 __METHOD__,
579 $e->getMessage(),
580 $e->getTraceAsString()
581 ));
582 }
583
584 return $message;
585 }
586
587 private function replacePlaceholdersEmpty(string $message): string
588 {
589 return $this->placeholder_to_empty_resolver->resolve($message);
590 }
591
592 private function distributeMail(MailDeliveryData $mail_data): bool
593 {
594 $this->auto_responder_service->emptyAutoresponderData();
595 $to_usr_ids = $this->getUserIds([$mail_data->getTo()]);
596 $this->logger->debug(sprintf(
597 'Parsed TO user ids from given recipients for serial letter notification: %s',
598 implode(', ', $to_usr_ids)
599 ));
600
601 $other_usr_ids = $this->getUserIds([$mail_data->getCc(), $mail_data->getBcc()]);
602 $cc_bcc_recipients = array_map(
603 $this->createRecipient(...),
604 $other_usr_ids
605 );
606 $this->logger->debug(sprintf(
607 'Parsed CC/BCC user ids from given recipients for serial letter notification: %s',
608 implode(', ', $other_usr_ids)
609 ));
610
611 if ($mail_data->isUsePlaceholder()) {
612 $this->sendMailWithReplacedPlaceholder($mail_data, $to_usr_ids);
613 $this->sendMailWithReplacedEmptyPlaceholder($mail_data, $cc_bcc_recipients);
614 } else {
615 $this->sendMailWithoutReplacedPlaceholder($mail_data, $to_usr_ids, $cc_bcc_recipients);
616 }
617
618 $this->auto_responder_service->disableAutoresponder();
619 $this->auto_responder_service->handleAutoresponderMails($this->user_id);
620
621 return true;
622 }
623
628 MailDeliveryData $mail_data,
629 array $to_usr_ids
630 ): void {
631 foreach ($to_usr_ids as $user_id) {
632 $recipient = $this->createRecipient($user_id);
633
634 $this->sendChanneledMails(
635 $mail_data,
636 [$recipient],
637 $this->replacePlaceholders($mail_data->getMessage(), $user_id),
638 );
639 }
640 }
641
646 MailDeliveryData $mail_data,
647 array $recipients,
648 ): void {
649 $this->sendChanneledMails(
650 $mail_data,
651 $recipients,
652 $this->replacePlaceholdersEmpty($mail_data->getMessage()),
653 );
654 }
655
661 MailDeliveryData $mail_data,
662 array $to_usr_ids,
663 array $cc_bcc_recipients
664 ): void {
665 $to_recipients = array_map(
666 $this->createRecipient(...),
667 $to_usr_ids
668 );
669
670 $this->sendChanneledMails(
671 $mail_data,
672 array_merge($to_recipients, $cc_bcc_recipients),
673 $mail_data->getMessage()
674 );
675 }
676
680 private function sendChanneledMails(
681 MailDeliveryData $mail_data,
682 array $recipients,
683 string $message
684 ): void {
685 $usr_id_to_external_email_addresses_map = [];
686
687 foreach ($recipients as $recipient) {
688 if (!$recipient->isUser()) {
689 $this->logger->critical(sprintf(
690 'Skipped recipient with id %s (User not found)',
691 $recipient->getUserId()
692 ));
693 continue;
694 }
695
696 $can_read_internal = $recipient->evaluateInternalMailReadability();
697 if ($this->isSystemMail() && !$can_read_internal->isOk()) {
698 $this->logger->debug(sprintf(
699 'Skipped recipient with id %s and reason: %s',
700 $recipient->getUserId(),
701 is_string($can_read_internal->error()) ? $can_read_internal->error() : $can_read_internal->error()->getMessage()
702 ));
703 continue;
704 }
705
706 if ($recipient->isUserActive() && !$recipient->isUserExpired()) {
707 if (!$can_read_internal->isOk() || $recipient->userWantsToReceiveExternalMails()) {
708 $email_addresses = $recipient->getExternalMailAddress();
709 $usr_id_to_external_email_addresses_map[$recipient->getUserId()] = $email_addresses;
710
711 if ($recipient->onlyToExternalMailAddress()) {
712 $this->logger->debug(sprintf(
713 'Recipient with id %s will only receive external emails sent to: %s',
714 $recipient->getUserId(),
715 implode(', ', $email_addresses)
716 ));
717 continue;
718 }
719
720 $this->logger->debug(sprintf(
721 'Recipient with id %s will additionally receive external emails ' .
722 '(because the user wants to receive it externally, or the user cannot did not accept ' .
723 'the legal documents) sent to: %s',
724 $recipient->getUserId(),
725 implode(', ', $email_addresses)
726 ));
727 } else {
728 $this->logger->debug(sprintf(
729 'Recipient with id %s does not want to receive external emails',
730 $recipient->getUserId()
731 ));
732 }
733 } else {
734 $this->logger->debug(sprintf(
735 'Recipient with id %s is inactive or expired and will not receive external emails',
736 $recipient->getUserId()
737 ));
738 }
739
740 $mbox = clone $this->mailbox;
741 $mbox->setUsrId($recipient->getUserId());
742 $recipient_inbox_id = $mbox->getInboxFolder();
743
744 $internal_mail_id = $this->sendInternalMail(
745 $recipient_inbox_id,
746 $this->user_id,
747 $mail_data->getAttachments(),
748 $mail_data->getTo(),
749 $mail_data->getCc(),
750 '',
751 'unread',
752 $mail_data->getSubject(),
753 $message,
754 $recipient->getUserId()
755 );
756
757 $this->auto_responder_service->enqueueAutoresponderIfEnabled(
758 $recipient->getUserId(),
759 $recipient->getMailOptions(),
760 $this->getMailOptionsByUserId($this->user_id),
761 );
762
763 if ($mail_data->getAttachments() !== []) {
764 $this->mail_file_data->assignAttachmentsToDirectory($internal_mail_id, $mail_data->getInternalMailId());
765 }
766 }
767
768 $this->delegateExternalEmails(
769 $mail_data->getSubject(),
770 $mail_data->getAttachments(),
771 $message,
772 $usr_id_to_external_email_addresses_map
773 );
774 }
775
780 private function delegateExternalEmails(
781 string $subject,
782 array $attachments,
783 string $message,
784 array $usr_id_to_external_email_addresses_map
785 ): void {
786 if (count($usr_id_to_external_email_addresses_map) === 1) {
787 $usr_id_to_external_email_addresses_map = array_values($usr_id_to_external_email_addresses_map);
788 $first_addresses = current($usr_id_to_external_email_addresses_map);
789
790 $this->sendMimeMail(
791 implode(',', $first_addresses),
792 '',
793 '',
794 $subject,
795 $message,
796 $attachments
797 );
798 } elseif (count($usr_id_to_external_email_addresses_map) > 1) {
799 $flattened_email_addresses = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator(
800 $usr_id_to_external_email_addresses_map
801 )), false);
802
803 $flattened_email_addresses = array_unique($flattened_email_addresses);
804
805 // https://mantis.ilias.de/view.php?id=23981 and https://www.ietf.org/rfc/rfc2822.txt
806 $remaining_addresses = '';
807 foreach ($flattened_email_addresses as $email_address) {
808 $sep = '';
809 if ($remaining_addresses !== '') {
810 $sep = ',';
811 }
812
813 $recipients_line_length = ilStr::strLen($remaining_addresses) +
814 ilStr::strLen($sep . $email_address);
815 if ($recipients_line_length >= $this->max_recipient_character_length) {
816 $this->sendMimeMail(
817 '',
818 '',
819 $remaining_addresses,
820 $subject,
821 $message,
822 $attachments
823 );
824
825 $remaining_addresses = '';
826 $sep = '';
827 }
828
829 $remaining_addresses .= ($sep . $email_address);
830 }
831
832 if ($remaining_addresses !== '') {
833 $this->sendMimeMail(
834 '',
835 '',
836 $remaining_addresses,
837 $subject,
838 $message,
839 $attachments
840 );
841 }
842 }
843 }
844
849 private function getUserIds(array $recipients): array
850 {
851 $parsed_usr_ids = [];
852
853 $joined_recipients = implode(',', array_filter(array_map('trim', $recipients)));
854
855 $addresses = $this->parseAddresses($joined_recipients);
856 foreach ($addresses as $address) {
857 $address_type = $this->mail_address_type_factory->getByPrefix($address);
858 $parsed_usr_ids[] = $address_type->resolve();
859 }
860
861 return array_unique(array_merge(...$parsed_usr_ids));
862 }
863
867 private function checkMail(string $to, string $cc, string $bcc, string $subject): array
868 {
869 $errors = [];
870
871 $checks = [
872 $subject => 'mail_add_subject',
873 $to => 'mail_add_recipient',
874 ];
875 foreach ($checks as $string => $error) {
876 if ($string === '') {
877 $errors[] = new ilMailError($error);
878 }
879 }
880
881 if (ilStr::strLen($subject) > 255) {
882 // https://mantis.ilias.de/view.php?id=37881
883 $errors[] = new ilMailError('mail_subject_too_long');
884 }
885
886 return $errors;
887 }
888
892 private function checkRecipients(string $recipients): array
893 {
894 $errors = [];
895
896 try {
897 $addresses = $this->parseAddresses($recipients);
898 foreach ($addresses as $address) {
899 $address_type = $this->mail_address_type_factory->getByPrefix($address);
900 if (!$address_type->validate($this->user_id)) {
901 $errors[] = $address_type->getErrors();
902 }
903 }
904 } catch (Exception $e) {
905 $position = strpos($e->getMessage(), ':');
906 throw new ilMailException(
907 ($position === false) ? $e->getMessage() : substr($e->getMessage(), $position + 2),
908 $e->getCode(),
909 $e
910 );
911 }
912
913 return array_merge(...$errors);
914 }
915
919 public function persistToStage(
920 int $a_user_id,
921 array $a_attachments,
922 string $a_rcp_to,
923 string $a_rcp_cc,
924 string $a_rcp_bcc,
925 string $a_m_subject,
926 string $a_m_message,
927 bool $a_use_placeholders = false,
928 ?string $a_tpl_context_id = null,
929 ?array $a_tpl_ctx_params = []
930 ): bool {
931 $this->db->replace(
932 $this->table_mail_saved,
933 [
934 'user_id' => ['integer', $this->user_id],
935 ],
936 [
937 'attachments' => ['clob', serialize($a_attachments)],
938 'rcp_to' => ['clob', $a_rcp_to],
939 'rcp_cc' => ['clob', $a_rcp_cc],
940 'rcp_bcc' => ['clob', $a_rcp_bcc],
941 'm_subject' => ['text', $a_m_subject],
942 'm_message' => ['clob', $a_m_message],
943 'use_placeholders' => ['integer', (int) $a_use_placeholders],
944 'tpl_ctx_id' => ['text', $a_tpl_context_id],
945 'tpl_ctx_params' => ['blob', json_encode((array) $a_tpl_ctx_params, JSON_THROW_ON_ERROR)],
946 ]
947 );
948
949 $this->retrieveFromStage();
950
951 return true;
952 }
953
954 public function retrieveFromStage(): array
955 {
956 $res = $this->db->queryF(
957 "SELECT * FROM $this->table_mail_saved WHERE user_id = %s",
958 ['integer'],
959 [$this->user_id]
960 );
961
962 $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
963 if (!is_array($this->mail_data)) {
964 $this->persistToStage($this->user_id, [], '', '', '', '', '', false);
965 }
966
967 return $this->mail_data;
968 }
969
975 public function enqueue(
976 string $a_rcp_to,
977 string $a_rcp_cc,
978 string $a_rcp_bcc,
979 string $a_m_subject,
980 string $a_m_message,
981 array $a_attachment,
982 bool $a_use_placeholders = false
983 ): array {
984 global $DIC;
985
986 $sanitizeMb4Encoding = new Utf8Mb4Sanitizer();
987 $a_m_subject = $sanitizeMb4Encoding->transform($a_m_subject);
988 $a_m_message = $sanitizeMb4Encoding->transform($a_m_message);
989
990 $this->logger->info(
991 'New mail system task:' .
992 ' To: ' . $a_rcp_to .
993 ' | CC: ' . $a_rcp_cc .
994 ' | BCC: ' . $a_rcp_bcc .
995 ' | Subject: ' . $a_m_subject .
996 ' | Attachments: ' . print_r($a_attachment, true)
997 );
998
999 if ($a_attachment && !$this->mail_file_data->checkFilesExist($a_attachment)) {
1000 return [new ilMailError('mail_attachment_file_not_exist', [implode(', ', $a_attachment)])];
1001 }
1002
1003 $errors = $this->checkMail($a_rcp_to, $a_rcp_cc, $a_rcp_bcc, $a_m_subject);
1004 if ($errors !== []) {
1005 return $errors;
1006 }
1007
1008 $errors = $this->validateRecipients($a_rcp_to, $a_rcp_cc, $a_rcp_bcc);
1009 if ($errors !== []) {
1010 return $errors;
1011 }
1012
1013 $rcp_to = $a_rcp_to;
1014 $rcp_cc = $a_rcp_cc;
1015 $rcp_bcc = $a_rcp_bcc;
1016
1017 $number_of_external_addresses = $this->getCountRecipients($rcp_to, $rcp_cc, $rcp_bcc);
1018 if (
1019 $number_of_external_addresses > 0 &&
1020 !$this->isSystemMail() &&
1021 !$DIC->rbac()->system()->checkAccessOfUser($this->user_id, 'smtp_mail', $this->mail_obj_ref_id)
1022 ) {
1023 return [new ilMailError('mail_no_permissions_write_smtp')];
1024 }
1025
1026 if ($this->appendInstallationSignature()) {
1027 $a_m_message .= self::_getInstallationSignature();
1028 }
1029
1031 $mail_data = new MailDeliveryData(
1032 $rcp_to,
1033 $rcp_cc,
1034 $rcp_bcc,
1035 $a_m_subject,
1036 $a_m_message,
1037 $a_attachment,
1038 $a_use_placeholders
1039 );
1040 return $this->sendMail($mail_data);
1041 }
1042
1043 $task_factory = $DIC->backgroundTasks()->taskFactory();
1044 $task_manager = $DIC->backgroundTasks()->taskManager();
1045
1046 $bucket = new BasicBucket();
1047 $bucket->setUserId($this->user_id);
1048
1049 $task = $task_factory->createTask(ilMailDeliveryJob::class, [
1050 $this->user_id,
1051 $rcp_to,
1052 $rcp_cc,
1053 $rcp_bcc,
1054 $a_m_subject,
1055 $a_m_message,
1056 serialize($a_attachment),
1057 $a_use_placeholders,
1058 $this->getSaveInSentbox(),
1059 (string) $this->context_id,
1060 serialize(array_merge(
1061 $this->context_parameters,
1062 [
1063 'auto_responder' => $this->auto_responder_service->isAutoresponderEnabled()
1064 ]
1065 ))
1066 ]);
1067 $interaction = $task_factory->createTask(ilMailDeliveryJobUserInteraction::class, [
1068 $task,
1069 $this->user_id,
1070 ]);
1071
1072 $bucket->setTask($interaction);
1073 $bucket->setTitle($this->lng->txt('mail_bg_task_title'));
1074 $bucket->setDescription(sprintf($this->lng->txt('mail_bg_task_desc'), $a_m_subject));
1075
1076 $this->logger->info('Delegated delivery to background task');
1077 $task_manager->run($bucket);
1078
1079 return [];
1080 }
1081
1090 public function sendMail(
1091 MailDeliveryData $mail_data
1092 ): array {
1093 $internal_message_id = $this->saveInSentbox(
1094 $mail_data->getAttachments(),
1095 $mail_data->getTo(),
1096 $mail_data->getCc(),
1097 $mail_data->getBcc(),
1098 $mail_data->getSubject(),
1099 $mail_data->getMessage()
1100 );
1101 $mail_data = $mail_data->withInternalMailId($internal_message_id);
1102
1103 if ($mail_data->getAttachments() !== []) {
1104 $this->mail_file_data->assignAttachmentsToDirectory($internal_message_id, $internal_message_id);
1105 $this->mail_file_data->saveFiles($internal_message_id, $mail_data->getAttachments());
1106 }
1107
1108 $num_external_email_addresses = $this->getCountRecipients(
1109 $mail_data->getTo(),
1110 $mail_data->getCc(),
1111 $mail_data->getBcc()
1112 );
1113
1114 if ($num_external_email_addresses > 0) {
1115 $external_mail_recipients_to = $this->getEmailRecipients($mail_data->getTo());
1116 $external_mail_recipients_cc = $this->getEmailRecipients($mail_data->getCc());
1117 $external_eail_recipients_bcc = $this->getEmailRecipients($mail_data->getBcc());
1118
1119 $this->logger->debug(
1120 'Parsed external email addresses from given recipients /' .
1121 ' To: ' . $external_mail_recipients_to .
1122 ' | CC: ' . $external_mail_recipients_cc .
1123 ' | BCC: ' . $external_eail_recipients_bcc .
1124 ' | Subject: ' . $mail_data->getSubject()
1125 );
1126
1127 $this->sendMimeMail(
1128 $external_mail_recipients_to,
1129 $external_mail_recipients_cc,
1130 $external_eail_recipients_bcc,
1131 $mail_data->getSubject(),
1132 $mail_data->isUsePlaceholder() ?
1133 $this->replacePlaceholders($mail_data->getMessage(), 0) :
1134 $mail_data->getMessage(),
1135 $mail_data->getAttachments()
1136 );
1137 } else {
1138 $this->logger->debug('No external email addresses given in recipient string');
1139 }
1140
1141 $errors = [];
1142 if (!$this->distributeMail($mail_data)) {
1143 $errors['mail_send_error'] = new ilMailError('mail_send_error');
1144 }
1145
1146 if (!$this->getSaveInSentbox()) {
1147 $this->deleteMails([$internal_message_id]);
1148 }
1149
1150 if ($this->isSystemMail()) {
1151 $random = new Random\Randomizer();
1152 if ($random->getInt(0, 50) === 2) {
1154 $this->logger,
1155 $this->mail_file_data
1156 ))->run();
1157 }
1158 }
1159
1160 return array_values($errors);
1161 }
1162
1166 public function validateRecipients(string $to, string $cc, string $bcc): array
1167 {
1168 try {
1169 $errors = [];
1170 $errors = array_merge($errors, $this->checkRecipients($to));
1171 $errors = array_merge($errors, $this->checkRecipients($cc));
1172 $errors = array_merge($errors, $this->checkRecipients($bcc));
1173
1174 if ($errors !== []) {
1175 return array_merge([new ilMailError('mail_following_rcp_not_valid')], $errors);
1176 }
1177 } catch (ilMailException $e) {
1178 return [new ilMailError('mail_generic_rcp_error', [$e->getMessage()])];
1179 }
1180
1181 return [];
1182 }
1183
1184 private function getSubjectSentFolderId(): int
1185 {
1186 $send_folder_id = 0;
1187 if (!$this->isSystemMail()) {
1188 $send_folder_id = $this->mailbox->getSentFolder();
1189 }
1190
1191 return $send_folder_id;
1192 }
1193
1197 private function saveInSentbox(
1198 array $attachment,
1199 string $to,
1200 string $cc,
1201 string $bcc,
1202 string $subject,
1203 string $message
1204 ): int {
1205 return $this->sendInternalMail(
1206 $this->getSubjectSentFolderId(),
1207 $this->user_id,
1208 $attachment,
1209 $to,
1210 $cc,
1211 $bcc,
1212 'read',
1213 $subject,
1214 $message,
1215 $this->user_id
1216 );
1217 }
1218
1222 private function sendMimeMail(
1223 string $to,
1224 string $cc,
1225 string $bcc,
1226 string $subject,
1227 string $message,
1228 array $attachments
1229 ): void {
1230 $mailer = new ilMimeMail();
1231 $mailer->From($this->sender_factory->getSenderByUsrId($this->user_id));
1232 $mailer->To($to);
1233 $mailer->Subject(
1234 $subject,
1235 true,
1236 (string) ($this->context_parameters[self::PROP_CONTEXT_SUBJECT_PREFIX] ?? '')
1237 );
1238
1239 if (!$this->isSystemMail()) {
1240 $message .= $this->signature_service->user($this->user_id);
1241 }
1242 $mailer->Body($message);
1243
1244 if ($cc !== '') {
1245 $mailer->Cc($cc);
1246 }
1247
1248 if ($bcc !== '') {
1249 $mailer->Bcc($bcc);
1250 }
1251
1252
1253 foreach ($attachments as $attachment) {
1254 $mailer->Attach(
1255 $this->mail_file_data->getAbsoluteAttachmentPoolPathByFilename($attachment),
1256 '',
1257 'inline',
1258 $attachment
1259 );
1260 }
1261
1262 $mailer->Send();
1263 }
1264
1268 public function saveAttachments(array $attachments): void
1269 {
1270 $this->db->update(
1271 $this->table_mail_saved,
1272 [
1273 'attachments' => ['clob', serialize($attachments)],
1274 ],
1275 [
1276 'user_id' => ['integer', $this->user_id],
1277 ]
1278 );
1279 }
1280
1285 private function parseAddresses(string $addresses): array
1286 {
1287 if ($addresses !== '') {
1288 $this->logger->debug(sprintf(
1289 'Started parsing of recipient string: %s',
1290 $addresses
1291 ));
1292 }
1293
1294 $parser = $this->mail_address_parser_factory->getParser($addresses);
1295 $parsed_addresses = $parser->parse();
1296
1297 if ($addresses !== '') {
1298 $this->logger->debug(sprintf(
1299 'Parsed addresses: %s',
1300 implode(',', array_map(static fn(ilMailAddress $address): string => (string) $address, $parsed_addresses))
1301 ));
1302 }
1303
1304 return $parsed_addresses;
1305 }
1306
1307 private function getCountRecipient(string $recipients, bool $only_external_addresses = true): int
1308 {
1309 $addresses = new ilMailAddressListImpl($this->parseAddresses($recipients));
1310 if ($only_external_addresses) {
1311 $addresses = new ilMailOnlyExternalAddressList(
1312 $addresses,
1313 self::ILIAS_HOST,
1314 $this->usr_id_by_login_callable
1315 );
1316 }
1317
1318 return count($addresses->value());
1319 }
1320
1321 private function getCountRecipients(
1322 string $to_recipients,
1323 string $cc_recipients,
1324 string $bcc_recipients,
1325 bool $only_external_addresses = true
1326 ): int {
1327 return (
1328 $this->getCountRecipient($to_recipients, $only_external_addresses) +
1329 $this->getCountRecipient($cc_recipients, $only_external_addresses) +
1330 $this->getCountRecipient($bcc_recipients, $only_external_addresses)
1331 );
1332 }
1333
1334 private function getEmailRecipients(string $recipients): string
1335 {
1336 $addresses = new ilMailOnlyExternalAddressList(
1337 new ilMailAddressListImpl($this->parseAddresses($recipients)),
1338 self::ILIAS_HOST,
1339 $this->usr_id_by_login_callable
1340 );
1341
1342 $email_recipients = array_map(static fn(ilMailAddress $address): string => (string) $address, $addresses->value());
1343
1344 return implode(',', $email_recipients);
1345 }
1346
1347 public static function _getAutoGeneratedMessageString(?ilLanguage $lang = null): string
1348 {
1349 global $DIC;
1350
1351 if (!($lang instanceof ilLanguage)) {
1353 }
1354
1355 $lang->loadLanguageModule('mail');
1356
1357 return sprintf(
1358 $lang->txt('mail_auto_generated_info'),
1359 $DIC->settings()->get('inst_name', 'ILIAS ' . ((int) ILIAS_VERSION_NUMERIC)),
1361 ) . "\n\n";
1362 }
1363
1364 public static function _getIliasMailerName(): string
1365 {
1366 global $DIC;
1367 $sender_factory = $DIC->mail()->mime()->senderFactory();
1368
1369 return $sender_factory->system()->getFromName();
1370 }
1371
1375 public function appendInstallationSignature(?bool $a_flag = null)
1376 {
1377 if ($a_flag === null) {
1378 return $this->append_installation_signature;
1379 }
1380
1381 $this->append_installation_signature = $a_flag;
1382 return $this;
1383 }
1384
1385 public static function _getInstallationSignature(): string
1386 {
1387 global $DIC;
1388 return $DIC->mail()->signature()->installation();
1389 }
1390
1391 public static function getSalutation(int $a_usr_id, ?ilLanguage $a_language = null): string
1392 {
1393 global $DIC;
1394
1395 $lang = ($a_language instanceof ilLanguage) ? $a_language : $DIC->language();
1396 $lang->loadLanguageModule('mail');
1397
1398 $gender = ilObjUser::_lookupGender($a_usr_id);
1399 $gender = $gender ?: 'n';
1400 $name = ilObjUser::_lookupName($a_usr_id);
1401
1402 if ($name['firstname'] === '') {
1403 return $lang->txt('mail_salutation_anonymous') . ',';
1404 }
1405
1406 return
1407 $lang->txt('mail_salutation_' . $gender) . ' ' .
1408 ($name['title'] ? $name['title'] . ' ' : '') .
1409 ($name['firstname'] ? $name['firstname'] . ' ' : '') .
1410 $name['lastname'] . ',';
1411 }
1412
1413 private function getUserInstanceById(int $usr_id): ?ilObjUser
1414 {
1415 if (!array_key_exists($usr_id, $this->user_instances_by_id_map)) {
1416 try {
1417 $user = new ilObjUser($usr_id);
1418 } catch (Exception) {
1419 $user = null;
1420 }
1421
1422 $this->user_instances_by_id_map[$usr_id] = $user;
1423 }
1424
1425 return $this->user_instances_by_id_map[$usr_id];
1426 }
1427
1431 public function setUserInstanceById(array $user_instances_by_id_map): void
1432 {
1433 $this->user_instances_by_id_map = $user_instances_by_id_map;
1434 }
1435
1436 private function getMailOptionsByUserId(int $usr_id): ilMailOptions
1437 {
1438 if (!isset($this->mail_options_by_usr_id_map[$usr_id])) {
1439 $this->mail_options_by_usr_id_map[$usr_id] = new ilMailOptions($usr_id);
1440 }
1441
1442 return $this->mail_options_by_usr_id_map[$usr_id];
1443 }
1444
1448 public function setMailOptionsByUserIdMap(array $mail_options_by_usr_id_map): void
1449 {
1450 $this->mail_options_by_usr_id_map = $mail_options_by_usr_id_map;
1451 }
1452
1453 public function formatLinebreakMessage(string $message): string
1454 {
1455 return $message;
1456 }
1457
1458 private function createRecipient(int $user_id): Recipient
1459 {
1460 return new Recipient(
1461 $user_id,
1462 $this->getUserInstanceById($user_id),
1463 $this->getMailOptionsByUserId($user_id),
1464 $this->legal_documents
1465 );
1466 }
1467}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
withInternalMailId(int $internal_mail_id)
Global event handler.
const CONTEXT_CRON
static getType()
Get context type.
static _getLanguage(string $a_lang_key='')
Get language object.
language handling
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component 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)
autoresponder()
array $context_parameters
markUnread(array $mail_ids)
saveAttachments(array $attachments)
array $mail_options_by_usr_id_map
const string PROP_CONTEXT_SUBJECT_PREFIX
array $user_instances_by_id_map
formatNamesForOutput(string $recipients)
isSystemMail()
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)
sendMailWithReplacedEmptyPlaceholder(MailDeliveryData $mail_data, array $recipients,)
deleteMailsOfFolder(int $folder_id)
appendInstallationSignature(?bool $a_flag=null)
const string ILIAS_HOST
string $table_mail_saved
persistToStage(int $a_user_id, array $a_attachments, string $a_rcp_to, string $a_rcp_cc, string $a_rcp_bcc, string $a_m_subject, string $a_m_message, bool $a_use_placeholders=false, ?string $a_tpl_context_id=null, ?array $a_tpl_ctx_params=[])
validateRecipients(string $to, string $cc, string $bcc)
readonly Conductor $legal_documents
retrieveFromStage()
setMailOptionsByUserIdMap(array $mail_options_by_usr_id_map)
static getSalutation(int $a_usr_id, ?ilLanguage $a_language=null)
distributeMail(MailDeliveryData $mail_data)
string $table_mail
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)
getSubjectSentFolderId()
array $mail_data
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)
formatLinebreakMessage(string $message)
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, bool $a_use_placeholders=false, ?string $a_tpl_context_id=null, array $a_tpl_context_params=[])
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)
string $context_id
checkMail(string $to, string $cc, string $bcc, string $subject)
replacePlaceholdersEmpty(string $message)
int $user_id
static _getAutoGeneratedMessageString(?ilLanguage $lang=null)
createRecipient(int $user_id)
getMailObjectReferenceId()
bool $save_in_sentbox
getPreviousMail(int $mail_id)
bool $append_user_signature
readMailObjectReferenceId()
getNextMail(int $mail_id)
getMail(int $mail_id)
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'.
getSaveInSentbox()
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)
User class.
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)
Definition: class.ilStr.php:60
static _getHttpPath()
const ANONYMOUS_USER_ID
Definition: constants.php:27
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 ilDBInterface.
$res
Definition: ltiservices.php:69
try
handle Lrs Init
Definition: xapiproxy.php:86
global $lng
Definition: privfeed.php:31
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$context
Definition: webdav.php:31
$lang
Definition: xapiexit.php:25
$message
Definition: xapiexit.php:31