ILIAS  release_8 Revision v8.23
class.ilMail.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
27 class ilMail
28 {
29  public const ILIAS_HOST = 'ilias';
30  public const PROP_CONTEXT_SUBJECT_PREFIX = 'subject_prefix';
31  protected ilLanguage $lng;
32  protected ilDBInterface $db;
35  protected ilMailbox $mailbox;
36  public int $user_id;
37  protected string $table_mail;
38  protected string $table_mail_saved;
40  protected ?array $mail_data = [];
41  protected ?int $mail_obj_ref_id = null;
42  protected bool $save_in_sentbox;
43  protected bool $appendInstallationSignature = false;
47  protected ?string $contextId = null;
48  protected array $contextParameters = [];
49  protected ilLogger $logger;
51  protected array $mailOptionsByUsrIdMap = [];
53  protected array $userInstancesByIdMap = [];
55  protected int $maxRecipientCharacterLength = 998;
57  protected ilObjUser $actor;
58 
59  public function __construct(
60  int $a_user_id,
61  ilMailAddressTypeFactory $mailAddressTypeFactory = null,
62  ilMailRfc822AddressParserFactory $mailAddressParserFactory = null,
63  ilAppEventHandler $eventHandler = null,
64  ilLogger $logger = null,
65  ilDBInterface $db = null,
66  ilLanguage $lng = null,
67  ilFileDataMail $mailFileData = null,
68  ilMailOptions $mailOptions = null,
69  ilMailbox $mailBox = null,
70  ilMailMimeSenderFactory $senderFactory = null,
71  callable $usrIdByLoginCallable = null,
72  int $mailAdminNodeRefId = null,
73  ilObjUser $actor = null
74  ) {
75  global $DIC;
76  $this->logger = $logger ?? ilLoggerFactory::getLogger('mail');
77  $this->mailAddressTypeFactory = $mailAddressTypeFactory ?? new ilMailAddressTypeFactory(null, $logger);
78  $this->mailAddressParserFactory = $mailAddressParserFactory ?? new ilMailRfc822AddressParserFactory();
79  $this->eventHandler = $eventHandler ?? $DIC->event();
80  $this->db = $db ?? $DIC->database();
81  $this->lng = $lng ?? $DIC->language();
82  $this->actor = $actor ?? $DIC->user();
83  $this->mfile = $mailFileData ?? new ilFileDataMail($a_user_id);
84  $this->mail_options = $mailOptions ?? new ilMailOptions($a_user_id);
85  $this->mailbox = $mailBox ?? new ilMailbox($a_user_id);
86  $this->senderFactory = $senderFactory ?? $GLOBALS["DIC"]["mail.mime.sender.factory"];
87  $this->usrIdByLoginCallable = $usrIdByLoginCallable ?? static function (string $login): int {
88  return (int) ilObjUser::_lookupId($login);
89  };
90  $this->user_id = $a_user_id;
91  $this->mail_obj_ref_id = $mailAdminNodeRefId;
92  if (null === $this->mail_obj_ref_id) {
94  }
95  $this->lng->loadLanguageModule('mail');
96  $this->table_mail = 'mail';
97  $this->table_mail_saved = 'mail_saved';
98  $this->setSaveInSentbox(false);
99  }
100 
101  public function withContextId(string $contextId): self
102  {
103  $clone = clone $this;
104 
105  $clone->contextId = $contextId;
106 
107  return $clone;
108  }
109 
110  public function withContextParameters(array $parameters): self
111  {
112  $clone = clone $this;
113 
114  $clone->contextParameters = $parameters;
115 
116  return $clone;
117  }
118 
119  protected function isSystemMail(): bool
120  {
121  return $this->user_id === ANONYMOUS_USER_ID;
122  }
123 
124  public function existsRecipient(string $newRecipient, string $existingRecipients): bool
125  {
126  $newAddresses = new ilMailAddressListImpl($this->parseAddresses($newRecipient));
127  $addresses = new ilMailAddressListImpl($this->parseAddresses($existingRecipients));
128 
129  $list = new ilMailDiffAddressList($newAddresses, $addresses);
130 
131  $diffedAddresses = $list->value();
132 
133  return count($diffedAddresses) === 0;
134  }
135 
136  public function setSaveInSentbox(bool $saveInSentbox): void
137  {
138  $this->save_in_sentbox = $saveInSentbox;
139  }
140 
141  public function getSaveInSentbox(): bool
142  {
143  return $this->save_in_sentbox;
144  }
145 
146  protected function readMailObjectReferenceId(): void
147  {
148  $this->mail_obj_ref_id = ilMailGlobalServices::getMailObjectRefId();
149  }
150 
151  public function getMailObjectReferenceId(): int
152  {
153  return $this->mail_obj_ref_id;
154  }
155 
156  public function formatNamesForOutput(string $recipients): string
157  {
158  $recipients = trim($recipients);
159  if ($recipients === '') {
160  return $this->lng->txt('not_available');
161  }
162 
163  $names = [];
164 
165  $recipients = array_filter(array_map('trim', explode(',', $recipients)));
166  foreach ($recipients as $recipient) {
167  $usrId = ilObjUser::_lookupId($recipient);
168  if (is_int($usrId) && $usrId > 0) {
169  $pp = ilObjUser::_lookupPref($usrId, 'public_profile');
170  if ($pp === 'g' || ($pp === 'y' && !$this->actor->isAnonymous())) {
171  $user = $this->getUserInstanceById($usrId);
172  if ($user) {
173  $names[] = $user->getFullname() . ' [' . $recipient . ']';
174  continue;
175  }
176  }
177  }
178 
179  $names[] = $recipient;
180  }
181 
182  return implode(', ', $names);
183  }
184 
185  public function getPreviousMail(int $mailId): ?array
186  {
187  $this->db->setLimit(1, 0);
188 
189  $query = implode(' ', [
190  "SELECT b.* FROM $this->table_mail a",
191  "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
192  'AND b.user_id = a.user_id AND b.send_time > a.send_time',
193  'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time ASC',
194  ]);
195  $res = $this->db->queryF(
196  $query,
197  ['integer', 'integer'],
198  [$this->user_id, $mailId]
199  );
200 
201  $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
202 
203  return $this->mail_data;
204  }
205 
206  public function getNextMail(int $mailId): ?array
207  {
208  $this->db->setLimit(1, 0);
209 
210  $query = implode(' ', [
211  "SELECT b.* FROM $this->table_mail a",
212  "INNER JOIN $this->table_mail b ON b.folder_id = a.folder_id",
213  'AND b.user_id = a.user_id AND b.send_time < a.send_time',
214  'WHERE a.user_id = %s AND a.mail_id = %s ORDER BY b.send_time DESC',
215  ]);
216  $res = $this->db->queryF(
217  $query,
218  ['integer', 'integer'],
219  [$this->user_id, $mailId]
220  );
221 
222  $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
223 
224  return $this->mail_data;
225  }
226 
227  public function getMailsOfFolder(int $a_folder_id, array $filter = []): array
228  {
229  $mails = [];
230 
231  $query =
232  "SELECT sender_id, m_subject, mail_id, m_status, send_time, import_name " .
233  "FROM $this->table_mail " .
234  "LEFT JOIN object_data ON obj_id = sender_id " .
235  "WHERE user_id = %s AND folder_id = %s " .
236  "AND ((sender_id > 0 AND sender_id IS NOT NULL AND obj_id IS NOT NULL) " .
237  "OR (sender_id = 0 OR sender_id IS NULL))";
238 
239  if (isset($filter['status']) && $filter['status'] !== '') {
240  $query .= ' AND m_status = ' . $this->db->quote($filter['status'], 'text');
241  }
242 
243  $query .= " ORDER BY send_time DESC";
244 
245  $res = $this->db->queryF(
246  $query,
247  ['integer', 'integer'],
248  [$this->user_id, $a_folder_id]
249  );
250 
251  while ($row = $this->db->fetchAssoc($res)) {
252  $mails[] = $this->fetchMailData($row);
253  }
254 
255  return array_filter($mails);
256  }
257 
258  public function countMailsOfFolder(int $folderId): int
259  {
260  $res = $this->db->queryF(
261  "SELECT COUNT(*) FROM $this->table_mail WHERE user_id = %s AND folder_id = %s",
262  ['integer', 'integer'],
263  [$this->user_id, $folderId]
264  );
265 
266  return $this->db->numRows($res);
267  }
268 
269  public function deleteMailsOfFolder(int $folderId): void
270  {
271  $mails = $this->getMailsOfFolder($folderId);
272  foreach ($mails as $mail_data) {
273  $this->deleteMails([$mail_data['mail_id']]);
274  }
275  }
276 
277  public function getMail(int $mailId): ?array
278  {
279  $res = $this->db->queryF(
280  "SELECT * FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
281  ['integer', 'integer'],
282  [$this->user_id, $mailId]
283  );
284 
285  $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
286 
287  return $this->mail_data;
288  }
289 
293  public function markRead(array $mailIds): void
294  {
295  $values = [];
296  $types = [];
297 
298  $query = "UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
299  array_push($types, 'text', 'integer');
300  array_push($values, 'read', $this->user_id);
301 
302  if (count($mailIds) > 0) {
303  $query .= ' AND ' . $this->db->in('mail_id', $mailIds, false, 'integer');
304  }
305 
306  $this->db->manipulateF($query, $types, $values);
307  }
308 
312  public function markUnread(array $mailIds): void
313  {
314  $values = [];
315  $types = [];
316 
317  $query = "UPDATE $this->table_mail SET m_status = %s WHERE user_id = %s ";
318  array_push($types, 'text', 'integer');
319  array_push($values, 'unread', $this->user_id);
320 
321  if (count($mailIds) > 0) {
322  $query .= ' AND ' . $this->db->in('mail_id', $mailIds, false, 'integer');
323  }
324 
325  $this->db->manipulateF($query, $types, $values);
326  }
327 
333  public function moveMailsToFolder(array $mailIds, int $folderId): bool
334  {
335  $values = [];
336  $types = [];
337 
338  $mailIds = array_filter(array_map('intval', $mailIds));
339 
340  if (0 === count($mailIds)) {
341  return false;
342  }
343 
344  $query =
345  "UPDATE $this->table_mail " .
346  "INNER JOIN mail_obj_data " .
347  "ON mail_obj_data.obj_id = %s AND mail_obj_data.user_id = %s " .
348  "SET $this->table_mail.folder_id = mail_obj_data.obj_id " .
349  "WHERE $this->table_mail.user_id = %s";
350  array_push($types, 'integer', 'integer', 'integer');
351  array_push($values, $folderId, $this->user_id, $this->user_id);
352 
353  $query .= ' AND ' . $this->db->in('mail_id', $mailIds, false, 'integer');
354 
355  $affectedRows = $this->db->manipulateF($query, $types, $values);
356 
357  return $affectedRows > 0;
358  }
359 
363  public function deleteMails(array $mailIds): void
364  {
365  $mailIds = array_filter(array_map('intval', $mailIds));
366  foreach ($mailIds as $id) {
367  $this->db->manipulateF(
368  "DELETE FROM $this->table_mail WHERE user_id = %s AND mail_id = %s",
369  ['integer', 'integer'],
370  [$this->user_id, $id]
371  );
372  $this->mfile->deassignAttachmentFromDirectory($id);
373  }
374  }
375 
380  protected function fetchMailData(?array $row): ?array
381  {
382  if (!is_array($row) || empty($row)) {
383  return null;
384  }
385 
386  if (isset($row['attachments'])) {
387  $unserialized = unserialize(stripslashes($row['attachments']), ['allowed_classes' => false]);
388  $row['attachments'] = is_array($unserialized) ? $unserialized : [];
389  } else {
390  $row['attachments'] = [];
391  }
392 
393  if (isset($row['tpl_ctx_params']) && is_string($row['tpl_ctx_params'])) {
394  $decoded = json_decode($row['tpl_ctx_params'], true, 512, JSON_THROW_ON_ERROR);
395  $row['tpl_ctx_params'] = (array) ($decoded ?? []);
396  } else {
397  $row['tpl_ctx_params'] = [];
398  }
399 
400  if (isset($row['mail_id'])) {
401  $row['mail_id'] = (int) $row['mail_id'];
402  }
403 
404  if (isset($row['user_id'])) {
405  $row['user_id'] = (int) $row['user_id'];
406  }
407 
408  if (isset($row['folder_id'])) {
409  $row['folder_id'] = (int) $row['folder_id'];
410  }
411 
412  if (isset($row['sender_id'])) {
413  $row['sender_id'] = (int) $row['sender_id'];
414  }
415 
416  if (isset($row['use_placeholders'])) {
417  $row['use_placeholders'] = (bool) $row['use_placeholders'];
418  }
419 
420  $null_to_string_properties = ['m_subject', 'm_message', 'rcp_to', 'rcp_cc', 'rcp_bcc'];
421  foreach ($null_to_string_properties as $null_to_string_property) {
422  if (!isset($row[$null_to_string_property])) {
423  $row[$null_to_string_property] = '';
424  }
425  }
426 
427  return $row;
428  }
429 
430  public function getNewDraftId(int $folderId): int
431  {
432  $nextId = $this->db->nextId($this->table_mail);
433  $this->db->insert($this->table_mail, [
434  'mail_id' => ['integer', $nextId],
435  'user_id' => ['integer', $this->user_id],
436  'folder_id' => ['integer', $folderId],
437  'sender_id' => ['integer', $this->user_id],
438  ]);
439 
440  return $nextId;
441  }
442 
457  public function updateDraft(
458  int $a_folder_id,
459  array $a_attachments,
460  string $a_rcp_to,
461  string $a_rcp_cc,
462  string $a_rcp_bcc,
463  string $a_m_subject,
464  string $a_m_message,
465  int $a_draft_id = 0,
466  bool $a_use_placeholders = false,
467  ?string $a_tpl_context_id = null,
468  array $a_tpl_context_params = []
469  ): int {
470  $this->db->update(
471  $this->table_mail,
472  [
473  'folder_id' => ['integer', $a_folder_id],
474  'attachments' => ['clob', serialize($a_attachments)],
475  'send_time' => ['timestamp', date('Y-m-d H:i:s')],
476  'rcp_to' => ['clob', $a_rcp_to],
477  'rcp_cc' => ['clob', $a_rcp_cc],
478  'rcp_bcc' => ['clob', $a_rcp_bcc],
479  'm_status' => ['text', 'read'],
480  'm_subject' => ['text', $a_m_subject],
481  'm_message' => ['clob', $a_m_message],
482  'use_placeholders' => ['integer', (int) $a_use_placeholders],
483  'tpl_ctx_id' => ['text', $a_tpl_context_id],
484  'tpl_ctx_params' => ['blob', json_encode($a_tpl_context_params, JSON_THROW_ON_ERROR)],
485  ],
486  [
487  'mail_id' => ['integer', $a_draft_id],
488  ]
489  );
490 
491  return $a_draft_id;
492  }
493 
494  private function sendInternalMail(
495  int $folderId,
496  int $senderUsrId,
497  array $attachments,
498  string $to,
499  string $cc,
500  string $bcc,
501  string $status,
502  string $subject,
503  string $message,
504  int $usrId = 0,
505  bool $usePlaceholders = false,
506  ?string $templateContextId = null,
507  array $templateContextParameters = []
508  ): int {
509  $usrId = $usrId ?: $this->user_id;
510 
511  if ($usePlaceholders) {
512  $message = $this->replacePlaceholders($message, $usrId);
513  }
514  $message = $this->formatLinebreakMessage($message);
515  $message = str_ireplace(["<br />", "<br>", "<br/>"], "\n", $message);
516 
517  $nextId = $this->db->nextId($this->table_mail);
518  $this->db->insert($this->table_mail, [
519  'mail_id' => ['integer', $nextId],
520  'user_id' => ['integer', $usrId],
521  'folder_id' => ['integer', $folderId],
522  'sender_id' => ['integer', $senderUsrId],
523  'attachments' => ['clob', serialize($attachments)],
524  'send_time' => ['timestamp', date('Y-m-d H:i:s')],
525  'rcp_to' => ['clob', $to],
526  'rcp_cc' => ['clob', $cc],
527  'rcp_bcc' => ['clob', $bcc],
528  'm_status' => ['text', $status],
529  'm_subject' => ['text', $subject],
530  'm_message' => ['clob', $message],
531  'tpl_ctx_id' => ['text', $templateContextId],
532  'tpl_ctx_params' => ['blob', json_encode($templateContextParameters, JSON_THROW_ON_ERROR)],
533  ]);
534 
535  $sender_equals_reveiver = $usrId === $this->mailbox->getUsrId();
536  $is_sent_folder_of_sender = false;
537  if ($sender_equals_reveiver) {
538  $current_folder_id = $this->getSubjectSentFolderId();
539  $is_sent_folder_of_sender = $folderId === $current_folder_id;
540  }
541 
542  $raise_event = !$sender_equals_reveiver || !$is_sent_folder_of_sender;
543 
544  if ($raise_event) {
545  $this->eventHandler->raise('Services/Mail', 'sentInternalMail', [
546  'id' => $nextId,
547  'subject' => $subject,
548  'body' => (string) $message,
549  'from_usr_id' => $senderUsrId,
550  'to_usr_id' => $usrId,
551  'rcp_to' => $to,
552  'rcp_cc' => $cc,
553  'rcp_bcc' => $bcc,
554  ]);
555  }
556 
557  return $nextId;
558  }
559 
560  protected function replacePlaceholders(
561  string $message,
562  int $usrId = 0,
563  bool $replaceEmptyPlaceholders = true
564  ): string {
565  try {
566  if ($this->contextId) {
568  } else {
570  }
571  $user = $usrId > 0 ? $this->getUserInstanceById($usrId) : null;
572 
573  $processor = new ilMailTemplatePlaceholderResolver($context, $message);
574  $message = $processor->resolve($user, $this->contextParameters, $replaceEmptyPlaceholders);
575  } catch (Exception $e) {
576  $this->logger->error(__METHOD__ . ' has been called with invalid context. ' . $e->getMessage());
577  }
578 
579  return $message;
580  }
581 
593  protected function distributeMail(
594  string $to,
595  string $cc,
596  string $bcc,
597  string $subject,
598  string $message,
599  array $attachments,
600  int $sentMailId,
601  bool $usePlaceholders = false
602  ): bool {
603  if ($usePlaceholders) {
604  $toUsrIds = $this->getUserIds([$to]);
605  $this->logger->debug(sprintf(
606  "Parsed TO user ids from given recipients for serial letter notification: %s",
607  implode(', ', $toUsrIds)
608  ));
609 
610  $this->sendChanneledMails(
611  $to,
612  $cc,
613  '',
614  $toUsrIds,
615  $subject,
616  $message,
617  $attachments,
618  $sentMailId,
619  true
620  );
621 
622  $otherUsrIds = $this->getUserIds([$cc, $bcc]);
623  $this->logger->debug(sprintf(
624  "Parsed CC/BCC user ids from given recipients for serial letter notification: %s",
625  implode(', ', $otherUsrIds)
626  ));
627 
628  $this->sendChanneledMails(
629  $to,
630  $cc,
631  '',
632  $otherUsrIds,
633  $subject,
634  $this->replacePlaceholders($message, 0, false),
635  $attachments,
636  $sentMailId
637  );
638  } else {
639  $usrIds = $this->getUserIds([$to, $cc, $bcc]);
640  $this->logger->debug(sprintf(
641  "Parsed TO/CC/BCC user ids from given recipients: %s",
642  implode(', ', $usrIds)
643  ));
644 
645  $this->sendChanneledMails(
646  $to,
647  $cc,
648  '',
649  $usrIds,
650  $subject,
651  $message,
652  $attachments,
653  $sentMailId
654  );
655  }
656 
657  return true;
658  }
659 
671  protected function sendChanneledMails(
672  string $to,
673  string $cc,
674  string $bcc,
675  array $usrIds,
676  string $subject,
677  string $message,
678  array $attachments,
679  int $sentMailId,
680  bool $usePlaceholders = false
681  ): void {
682  $usrIdToExternalEmailAddressesMap = [];
683  $usrIdToMessageMap = [];
684 
685  foreach ($usrIds as $usrId) {
686  $user = $this->getUserInstanceById($usrId);
687  if (!($user instanceof ilObjUser)) {
688  $this->logger->critical(sprintf(
689  "Skipped recipient with id %s (User not found)",
690  $usrId
691  ));
692  continue;
693  }
694 
695  $mailOptions = $this->getMailOptionsByUserId($user->getId());
696 
697  $canReadInternalMails = !$user->hasToAcceptTermsOfService() && $user->checkTimeLimit();
698 
699  if ($this->isSystemMail() && !$canReadInternalMails) {
700  $this->logger->debug(sprintf(
701  "Skipped recipient with id %s (Accepted User Agreement:%s|Expired Account:%s)",
702  $usrId,
703  var_export(!$user->hasToAcceptTermsOfService(), true),
704  var_export(!$user->checkTimeLimit(), true)
705  ));
706  continue;
707  }
708 
709  $individualMessage = $message;
710  if ($usePlaceholders) {
711  $individualMessage = $this->replacePlaceholders($message, $user->getId());
712  $usrIdToMessageMap[$user->getId()] = $individualMessage;
713  }
714 
715  if ($user->getActive()) {
716  $wantsToReceiveExternalEmail = (
717  $mailOptions->getIncomingType() === ilMailOptions::INCOMING_EMAIL ||
718  $mailOptions->getIncomingType() === ilMailOptions::INCOMING_BOTH
719  );
720 
721  if (!$canReadInternalMails || $wantsToReceiveExternalEmail) {
722  $emailAddresses = $mailOptions->getExternalEmailAddresses();
723  $usrIdToExternalEmailAddressesMap[$user->getId()] = $emailAddresses;
724 
725  if ($mailOptions->getIncomingType() === ilMailOptions::INCOMING_EMAIL) {
726  $this->logger->debug(sprintf(
727  "Recipient with id %s will only receive external emails sent to: %s",
728  $user->getId(),
729  implode(', ', $emailAddresses)
730  ));
731  continue;
732  }
733 
734  $this->logger->debug(sprintf(
735  "Recipient with id %s will additionally receive external emails " .
736  "(because the user wants to receive it externally, or the user cannot access " .
737  "the internal mail system) sent to: %s",
738  $user->getId(),
739  implode(', ', $emailAddresses)
740  ));
741  } else {
742  $this->logger->debug(sprintf(
743  "Recipient with id %s is does not want to receive external emails",
744  $user->getId()
745  ));
746  }
747  } else {
748  $this->logger->debug(sprintf(
749  "Recipient with id %s is inactive and will not receive external emails",
750  $user->getId()
751  ));
752  }
753 
754  $mbox = clone $this->mailbox;
755  $mbox->setUsrId($user->getId());
756  $recipientInboxId = $mbox->getInboxFolder();
757 
758  $internalMailId = $this->sendInternalMail(
759  $recipientInboxId,
760  $this->user_id,
761  $attachments,
762  $to,
763  $cc,
764  '',
765  'unread',
766  $subject,
767  $individualMessage,
768  $user->getId()
769  );
770 
771  if (count($attachments) > 0) {
772  $this->mfile->assignAttachmentsToDirectory($internalMailId, $sentMailId);
773  }
774  }
775 
776  $this->delegateExternalEmails(
777  $subject,
778  $message,
779  $attachments,
780  $usePlaceholders,
781  $usrIdToExternalEmailAddressesMap,
782  $usrIdToMessageMap
783  );
784  }
785 
794  protected function delegateExternalEmails(
795  string $subject,
796  string $message,
797  array $attachments,
798  bool $usePlaceholders,
799  array $usrIdToExternalEmailAddressesMap,
800  array $usrIdToMessageMap
801  ): void {
802  if (1 === count($usrIdToExternalEmailAddressesMap)) {
803  if ($usePlaceholders) {
804  $message = array_values($usrIdToMessageMap)[0];
805  }
806 
807  $usrIdToExternalEmailAddressesMap = array_values($usrIdToExternalEmailAddressesMap);
808  $firstAddresses = current($usrIdToExternalEmailAddressesMap);
809 
810  $this->sendMimeMail(
811  implode(',', $firstAddresses),
812  '',
813  '',
814  $subject,
815  $this->formatLinebreakMessage($message),
816  $attachments
817  );
818  } elseif (count($usrIdToExternalEmailAddressesMap) > 1) {
819  if ($usePlaceholders) {
820  foreach ($usrIdToExternalEmailAddressesMap as $usrId => $addresses) {
821  if (0 === count($addresses)) {
822  continue;
823  }
824 
825  $this->sendMimeMail(
826  implode(',', $addresses),
827  '',
828  '',
829  $subject,
830  $this->formatLinebreakMessage($usrIdToMessageMap[$usrId]),
831  $attachments
832  );
833  }
834  } else {
835  $flattenEmailAddresses = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator(
836  $usrIdToExternalEmailAddressesMap
837  )), false);
838 
839  $flattenEmailAddresses = array_unique($flattenEmailAddresses);
840 
841  // https://mantis.ilias.de/view.php?id=23981 and https://www.ietf.org/rfc/rfc2822.txt
842  $remainingAddresses = '';
843  foreach ($flattenEmailAddresses as $emailAddress) {
844  $sep = '';
845  if ($remainingAddresses !== '') {
846  $sep = ',';
847  }
848 
849  $recipientsLineLength = ilStr::strLen($remainingAddresses) +
850  ilStr::strLen($sep . $emailAddress);
851  if ($recipientsLineLength >= $this->maxRecipientCharacterLength) {
852  $this->sendMimeMail(
853  '',
854  '',
855  $remainingAddresses,
856  $subject,
857  $this->formatLinebreakMessage($message),
858  $attachments
859  );
860 
861  $remainingAddresses = '';
862  $sep = '';
863  }
864 
865  $remainingAddresses .= ($sep . $emailAddress);
866  }
867 
868  if ('' !== $remainingAddresses) {
869  $this->sendMimeMail(
870  '',
871  '',
872  $remainingAddresses,
873  $subject,
874  $this->formatLinebreakMessage($message),
875  $attachments
876  );
877  }
878  }
879  }
880  }
881 
886  protected function getUserIds(array $recipients): array
887  {
888  $parsed_usr_ids = [];
889 
890  $joined_recipients = implode(',', array_filter(array_map('trim', $recipients)));
891 
892  $addresses = $this->parseAddresses($joined_recipients);
893  foreach ($addresses as $address) {
894  $address_type = $this->mailAddressTypeFactory->getByPrefix($address);
895  $parsed_usr_ids[] = $address_type->resolve();
896  }
897 
898  return array_unique(array_merge(...$parsed_usr_ids));
899  }
900 
908  protected function checkMail(string $to, string $cc, string $bcc, string $subject): array
909  {
910  $errors = [];
911 
912  $checks = [
913  $subject => 'mail_add_subject',
914  $to => 'mail_add_recipient',
915  ];
916  foreach ($checks as $string => $error) {
917  if ($string === '') {
918  $errors[] = new ilMailError($error);
919  }
920  }
921 
922  if (ilStr::strLen($subject) > 255) {
923  // https://mantis.ilias.de/view.php?id=37881
924  $errors[] = new ilMailError('mail_subject_too_long');
925  }
926 
927  return $errors;
928  }
929 
935  protected function checkRecipients(string $recipients): array
936  {
937  $errors = [];
938 
939  try {
940  $addresses = $this->parseAddresses($recipients);
941  foreach ($addresses as $address) {
942  $address_type = $this->mailAddressTypeFactory->getByPrefix($address);
943  if (!$address_type->validate($this->user_id)) {
944  $errors[] = $address_type->getErrors();
945  }
946  }
947  } catch (ilException $e) {
948  $colonPosition = strpos($e->getMessage(), ':');
949  throw new ilMailException(
950  ($colonPosition === false) ?
951  $e->getMessage() :
952  substr($e->getMessage(), $colonPosition + 2)
953  );
954  }
955 
956  return array_merge(...$errors);
957  }
958 
972  public function persistToStage(
973  int $a_user_id,
974  array $a_attachments,
975  string $a_rcp_to,
976  string $a_rcp_cc,
977  string $a_rcp_bcc,
978  string $a_m_subject,
979  string $a_m_message,
980  bool $a_use_placeholders = false,
981  ?string $a_tpl_context_id = null,
982  ?array $a_tpl_ctx_params = []
983  ): bool {
984  $this->db->replace(
985  $this->table_mail_saved,
986  [
987  'user_id' => ['integer', $this->user_id],
988  ],
989  [
990  'attachments' => ['clob', serialize($a_attachments)],
991  'rcp_to' => ['clob', $a_rcp_to],
992  'rcp_cc' => ['clob', $a_rcp_cc],
993  'rcp_bcc' => ['clob', $a_rcp_bcc],
994  'm_subject' => ['text', $a_m_subject],
995  'm_message' => ['clob', $a_m_message],
996  'use_placeholders' => ['integer', (int) $a_use_placeholders],
997  'tpl_ctx_id' => ['text', $a_tpl_context_id],
998  'tpl_ctx_params' => ['blob', json_encode((array) $a_tpl_ctx_params, JSON_THROW_ON_ERROR)],
999  ]
1000  );
1001 
1002  $this->retrieveFromStage();
1003 
1004  return true;
1005  }
1006 
1007  public function retrieveFromStage(): array
1008  {
1009  $res = $this->db->queryF(
1010  "SELECT * FROM $this->table_mail_saved WHERE user_id = %s",
1011  ['integer'],
1012  [$this->user_id]
1013  );
1014 
1015  $this->mail_data = $this->fetchMailData($this->db->fetchAssoc($res));
1016  if (!is_array($this->mail_data)) {
1017  $this->persistToStage($this->user_id, [], '', '', '', '', '', false);
1018  }
1019 
1020  return $this->mail_data;
1021  }
1022 
1034  public function enqueue(
1035  string $a_rcp_to,
1036  string $a_rcp_cc,
1037  string $a_rcp_bcc,
1038  string $a_m_subject,
1039  string $a_m_message,
1040  array $a_attachment,
1041  bool $a_use_placeholders = false
1042  ): array {
1043  global $DIC;
1044 
1045  $this->logger->info(
1046  "New mail system task:" .
1047  " To: " . $a_rcp_to .
1048  " | CC: " . $a_rcp_cc .
1049  " | BCC: " . $a_rcp_bcc .
1050  " | Subject: " . $a_m_subject .
1051  " | Attachments: " . print_r($a_attachment, true)
1052  );
1053 
1054  if ($a_attachment && !$this->mfile->checkFilesExist($a_attachment)) {
1055  return [new ilMailError('mail_attachment_file_not_exist', [$a_attachment])];
1056  }
1057 
1058  $errors = $this->checkMail($a_rcp_to, $a_rcp_cc, $a_rcp_bcc, $a_m_subject);
1059  if (count($errors) > 0) {
1060  return $errors;
1061  }
1062 
1063  $errors = $this->validateRecipients($a_rcp_to, $a_rcp_cc, $a_rcp_bcc);
1064  if (count($errors) > 0) {
1065  return $errors;
1066  }
1067 
1068  $rcp_to = $a_rcp_to;
1069  $rcp_cc = $a_rcp_cc;
1070  $rcp_bcc = $a_rcp_bcc;
1071 
1072  $numberOfExternalAddresses = $this->getCountRecipients($rcp_to, $rcp_cc, $rcp_bcc);
1073  if (
1074  $numberOfExternalAddresses > 0 &&
1075  !$this->isSystemMail() &&
1076  !$DIC->rbac()->system()->checkAccessOfUser($this->user_id, 'smtp_mail', $this->mail_obj_ref_id)
1077  ) {
1078  return [new ilMailError('mail_no_permissions_write_smtp')];
1079  }
1080 
1081  if ($this->appendInstallationSignature()) {
1082  $a_m_message .= self::_getInstallationSignature();
1083  }
1084 
1086  return $this->sendMail(
1087  $rcp_to,
1088  $rcp_cc,
1089  $rcp_bcc,
1090  $a_m_subject,
1091  $a_m_message,
1092  $a_attachment,
1093  $a_use_placeholders
1094  );
1095  }
1096 
1097  $taskFactory = $DIC->backgroundTasks()->taskFactory();
1098  $taskManager = $DIC->backgroundTasks()->taskManager();
1099 
1100  $bucket = new BasicBucket();
1101  $bucket->setUserId($this->user_id);
1102 
1103  $task = $taskFactory->createTask(ilMailDeliveryJob::class, [
1104  $this->user_id,
1105  $rcp_to,
1106  $rcp_cc,
1107  $rcp_bcc,
1108  $a_m_subject,
1109  $a_m_message,
1110  serialize($a_attachment),
1111  $a_use_placeholders,
1112  $this->getSaveInSentbox(),
1113  (string) $this->contextId,
1114  serialize($this->contextParameters),
1115  ]);
1116  $interaction = $taskFactory->createTask(ilMailDeliveryJobUserInteraction::class, [
1117  $task,
1118  $this->user_id,
1119  ]);
1120 
1121  $bucket->setTask($interaction);
1122  $bucket->setTitle($this->lng->txt('mail_bg_task_title'));
1123  $bucket->setDescription(sprintf($this->lng->txt('mail_bg_task_desc'), $a_m_subject));
1124 
1125  $this->logger->info('Delegated delivery to background task');
1126  $taskManager->run($bucket);
1127 
1128  return [];
1129  }
1130 
1145  public function sendMail(
1146  string $to,
1147  string $cc,
1148  string $bcc,
1149  string $subject,
1150  string $message,
1151  array $attachments,
1152  bool $usePlaceholders
1153  ): array {
1154  $internalMessageId = $this->saveInSentbox(
1155  $attachments,
1156  $to,
1157  $cc,
1158  $bcc,
1159  $subject,
1160  $message
1161  );
1162 
1163  if (count($attachments) > 0) {
1164  $this->mfile->assignAttachmentsToDirectory($internalMessageId, $internalMessageId);
1165  $this->mfile->saveFiles($internalMessageId, $attachments);
1166  }
1167 
1168  $numberOfExternalAddresses = $this->getCountRecipients($to, $cc, $bcc);
1169 
1170  if ($numberOfExternalAddresses > 0) {
1171  $externalMailRecipientsTo = $this->getEmailRecipients($to);
1172  $externalMailRecipientsCc = $this->getEmailRecipients($cc);
1173  $externalMailRecipientsBcc = $this->getEmailRecipients($bcc);
1174 
1175  $this->logger->debug(
1176  "Parsed external email addresses from given recipients /" .
1177  " To: " . $externalMailRecipientsTo .
1178  " | CC: " . $externalMailRecipientsCc .
1179  " | BCC: " . $externalMailRecipientsBcc .
1180  " | Subject: " . $subject
1181  );
1182 
1183  $this->sendMimeMail(
1184  $externalMailRecipientsTo,
1185  $externalMailRecipientsCc,
1186  $externalMailRecipientsBcc,
1187  $subject,
1188  $this->formatLinebreakMessage(
1189  $usePlaceholders ?
1190  $this->replacePlaceholders($message, 0, false) :
1191  $message
1192  ),
1193  $attachments
1194  );
1195  } else {
1196  $this->logger->debug('No external email addresses given in recipient string');
1197  }
1198 
1199  $errors = [];
1200 
1201  if (!$this->distributeMail(
1202  $to,
1203  $cc,
1204  $bcc,
1205  $subject,
1206  $message,
1207  $attachments,
1208  $internalMessageId,
1209  $usePlaceholders
1210  )) {
1211  $errors['mail_send_error'] = new ilMailError('mail_send_error');
1212  }
1213 
1214  if (!$this->getSaveInSentbox()) {
1215  $this->deleteMails([$internalMessageId]);
1216  }
1217 
1218  if ($this->isSystemMail()) {
1219  $random = new ilRandom();
1220  if ($random->int(0, 50) === 2) {
1222  $this->logger,
1223  $this->mfile
1224  ))->run();
1225  }
1226  }
1227 
1228  return array_values($errors);
1229  }
1230 
1237  public function validateRecipients(string $to, string $cc, string $bcc): array
1238  {
1239  try {
1240  $errors = [];
1241  $errors = array_merge($errors, $this->checkRecipients($to));
1242  $errors = array_merge($errors, $this->checkRecipients($cc));
1243  $errors = array_merge($errors, $this->checkRecipients($bcc));
1244 
1245  if (count($errors) > 0) {
1246  return array_merge([new ilMailError('mail_following_rcp_not_valid')], $errors);
1247  }
1248  } catch (ilMailException $e) {
1249  return [new ilMailError('mail_generic_rcp_error', [$e->getMessage()])];
1250  }
1251 
1252  return [];
1253  }
1254 
1255  private function getSubjectSentFolderId(): int
1256  {
1257  $send_folder_id = 0;
1258  if (!$this->isSystemMail()) {
1259  $send_folder_id = $this->mailbox->getSentFolder();
1260  }
1261 
1262  return $send_folder_id;
1263  }
1264 
1274  protected function saveInSentbox(
1275  array $attachment,
1276  string $to,
1277  string $cc,
1278  string $bcc,
1279  string $subject,
1280  string $message
1281  ): int {
1282  return $this->sendInternalMail(
1283  $this->getSubjectSentFolderId(),
1284  $this->user_id,
1285  $attachment,
1286  $to,
1287  $cc,
1288  $bcc,
1289  'read',
1290  $subject,
1291  $message,
1292  $this->user_id
1293  );
1294  }
1295 
1304  private function sendMimeMail(
1305  string $to,
1306  string $cc,
1307  string $bcc,
1308  string $subject,
1309  string $message,
1310  array $attachments
1311  ): void {
1312  $mailer = new ilMimeMail();
1313  $mailer->From($this->senderFactory->getSenderByUsrId($this->user_id));
1314  $mailer->To($to);
1315  $mailer->Subject(
1316  $subject,
1317  true,
1318  (string) ($this->contextParameters[self::PROP_CONTEXT_SUBJECT_PREFIX] ?? '')
1319  );
1320  $mailer->Body($message);
1321 
1322  if ($cc) {
1323  $mailer->Cc($cc);
1324  }
1325 
1326  if ($bcc) {
1327  $mailer->Bcc($bcc);
1328  }
1329 
1330  foreach ($attachments as $attachment) {
1331  $mailer->Attach(
1332  $this->mfile->getAbsoluteAttachmentPoolPathByFilename($attachment),
1333  '',
1334  'inline',
1335  $attachment
1336  );
1337  }
1338 
1339  $mailer->Send();
1340  }
1341 
1345  public function saveAttachments(array $attachments): void
1346  {
1347  $this->db->update(
1348  $this->table_mail_saved,
1349  [
1350  'attachments' => ['clob', serialize($attachments)],
1351  ],
1352  [
1353  'user_id' => ['integer', $this->user_id],
1354  ]
1355  );
1356  }
1357 
1363  protected function parseAddresses(string $addresses): array
1364  {
1365  if ($addresses !== '') {
1366  $this->logger->debug(sprintf(
1367  "Started parsing of recipient string: %s",
1368  $addresses
1369  ));
1370  }
1371 
1372  $parser = $this->mailAddressParserFactory->getParser($addresses);
1373  $parsedAddresses = $parser->parse();
1374 
1375  if ($addresses !== '') {
1376  $this->logger->debug(sprintf(
1377  "Parsed addresses: %s",
1378  implode(',', array_map(static function (ilMailAddress $address): string {
1379  return (string) $address;
1380  }, $parsedAddresses))
1381  ));
1382  }
1383 
1384  return $parsedAddresses;
1385  }
1386 
1387  protected function getCountRecipient(string $recipients, bool $onlyExternalAddresses = true): int
1388  {
1389  $addresses = new ilMailAddressListImpl($this->parseAddresses($recipients));
1390  if ($onlyExternalAddresses) {
1391  $addresses = new ilMailOnlyExternalAddressList(
1392  $addresses,
1393  self::ILIAS_HOST,
1394  $this->usrIdByLoginCallable
1395  );
1396  }
1397 
1398  return count($addresses->value());
1399  }
1400 
1401  protected function getCountRecipients(
1402  string $toRecipients,
1403  string $ccRecipients,
1404  string $bccRecipients,
1405  bool $onlyExternalAddresses = true
1406  ): int {
1407  return (
1408  $this->getCountRecipient($toRecipients, $onlyExternalAddresses) +
1409  $this->getCountRecipient($ccRecipients, $onlyExternalAddresses) +
1410  $this->getCountRecipient($bccRecipients, $onlyExternalAddresses)
1411  );
1412  }
1413 
1414  protected function getEmailRecipients(string $recipients): string
1415  {
1416  $addresses = new ilMailOnlyExternalAddressList(
1417  new ilMailAddressListImpl($this->parseAddresses($recipients)),
1418  self::ILIAS_HOST,
1419  $this->usrIdByLoginCallable
1420  );
1421 
1422  $emailRecipients = array_map(static function (ilMailAddress $address): string {
1423  return (string) $address;
1424  }, $addresses->value());
1425 
1426  return implode(',', $emailRecipients);
1427  }
1428 
1429  public static function _getAutoGeneratedMessageString(ilLanguage $lang = null): string
1430  {
1431  global $DIC;
1432 
1433  if (!($lang instanceof ilLanguage)) {
1435  }
1436 
1437  $lang->loadLanguageModule('mail');
1438 
1439  return sprintf(
1440  $lang->txt('mail_auto_generated_info'),
1441  $DIC->settings()->get('inst_name', 'ILIAS ' . ((int) ILIAS_VERSION_NUMERIC)),
1443  ) . "\n\n";
1444  }
1445 
1446  public static function _getIliasMailerName(): string
1447  {
1449  $senderFactory = $GLOBALS["DIC"]["mail.mime.sender.factory"];
1450 
1451  return $senderFactory->system()->getFromName();
1452  }
1453 
1458  public function appendInstallationSignature(bool $a_flag = null)
1459  {
1460  if (null === $a_flag) {
1462  }
1463 
1464  $this->appendInstallationSignature = $a_flag;
1465  return $this;
1466  }
1467 
1468  public static function _getInstallationSignature(): string
1469  {
1470  global $DIC;
1471 
1472  $signature = $DIC->settings()->get('mail_system_sys_signature', '');
1473 
1474  $clientUrl = ilUtil::_getHttpPath();
1475  $clientdirs = glob(ILIAS_WEB_DIR . '/*', GLOB_ONLYDIR);
1476  if (is_array($clientdirs) && count($clientdirs) > 1) {
1477  $clientUrl .= '/login.php?client_id=' . CLIENT_ID; // #18051
1478  }
1479 
1480  $signature = str_ireplace(
1481  '[INSTALLATION_NAME]',
1482  $DIC['ilClientIniFile']->readVariable('client', 'name'),
1483  $signature
1484  );
1485  $signature = str_ireplace(
1486  '[INSTALLATION_DESC]',
1487  $DIC['ilClientIniFile']->readVariable('client', 'description'),
1488  $signature
1489  );
1490  $signature = str_ireplace('[ILIAS_URL]', $clientUrl, $signature);
1491 
1492  if (!preg_match('/^[\n\r]+/', $signature)) {
1493  $signature = "\n" . $signature;
1494  }
1495 
1496  return $signature;
1497  }
1498 
1499  public static function getSalutation(int $a_usr_id, ?ilLanguage $a_language = null): string
1500  {
1501  global $DIC;
1502 
1503  $lang = ($a_language instanceof ilLanguage) ? $a_language : $DIC->language();
1504  $lang->loadLanguageModule('mail');
1505 
1506  $gender = ilObjUser::_lookupGender($a_usr_id);
1507  $gender = $gender ?: 'n';
1508  $name = ilObjUser::_lookupName($a_usr_id);
1509 
1510  if ($name['firstname'] === '') {
1511  return $lang->txt('mail_salutation_anonymous') . ',';
1512  }
1513 
1514  return
1515  $lang->txt('mail_salutation_' . $gender) . ' ' .
1516  ($name['title'] ? $name['title'] . ' ' : '') .
1517  ($name['firstname'] ? $name['firstname'] . ' ' : '') .
1518  $name['lastname'] . ',';
1519  }
1520 
1521  protected function getUserInstanceById(int $usrId): ?ilObjUser
1522  {
1523  if (!array_key_exists($usrId, $this->userInstancesByIdMap)) {
1524  try {
1525  $user = new ilObjUser($usrId);
1526  } catch (Exception $e) {
1527  $user = null;
1528  }
1529 
1530  $this->userInstancesByIdMap[$usrId] = $user;
1531  }
1532 
1533  return $this->userInstancesByIdMap[$usrId];
1534  }
1535 
1539  public function setUserInstanceById(array $userInstanceByIdMap): void
1540  {
1541  $this->userInstancesByIdMap = $userInstanceByIdMap;
1542  }
1543 
1544  protected function getMailOptionsByUserId(int $usrId): ilMailOptions
1545  {
1546  if (!isset($this->mailOptionsByUsrIdMap[$usrId])) {
1547  $this->mailOptionsByUsrIdMap[$usrId] = new ilMailOptions($usrId);
1548  }
1549 
1550  return $this->mailOptionsByUsrIdMap[$usrId];
1551  }
1552 
1556  public function setMailOptionsByUserIdMap(array $mailOptionsByUsrIdMap): void
1557  {
1558  $this->mailOptionsByUsrIdMap = $mailOptionsByUsrIdMap;
1559  }
1560 
1561  public function formatLinebreakMessage(string $message): string
1562  {
1563  return $message;
1564  }
1565 }
setSaveInSentbox(bool $saveInSentbox)
ilMailMimeSenderFactory $senderFactory
Class ilMailError.
formatLinebreakMessage(string $message)
Class ilMailOptions this class handles user mails.
$res
Definition: ltiservices.php:69
Global event handler.
getEmailRecipients(string $recipients)
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=[])
Class ilMailMimeSenderFactory.
__construct(int $a_user_id, ilMailAddressTypeFactory $mailAddressTypeFactory=null, ilMailRfc822AddressParserFactory $mailAddressParserFactory=null, ilAppEventHandler $eventHandler=null, ilLogger $logger=null, ilDBInterface $db=null, ilLanguage $lng=null, ilFileDataMail $mailFileData=null, ilMailOptions $mailOptions=null, ilMailbox $mailBox=null, ilMailMimeSenderFactory $senderFactory=null, callable $usrIdByLoginCallable=null, int $mailAdminNodeRefId=null, ilObjUser $actor=null)
countMailsOfFolder(int $folderId)
$context
Definition: webdav.php:29
const ANONYMOUS_USER_ID
Definition: constants.php:27
static getLogger(string $a_component_id)
Get component logger.
int $maxRecipientCharacterLength
ilMailbox $mailbox
const ILIAS_VERSION_NUMERIC
$errors
Definition: imgupload.php:65
int $mail_obj_ref_id
const ILIAS_HOST
markUnread(array $mailIds)
array $mail_data
delegateExternalEmails(string $subject, string $message, array $attachments, bool $usePlaceholders, array $usrIdToExternalEmailAddressesMap, array $usrIdToMessageMap)
This class handles all operations on files (attachments) in directory ilias_data/mail.
ilLanguage $lng
appendInstallationSignature(bool $a_flag=null)
checkMail(string $to, string $cc, string $bcc, string $subject)
existsRecipient(string $newRecipient, string $existingRecipients)
getCountRecipients(string $toRecipients, string $ccRecipients, string $bccRecipients, bool $onlyExternalAddresses=true)
const CONTEXT_CRON
getMailsOfFolder(int $a_folder_id, array $filter=[])
const PROP_CONTEXT_SUBJECT_PREFIX
sendMimeMail(string $to, string $cc, string $bcc, string $subject, string $message, array $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 &#39;mail&#39;.
getUserInstanceById(int $usrId)
static _lookupName(int $a_user_id)
lookup user name
static _lookupId($a_user_str)
setUsrId(int $usrId)
Class ilMailOnlyExternalAddressList.
ilAppEventHandler $eventHandler
deleteMailsOfFolder(int $folderId)
static _lookupPref(int $a_usr_id, string $a_keyword)
array $contextParameters
saveInSentbox(array $attachment, string $to, string $cc, string $bcc, string $subject, string $message)
getPreviousMail(int $mailId)
static _lookupGender(int $a_user_id)
int $user_id
Class ilMailDiffAddressList.
getCountRecipient(string $recipients, bool $onlyExternalAddresses=true)
retrieveFromStage()
withContextParameters(array $parameters)
global $DIC
Definition: feed.php:28
saveAttachments(array $attachments)
static strLen(string $a_string)
Definition: class.ilStr.php:63
if($format !==null) $name
Definition: metadata.php:247
ilFileDataMail $mfile
Class ilMailRfc822AddressParserFactory.
bool $appendInstallationSignature
string $contextId
ilDBInterface $db
fetchMailData(?array $row)
withContextId(string $contextId)
isSystemMail()
Mail Box class Base class for creating and handling mail boxes.
static getSalutation(int $a_usr_id, ?ilLanguage $a_language=null)
checkRecipients(string $recipients)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const CLIENT_ID
Definition: constants.php:41
bool $save_in_sentbox
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
getMailOptionsByUserId(int $usrId)
ilMailRfc822AddressParserFactory $mailAddressParserFactory
string $table_mail_saved
$query
$usrIdByLoginCallable
getSaveInSentbox()
setUserInstanceById(array $userInstanceByIdMap)
ilMailOptions $mail_options
static _getLanguage(string $a_lang_key='')
Get language object.
Class ilMailTemplatePlaceholderResolver.
getMailObjectReferenceId()
distributeMail(string $to, string $cc, string $bcc, string $subject, string $message, array $attachments, int $sentMailId, bool $usePlaceholders=false)
validateRecipients(string $to, string $cc, string $bcc)
$lang
Definition: xapiexit.php:26
getNewDraftId(int $folderId)
getMail(int $mailId)
static _getHttpPath()
ilMailAddressTypeFactory $mailAddressTypeFactory
formatNamesForOutput(string $recipients)
deleteMails(array $mailIds)
Wrapper for generation of random numbers, strings, bytes.
static _getAutoGeneratedMessageString(ilLanguage $lang=null)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
string $table_mail
getNextMail(int $mailId)
ilLogger $logger
array $mailOptionsByUsrIdMap
setMailOptionsByUserIdMap(array $mailOptionsByUsrIdMap)
sendInternalMail(int $folderId, int $senderUsrId, array $attachments, string $to, string $cc, string $bcc, string $status, string $subject, string $message, int $usrId=0, bool $usePlaceholders=false, ?string $templateContextId=null, array $templateContextParameters=[])
sendChanneledMails(string $to, string $cc, string $bcc, array $usrIds, string $subject, string $message, array $attachments, int $sentMailId, bool $usePlaceholders=false)
$message
Definition: xapiexit.php:32
getUserIds(array $recipients)
static getType()
Get context type.
replacePlaceholders(string $message, int $usrId=0, bool $replaceEmptyPlaceholders=true)
markRead(array $mailIds)
sendMail(string $to, string $cc, string $bcc, string $subject, string $message, array $attachments, bool $usePlaceholders)
This method is used to finally send internal messages and external emails To use the mail system as a...
getSubjectSentFolderId()
parseAddresses(string $addresses)
Explode recipient string, allowed separators are &#39;,&#39; &#39;;&#39; &#39; &#39;.
Class ilMailAddressTypeFactory.
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=[])
ilObjUser $actor
moveMailsToFolder(array $mailIds, int $folderId)
readMailObjectReferenceId()
Class ilMailAddress.
static _getInstallationSignature()
array $userInstancesByIdMap
const ILIAS_WEB_DIR
Definition: constants.php:45
Class ilMailAddressListImpl.