1# Mail
2
3ILIAS provides several classes to create and
4send Emails/Messages for different purposes.
5
6The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
7“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be
8interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
9
10**Table of Contents**
11* [General](#general)
12  * [Delivery Channels](#delivery-channels)
13  * [External Emails: HTML Frame](#external-emails-html-frame)
14* [ilMail](#ilmail)
15  * [Recipients](#recipients)
16      * [Supported Recipient String Examples](#supported-recipient-string-examples)
17      * [Syntax Rules](#syntax-rules)
18      * [Semantics](#semantics)
19  * [Subject and Body](#subject-and-body)
20* [ilMimeMail](#ilmimemail)
21  * [Sender](#sender)
22  * [Transport](#transport)
23* [ilMailNotification](#ilmailnotification)
24* [ilSystemNotification](#ilsystemnotification)
25* [ilAccountMail](#ilaccountmail)
26* [Manual Mail Templates](#manual-mail-templates)
27  * [Context Registration](#context-registration)
28  * [Context Usage Example](#context-usage-example)
29* [ilMassMailTaskProcessor](#ilmassmailtaskprocessor)
30
31## General
32
33The following chapters will describe and explain which purposes
34each class has and how to use them.
35
36All of the following described classes and code snippets
37rely on a valid email server configuration and meaningful
38settings in the global ILIAS email administration.
39
40A short introduction of some base features/concepts
41will be given before the respective classes are
42substantiated.
43
44### Delivery Channels
45
46The delivery channel for messages MAY be based
47on individual settings by each user. These settings
48can be configured for each user via the ILIAS GUI.
49
50There are two possible recipient channels:
51* internal - Users on the system will be addressed.
52  Internal messages will be delivered to the internal
53  inbox, which is accessible via the ILIAS user
54  interface.
55* external - The email will be sent to an external address
56  outside of the ILIAS context.
57
58Both channels can be combined, so the user
59will receive messages on both channels.
60
61### External Emails: HTML Frame
62
63With ILIAS 5.1.x the [HTML Mails with Skin](https://www.ilias.de/docu/goto_docu_wiki_wpage_3506_1357.html)
64were introduced.
65
66Text emails sent to an **external** email address
67can be displayed in a HTML frame. The HTML template
68is part of the skin:
69
70    ./Services/Mail/templates/default/tpl.html_mail_template.html
71
72There are no advanced formatting options, except
73the global format given in the HTML file itself.
74HTML templates as a frame can only be used when a
75skin was set/configured as *default system-style* in
76`Administration » Layout and Styles » System Styles`.
77The configuration is stored and read from
78your `client.ini.php` file located in your internal
79data directory ('./data/<CLIENT_ID/').
80
81Example:
82```
83[layout]
84skin = "default"
85style = "delos"
86```
87
88Emails are sent without HTML frame and as raw plain/text
89when no template can be determined.
90
91Per Skin, one HTML template can be defined and has to be
92stored in the following location:
93
94    ./Customizing/global/skin/<NAME>/Services/Mail/tpl.html_mail_template.html.
95
96The HTML frame template concept consists of the HTML
97markup file itself and some optional attachments.
98Images of type \*.jp(e)g MUST be stored in a sub-folder *img*.
99It is possible to attach several image attachments.
100Images are packed into the email as inline images,
101regardless of their use.
102The source of the images is prefixed with a *cid*.
103The *cid* of an image with the file name "foo.jpg"
104will be *img/foo.jpg*.
105
106Other file types (like \*.png, \*.gif, \*.bmp, etc.) will
107be silently ignored. This is not considered to be a bug,
108but a design limitation ([http://www.ilias.de/mantis/view.php?id=18878](http://www.ilias.de/mantis/view.php?id=18878)).
109
110This feature does not apply for ILIAS-internal messages at all.
111
112## ilMail
113
114`\ilMail` is the central class of *Services/Mail* and acts as
115some kind of reduced and **medium level** notification system
116dealing only with internal and external emails.
117It does neither care about low-level transport of messages
118(e.g. like sending external emails via SMTP), nor does it
119act like a centralized notification system dealing with
120any kind/type of notification in ILIAS.
121
122The constructor of class `\ilMail` requires the
123internal ILIAS id of the sender's user account.
124For *System Emails* you MUST use the global
125constant **ANONYMOUS_USER_ID**.
126In the context of the mail service the
127term *System Emails* describes every email
128communication that is initiated and completed
129without manual editing.
130A *System Email* is not one that can be directly
131sent to one or more users by an interaction in the
132user interface.
133
134Examples:
135
136* User joined course
137* User created forum posting
138* ...
139
140The intended public API for sending messages is
141the `enqueue()` method.
142Other methods like `sendMimeMail()` are public
143as well but not intended to be used by consumers.
144
145Simple Example:
146
147```php
148global $DIC;
149
150$senderUserId = $DIC->user()->getId();
151
152$to = 'root';
153$cc = 'john.doe';
154$bc = 'max.mustermann';
155$subject = 'Make ILIAS great again!';
156$message = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor.";
157$attachments = [];
158
159$mail = new \ilMail($senderUserId);
160$mail->enqueue(
161    $to,
162    $cc,
163    $bc,
164    $subject,
165    $message,
166    $attachments
167);
168```
169
170### Recipients
171
172The `$to`, `$cc` and `$bcc` recipient arguments
173MUST be passed as string primitives.
174Multiple recipients for TO, CC and BCC MUST be
175concatenated with a `,` character.
176
177```php
178$to = 'john.doe@ilias.de, root, #il_role_1000';
179```
180
181The following recipient address types are supported:
182
183* Email addresses
184* Usernames
185* String representations of mailing lists
186* Group repository object titles (as long as they are globally unique)
187* String representations of local roles in courses and groups
188* String representations of roles in general
189
190Class `\ilMail` respects the configured transport channels for each evaluated
191user account parsed from the recipient strings.
192
193ILIAS is enabled to use standards compliant email addresses. `\ilMail`
194and the underlying address parsers support RFC 822 compliant address
195lists as specified in [RFC0822.txt](http://www.ietf.org/rfc/rfc0822.txt).
196
197The address parser below *./Services/Mail/classes/Address* could
198be considered as a separate service. To get an address parser you
199can simply use an instance of `ilMailRfc822AddressParserFactory`
200and pass a comma separated string of recipients.
201
202#### Supported Recipient String Examples
203
204The following mailbox addresses work for sending an email to the user with the
205login john.doe and email address jd@mail.com.
206The user is member of the course "French Course".
207The member role of the course object has the name "il_crs_member_998".
208Furthermore the user was assigned to a mailing list with the internal
209id "4711".
210
211* john.doe
212* John Doe <john.doe>
213* john.doe@ilias
214* \#member@\[French Course\]
215* \#il_crs_member_998
216* \#il_role_1000
217* jd@mail.com
218* John Doe <jd@mail.com>
219* \#il_ml_4711
220
221#### Syntax Rules
222
223The following excerpt from chapter 6.1 "Syntax" of RFC 822 is relevant for
224the semantics described below:
225
226    addr-spec = local-part [ "@", domain ]
227
228#### Semantics
229
230User account mailbox address:
231* The local part denotes the login of an ILIAS user account.
232* The domain denotes the current ILIAS client.
233* The local part MUST NOT start with a "#" character.
234* The domain MUST be omitted or MUST have the value "ilias".
235* Examples: john.doe / john.doe@iliasjohn.doe
236
237Role object mailbox address:
238* The local part denotes the title of an ILIAS role.
239* The domain denotes the title of an ILIAS repository object.
240* The local part MUST start with a "#" character.
241* If the local part starts with "#il_role_" its remaining characters directly specify the object id of the role. For example "#il_role_1234 identifies the role with object id "1234".
242* If the object title identifies an object that is an ILIAS role, then the local-part is ignored.
243* If the object title identifies an object that is not an ILIAS role, then the local-part is used to identify a local role for that object.
244* The local part can be a substring of the role name. For example, "#member" can be used instead of "#il_crs_member_1234".
245* Examples: \#il_role_1000 / \#il_crs_member_998 / \#member@\[French Course\]
246* Such addresses can be created by `\ilRoleMailboxAddress`
247
248External email address:
249* The local part MUST NOT start with a "#" character.
250* The domain MUST be specified and it MUST not have the value "ilias".
251* Examples: \#il_ml_4711
252
253Mailing list:
254* The local part denotes the mailing list.
255* The local part MUST start with a "#" character, followed by the character sequence "il_ml_" and the internal id of the mailing list.
256* The domain MUST be omitted.
257* Examples: John Doe <jd@mail.com> / john.doe@ilias
258
259After recipient strings being parsed by a `RFC822`
260address parser, the corresponding user id resolvers
261are determined in `\ilMailAddressTypeFactory::getByPrefix`.
262
2631. If the first character of the parsed RFC822 compliant
264address does **not** equal `#` **and** the first two characters
265do **not** equal `"\#`, the address is supposed to be an external
266email address or an ILIAS username.
2672. If the first seven characters of the parsed RFC822 compliant
268address equal `#il_ml_`, the address is supposed to be a
269mailing list and the assigned user accounts are used as
270recipients, if you as the sender are the owner of this list.
2713. If the the parsed RFC822 compliant address is a
272valid group name, the address is supposed to be a
273Group and the respective members will be used as recipients.
2744. In all other cases the parsed RFC822 compliant address
275is supposed to be a role representation and the resolver
276fetches the assigned users as recipients for the email.
277
278### Subject and Body
279
280Beside the recipients the API accepts subject
281and body of the message, both being of type *plain/text*.
282The consumer MUST ensure that the message does
283not contain any HTML.
284Line breaks MUST be provided by a line feed (LF) character.
285Violations against this rule may raise exceptions in
286future ILIAS releases.
287
288Currently the mail system tries to magically detect
289whether or not the message body passed by consumers
290contains any HTML when sending **external**
291[emails with an HTML frame and a plain/text alternative](#external-emails:-html-frame).
292This is done in `\ilMimeMail::buildBodyParts`.
293If no HTML is included at all, or only a few inline
294elements (\<b\>, \<u\>, \<i\>, \<a\>) are given, a
295[`nl2br()`](http://php.net/manual/en/function.nl2br.php)
296is applied on the body and used for the HTML version
297of the email. The originally passed body is used as
298plain/text alternative.
299If HTML is detected in the body string passed by the
300consumer, the original body is used for the HTML email.
301For the plain/text alternative, `<br>` elements are replaced
302with a `\n` (LF) character and
303[`strip_tags'](http://php.net/manual/en/function.strip-tags.php)
304is applied afterwards on the originally passed message body.
305
306This behaviour is not specified at all and also tries
307to handle/fix misusage by consumers.
308The rule is: You MUST NOT pass any HTML.
309
310For **internal** messages HTML is completely escaped
311on the UI endpoint via `\ilUtil::htmlencodePlainString`.
312
313### Attachments
314
315The `$attachments` can be passed as an array of file names.
316Each file MUST have been assigned to the sending user account
317in a prior step.
318This can be done as described in the following examples:
319
320```php
321$attachment = new \ilFileDataMail($senderUserId);
322
323$attachment->storeAsAttachment(
324    'appointment.ics', $someIcalString
325);
326
327$attachment->copyAttachmentFile(
328    '/temp/hello.jpg', 'HelloWorld.jpg'
329);
330
331$mail = new \ilMail($senderUserId);
332$mail->enqueue(
333    $to,
334    $cc,
335    $bc,
336    $subject,
337    $message,
338    [
339        'appointment.ics',
340        'HelloWorld.jpg'
341    ],
342    array("system")
343);
344
345// or $attachment->unlinkFiles(['/temp/hello.jpg']);
346$attachment->unlinkFile('/temp/hello.jpg');
347```
348
349As outlined above attachments have to be removed
350manually by the consumer after the transport of an
351email has been delegated to the mail system.
352
353## ilMimeMail
354
355`\ilMimeMail` is a **low level** class to create and send
356an external email in the
357[Multipurpose Internet Mail Extensions(MIME)](https://en.wikipedia.org/wiki/MIME)
358format.
359
360It SHOULD be used whenever you want to explicitly send
361an email to external email addresses and you don't want to
362use one of the existing wrappers described below.
363This class is mainly used for external procedures, e.g. if
364user has not yet access to ILIAS, e.g. in the
365registration process.
366
367```php
368global $DIC;
369
370/** @var \ilMailMimeSenderFactory $senderFactory */
371$senderFactory = $DIC["mail.mime.sender.factory"];
372$sender        = $senderFactory->system();
373
374$mailer = new \ilMimeMail();
375$mailer->From($sender);
376
377$mailer->To(explode(',', [
378    'dummy1@gmail.com',
379    'dummy2@web.de',
380]));
381$mailer->Cc(explode(',', [
382    'dummy3@yahoo.com'
383]));
384$mailer->Bcc(explode(',', [
385    'dummy4@aol.com'
386]));
387
388$mailer->Subject($subject);
389$mailer->Body($plainText);
390
391$mailer->Attach(
392    '/srv/www/ilias5/data/defaultclient/ilFile/4/file_400/001/composer.json',
393    'application/json',
394    'inline',
395    'Composer.json'
396);
397$mailer->Attach(
398    '/srv/www/ilias5/data/defaultclient/ilFile/4/file_401/001/composer.json',
399    'application/json',
400    'inline',
401    'AnotherComposer.json'
402);
403
404$mailer->Send();
405```
406
407Subject and body MUST be of type plain text and MUST NOT contain any HTML fragments.
408When preparing the email transport `\ilMimeMail` wraps an HTML structure around
409the message body (see: [HTML Mails with Skin](https://www.ilias.de/docu/goto_docu_wiki_wpage_3506_1357.html))
410passed by the consumer. It automatically transforms newline characters (LF/CR)
411to HTML linebreak elements.
412The original message body is used as *text/plain* alternative, the processed
413body is used as *text/html* alternative.
414
415### Sender
416
417Since ILIAS 5.3.x the `$sender` cannot be passed as a primitive
418data type anymore. A sender MUST implement `\ilMailMimeSender`.
419ILIAS currently provides two different implementations:
420
4211. `\ilMailMimeSenderSystem`
4222. `\ilMailMimeSenderUser`
423
424Both instances can be retrieved by the globally available `\ilMailMimeSenderFactory`,
425registered in the dependency container (`$DIC["mail.mime.sender.factory"]`).
426
427The first MUST be used whenever an email is sent with the purpose of a *System Email*.
428The second type MUST be used for a *User-to-User Email*.
429
430### Transport
431
432The actual transport is decoupled from `\ilMimeMail`. `\ilMimeMail` uses
433the determined transport strategy given by the
434`\ilMailMimeTransportFactory` instance which is available in
435the dependency injection container (`$DIC["mail.mime.transport.factory"]`).
436
437A transport strategy MUST follow the definition of
438the `\ilMailMimeTransport` interface. A different transport could be
439globally set via `\ilMimeMail::setDefaultTransport`, or just for
440the next call of `Send()` by passing an instance of `\ilMailMimeTransport` as
441argument:
442
443```php
444$mailer->Send($transport);
445```
446
447## ilMailNotification
448
449`\ilMailNotification` is a **higher level** abstraction
450wrapping `\ilMail`. It can be extended to create a custom
451email for a specific purpose of your component or plugin.
452
453Every service/module/plugin in ILIAS MAY create a specialized class
454for creating and sending emails. Therefore it MUST use inheritance
455and derive from `\ilMailNotification`.
456
457```php
458class MyMailNotification extends \ilMailNotification
459{
460    // [...]
461    public function send()
462    {
463        try
464        {
465            $this->setSubject('Welcome to ILIAS');
466            $this->setBody('Hello World!');
467            $this->appendBody(\ilMail::_getInstallationSignature());
468
469            $this->sendMail($this->getRecipients());
470        }
471        catch(\ilMailException $e)
472        {
473            // Error handling
474        }
475    }
476    // [...]
477}
478```
479
480The usage could look like this:
481
482```php
483$myMailNotification = new \MyMailNotification();
484$myMailNotification->setRecipients(
485    [
486        4711, 666
487    ]
488);
489$myMailNotification->send();
490```
491
492If the recipients could only be/are already
493provided as usernames or email addresses,
494you can use the third parameter of `sendMail()`
495and pass a boolean `false`.
496If you pass `true` as third argument or don't pass
497a third argument at all, the elements of the first
498parameter array are considered to be the internal
499user ids of the recipients and the corresponding
500usernames will be determined automatically when
501`sendMail()` is called.
502
503```php
504class MyMailNotification extends \ilMailNotification
505{
506    // [...]
507    public function send()
508    {
509        try
510        {
511            $this->setSubject('Welcome to ILIAS');
512            $this->setBody('Hello World!');
513            $this->appendBody(\ilMail::_getInstallationSignature());
514
515            $this->sendMail($this->getRecipients(), false);
516        }
517        catch(\ilMailException $e)
518        {
519            // Error handling
520        }
521    }
522    // [...]
523}
524```
525
526The usage could look like this:
527
528```php
529$myMailNotification = new \MyMailNotification();
530$myMailNotification->setRecipients(
531    [
532        'root', 'dummy@gmail.com'
533    ]
534);
535$myMailNotification->send();
536```
537
538If you explicitly need to send an external email you
539can use/extend from `\ilMimeMailNotification`. This class itself
540also derives from `\ilMailNotification`.
541
542Recipients can be provided as:
543
544* Instances of \ilObjUser
545* The internal user id
546* Email address
547
548```php
549class ilRegistrationMailNotification extends \ilMimeMailNotification
550{
551    // [...]
552    public function send()
553    {
554        try
555        {
556            foreach ($this->getRecipients() as $rcp) {
557                $this->initMail();
558                $this->initLanguage($rcp);
559                $this->setSubject('Welcome to ILIAS');
560                $this->setBody('Hello World!');
561                $this->appendBody(\ilMail::_getInstallationSignature());
562
563                $this->getMail()->appendInstallationSignature(true);
564                $this->sendMail(array($rcp));
565            }
566        }
567        catch(\ilMailException $e)
568        {
569            // Error handling
570        }
571    }
572    // [...]
573}
574```
575
576The usage could look like this:
577
578```php
579$myMailNotification = new \ilRegistrationMailNotification();
580$myMailNotification->setRecipients([
581    6,
582    new ilObjUser(6),
583    'dummy@gmail.com'
584]);
585$myMailNotification->send();
586```
587
588## ilSystemNotification
589
590`\ilSystemNotification` is a commonly used implementation
591of the previous explained `\ilMailNotification`.
592
593This class is used to create an email sent by the ILIAS
594system with a more or less given structure and text layout.
595The implementation is used by several modules/services
596to create their own emails.
597
598```php
599$mail = new \ilSystemNotification();
600$mail->setLangModules(array('user'));
601$mail->setRefId($refId);
602$mail->setChangedByUserId($user->getId());
603$mail->setSubjectLangId('my_subject');
604$mail->setIntroductionLangId('my_body');
605$mail->addAdditionalInfo('additional_info', 'The title');
606$mail->setGotoLangId('exc_team_notification_link');
607$mail->setReasonLangId('my_reason');
608$mail->sendMail(array($targetUser->getId()));
609```
610
611## ilAccountMail
612
613An instance of `\ilAccountMail` MUST be used to sent
614external emails whenever a user account was created
615in ILIAS. It's main purpose is to provide user
616account information in the self registration process.
617
618The contents of this email can be configured in
619**Administration » User Management » New Account Mail**.
620Subject and body can be defined for each installed
621language. Furthermore placeholders can be used, being
622replaced with the user's account data when the email
623is sent:
624
625* \[MAIL_SALUTATION\]: Salutation
626* \[FIRST_NAME\]: First Name
627* \[LAST_NAME\]: Last Name
628* \[EMAIL\]: E-Mail
629* \[LOGIN\]: Login Account
630* \[PASSWORD\]: Password
631* \[IF_PASSWORD\]...\[/IF_PASSWORD\]: This text block is only included, if the new user account has been created including a password.
632* \[IF_NO_PASSWORD\]...\[/IF_NO_PASSWORD\]: This text block is only included, if the new user account has been created without a password.
633* \[ADMIN_MAIL\]: Email address of Administrator
634* \[ILIAS_URL\]: URL of ILIAS system
635* \[CLIENT_NAME\]: Client Name
636* \[TARGET\]: URL of target item, e.g. a linked course that is passed to ILIAS from outside.
637* \[TARGET_TITLE\]: Title of target item, e.g. course title.
638* \[TARGET_TYPE\]: Type of target item, e.g. ‘Course’ for a course item.
639* \[IF_TARGET\]...\[/IF_TARGET\]: This text is only included, if a target item is provided.
640* \[IF_TIMELIMIT\]...\[/IF_TIMELIMIT\]: This text is only included, if the user has a limited access period.
641* \[TIMELIMIT\]: User access period
642
643The object tries to determine subject and body based
644on the user's language. If this fails, the system
645language is used as a fallback for determination.
646If this fails again, there is an optional second
647fallback by using the following language variables:
648
649* reg_mail_body_salutation
650* reg_mail_body_text1
651* reg_mail_body_text2
652* reg_mail_body_text3
653
654```php
655global $DIC;
656
657$user = $DIC->user();
658
659$accountMail = new \ilAccountMail();
660$accountMail->setUser($user);
661
662$accountMail->send();
663```
664
665This will create a default message with the look
666of a registration email.
667
668To enable the language variable fallback the
669following mutator has to be called with a
670boolean true as it's argument:
671```php
672$accountMail->useLangVariablesAsFallback(true);
673```
674If a raw password should be included, it MUST be
675explicitly set via:
676```php
677$accountMail->setUserPassword($rawPassword);
678 ```
679
680Internally `\ilAccountMail` makes use of `\ilMimeMail`.
681
682## Manual Mail Templates
683
684The concept of ['Manual Mail Templates'](https://www.ilias.de/docu/goto_docu_wiki_wpage_2703_1357.html) is best described
685as a feature which enables services/modules to
686provide text templates for a 'User-to-User Email' in a
687specific context.
688
689Often tutors / admins send the emails with the same purpose
690and texts to course members, e.g. to ask them if they
691have problems with the course because they have not
692used the course yet.
693
694### Context Registration
695
696A module or service MAY announce its email template
697contexts to the system by adding them to their
698respective *module.xml* or *service.xml*.
699The template context id has to be globally unique.
700An optional path can be added if the module/service
701directory layout differs from the ILIAS standard,
702where most files are located in a `./classes`
703directory.
704
705```xml
706<?xml version = "1.0" encoding = "UTF-8"?>
707<module xmlns="http://www.w3.org" version="$Id$" id="crs">
708    ...
709    <mailtemplates>
710        <context id="crs_context_manual" class="ilCourseMailTemplateContext" />
711    </mailtemplates>
712</module>
713```
714
715If registered once, every email template context
716class defined in a *module.xml* or *service.xml*
717has to extend the base class `\ilMailTemplateContext`.
718All abstract methods MUST be implemented to make
719a template context usable.
720
721* getId(): string
722* getTitle(): string
723* getDescription(): string
724* getSpecificPlaceholders(): array
725* resolveSpecificPlaceholder(string $placeholderId, array $contextParameters, \ilObjUser $recipient = null, $htmlMarkup = false): string
726
727A collection of context specific placeholders
728can be returned by a simple array definition.
729The key of each element should be a unique
730placeholder id.
731Each placeholder contains (beside its id) a
732placeholder string and a label which is used
733in the user interfaced.
734
735```php
736return array(
737    'crs_title' => array(
738        'placeholder' => 'CRS_TITLE',
739        'label' => $lng->txt('crs_title')
740    ),
741    'crs_link' => array(
742        'placeholder' => 'CRS_LINK',
743        'label' => $lng->txt('crs_mail_permanent_link')
744    )
745);
746```
747
748Supposing the context registration succeeded and you
749properly derived a context PHP class providing all
750necessary data and placeholders, you are now
751able to use your registered context in your component
752and build hyperlinks to the mail system, transporting
753your context information.
754
755### Context Usage Example
756
757Given you created a context named `crs_context_tutor_manual` ...
758
759```php
760global $DIC;
761
762class ilCourseMailTemplateTutorContext extends \ilMailTemplateContext
763{
764    // [...]
765    const ID = 'crs_context_tutor_manual';
766    // [...]
767}
768```
769
770... you can provide a hyperlink to the mail system (or
771more precisely to `\ilMailFormGUI`) as follows:
772
773```php
774$DIC->ctrl()->redirectToUrl(
775    \ilMailFormCall::getRedirectTarget(
776        $this, // The referring ILIAS controller aka. GUI when redirecting back to the referrer
777        'participants', // The desired command aka. the method to be called when redirecting back to the referrer
778        array(), // Key/Value array for parameters important for the ilCtrl/GUI context when when redirecting back to the referrer, e.g. a ref_id
779        array(
780           'type' => 'new', // Could also be 'reply' with an additional 'mail_id' paremter provided here
781        ),
782        array(
783            \ilMailFormCall::CONTEXT_KEY => \ilCourseMailTemplateTutorContext::ID, // don't forget this!
784            'ref_id' => $courseRefId,
785            'ts'     => time(),
786            // further parameters which will be later automatically passed to your context class
787        )
788    )
789);
790```
791
792Parameters required by your mail context class
793MUST be provided as a key/value pair array in the
794fifth parameter of `\ilMailFormCall::getRedirectTarget`.
795These parameters will be passed back to
796your context class when the mail system uses
797`\ilMailTemplateContext::resolveSpecificPlaceholder(...)`
798as callback when an email is actually sent and included
799placeholders should be replaced.
800You also MUST add a key `\ilMailFormCall::CONTEXT_KEY`
801with your context id as value to this array.
802
803## ilMassMailTaskProcessor
804
805Sending more then 1000 mails **at once** can lead that mails can be missing,
806because the responding API couldn't process all requests so fast.
807
808The `ilMassMailTaskProcessor` can be used to transfer these mails into
809background tasks, which can be used to relieve the API.
810
811```php
812$processor = new ilMassMailTaskProcessor();
813$processor->run(
814		$mailValueObjects,    // array of ilMailValueObject
815		$userId,              // integer value of the current user id
816		$contextId,           // integer value of the context id
817		$contextParameters,   // array of context parameters, check out the documentation of backgroundtasks for more information
818		$mailsPerTask         // integer value how many mails should be added in each task, default value is 100
819);
820```
821
822The amount of mails before the background task will be executed can be defined
823by passing a positive integer in the **fifth parameter**.
824Be aware that a high integer for mails per task can exhaust the mail API.
825We recommend to keep this value below 1000 mails per task to ensure that every mail can be sent.
826