• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..24-Nov-2021-

classes/H24-Nov-2021-20,14712,459

exceptions/H24-Nov-2021-114

interfaces/H24-Nov-2021-12430

js/H03-May-2022-

templates/default/img/H24-Nov-2021-

test/H24-Nov-2021-1,7091,102

LuceneDataSource.xmlH A D24-Nov-20211.7 KiB3534

README.mdH A D24-Nov-202125.5 KiB812665

maintenance.jsonH A D24-Nov-2021358 1414

phpunit.xmlH A D24-Nov-2021715 2525

service.xmlH A D24-Nov-2021901 2928

README.md

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
30## General
31
32The following chapters will describe and explain which purposes
33each class has and how to use them.
34
35All of the following described classes and code snippets
36rely on a valid email server configuration and meaningful
37settings in the global ILIAS email administration.
38
39A short introduction of some base features/concepts
40will be given before the respective classes are
41substantiated.
42
43### Delivery Channels
44
45The delivery channel for messages MAY be based
46on individual settings by each user. These settings
47can be configured for each user via the ILIAS GUI.
48
49There are two possible recipient channels:
50* internal - Users on the system will be addressed.
51  Internal messages will be delivered to the internal
52  inbox, which is accessible via the ILIAS user
53  interface.
54* external - The email will be sent to an external address
55  outside of the ILIAS context.
56
57Both channels can be combined, so the user
58will receive messages on both channels.
59
60### External Emails: HTML Frame
61
62With ILIAS 5.1.x the [HTML Mails with Skin](https://www.ilias.de/docu/goto_docu_wiki_wpage_3506_1357.html)
63were introduced.
64
65Text emails sent to an **external** email address
66can be displayed in a HTML frame. The HTML template
67is part of the skin:
68
69    ./Services/Mail/templates/default/tpl.html_mail_template.html
70
71There are no advanced formatting options, except
72the global format given in the HTML file itself.
73HTML templates as a frame can only be used when a
74skin was set/configured as *default system-style* in
75`Administration » Layout and Styles » System Styles`.
76The configuration is stored and read from
77your `client.ini.php` file located in your internal
78data directory ('./data/<CLIENT_ID/').
79
80Example:
81```
82[layout]
83skin = "default"
84style = "delos"
85```
86
87Emails are sent without HTML frame and as raw plain/text
88when no template can be determined.
89
90Per Skin, one HTML template can be defined and has to be
91stored in the following location:
92
93    ./Customizing/global/skin/<NAME>/Services/Mail/tpl.html_mail_template.html.
94
95The HTML frame template concept consists of the HTML
96markup file itself and some optional attachments.
97Images of type \*.jp(e)g MUST be stored in a sub-folder *img*.
98It is possible to attach several image attachments.
99Images are packed into the email as inline images,
100regardless of their use.
101The source of the images is prefixed with a *cid*.
102The *cid* of an image with the file name "foo.jpg"
103will be *img/foo.jpg*.
104
105Other file types (like \*.png, \*.gif, \*.bmp, etc.) will
106be silently ignored. This is not considered to be a bug,
107but a design limitation ([http://www.ilias.de/mantis/view.php?id=18878](http://www.ilias.de/mantis/view.php?id=18878)).
108
109This feature does not apply for ILIAS-internal messages at all.
110
111## ilMail
112
113`\ilMail` is the central class of *Services/Mail* and acts as
114some kind of reduced and **medium level** notification system
115dealing only with internal and external emails.
116It does neither care about low-level transport of messages
117(e.g. like sending external emails via SMTP), nor does it
118act like a centralized notification system dealing with
119any kind/type of notification in ILIAS.
120
121The constructor of class `\ilMail` requires the
122internal ILIAS id of the sender's user account.
123For *System Emails* you MUST use the global
124constant **ANONYMOUS_USER_ID**.
125In the context of the mail service the
126term *System Emails* describes every email
127communication that is initiated and completed
128without manual editing.
129A *System Email* is not one that can be directly
130sent to one or more users by an interaction in the
131user interface.
132
133Examples:
134
135* User joined course
136* User created forum posting
137* ...
138
139The intended public API for sending messages is
140the `sendMail()` method.
141Other methods like `sendMimeMail()` are public
142as well but not intended to be used by consumers.
143
144Simple Example:
145
146```php
147global $DIC;
148
149$senderUserId = $DIC->user()->getId();
150
151$to = 'root';
152$cc = 'john.doe';
153$bc = 'max.mustermann';
154$subject = 'Make ILIAS great again!';
155$message = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor.";
156$attachments = [];
157
158$mail = new \ilMail($senderUserId);
159$mail->sendMail(
160    $to,
161    $cc,
162    $bc,
163    $subject,
164    $message,
165    $attachments,
166    [array("normal")](#recipients)
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->sendMail(
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### Type
354
355The type string MUST be one of the following options:
356
357* normal
358* system (displayed in a separate block at the *Personal Desktop*)
359
360Messages marked as *system* will not be delivered to the recipient if he/she
361did not accept the *Terms of Service*, or he/she has an expired user account.
362
363## ilMimeMail
364
365`\ilMimeMail` is a **low level** class to create and send
366an external email in the
367[Multipurpose Internet Mail Extensions(MIME)](https://en.wikipedia.org/wiki/MIME)
368format.
369
370It SHOULD be used whenever you want to explicitly send
371an email to external email addresses and you don't want to
372use one of the existing wrappers described below.
373This class is mainly used for external procedures, e.g. if
374user has not yet access to ILIAS, e.g. in the
375registration process.
376
377```php
378global $DIC;
379
380/** @var \ilMailMimeSenderFactory $senderFactory */
381$senderFactory = $DIC["mail.mime.sender.factory"];
382$sender        = $senderFactory->system();
383
384$mailer = new \ilMimeMail();
385$mailer->From($sender);
386
387$mailer->To(explode(',', [
388    'dummy1@gmail.com',
389    'dummy2@web.de',
390]));
391$mailer->Cc(explode(',', [
392    'dummy3@yahoo.com'
393]));
394$mailer->Bcc(explode(',', [
395    'dummy4@aol.com'
396]));
397
398$mailer->Subject($subject);
399$mailer->Body($plainText);
400
401$mailer->Attach(
402    '/srv/www/ilias5/data/defaultclient/ilFile/4/file_400/001/composer.json',
403    'application/json',
404    'inline',
405    'Composer.json'
406);
407$mailer->Attach(
408    '/srv/www/ilias5/data/defaultclient/ilFile/4/file_401/001/composer.json',
409    'application/json',
410    'inline',
411    'AnotherComposer.json'
412);
413
414$mailer->Send();
415```
416
417Subject and body MUST be of type plain text and MUST NOT contain any HTML fragments.
418When preparing the email transport `\ilMimeMail` wraps an HTML structure around
419the message body (see: [HTML Mails with Skin](https://www.ilias.de/docu/goto_docu_wiki_wpage_3506_1357.html))
420passed by the consumer. It automatically transforms newline characters (LF/CR)
421to HTML linebreak elements.
422The original message body is used as *text/plain* alternative, the processed
423body is used as *text/html* alternative.
424
425### Sender
426
427Since ILIAS 5.3.x the `$sender` cannot be passed as a primitive
428data type anymore. A sender MUST implement `\ilMailMimeSender`.
429ILIAS currently provides two different implementations:
430
4311. `\ilMailMimeSenderSystem`
4322. `\ilMailMimeSenderUser`
433
434Both instances can be retrieved by the globally available `\ilMailMimeSenderFactory`,
435registered in the dependency container (`$DIC["mail.mime.sender.factory"]`).
436
437The first MUST be used whenever an email is sent with the purpose of a *System Email*.
438The second type MUST be used for a *User-to-User Email*.
439
440### Transport
441
442The actual transport is decoupled from `\ilMimeMail`. `\ilMimeMail` uses
443the determined transport strategy given by the
444`\ilMailMimeTransportFactory` instance which is available in
445the dependency injection container (`$DIC["mail.mime.transport.factory"]`).
446
447A transport strategy MUST follow the definition of
448the `\ilMailMimeTransport` interface. A different transport could be
449globally set via `\ilMimeMail::setDefaultTransport`, or just for
450the next call of `Send()` by passing an instance of `\ilMailMimeTransport` as
451argument:
452
453```php
454$mailer->Send($transport);
455```
456
457## ilMailNotification
458
459`\ilMailNotification` is a **higher level** abstraction
460wrapping `\ilMail`. It can be extended to create a custom
461email for a specific purpose of your component or plugin.
462
463Every service/module/plugin in ILIAS MAY create a specialized class
464for creating and sending emails. Therefore it MUST use inheritance
465and derive from `\ilMailNotification`.
466
467```php
468class MyMailNotification extends \ilMailNotification
469{
470    // [...]
471    public function send()
472    {
473        try
474        {
475            $this->setSubject('Welcome to ILIAS');
476            $this->setBody('Hello World!');
477            $this->appendBody(\ilMail::_getInstallationSignature());
478
479            $this->sendMail($this->getRecipients(), array('system'));
480        }
481        catch(\ilMailException $e)
482        {
483            // Error handling
484        }
485    }
486    // [...]
487}
488```
489
490The usage could look like this:
491
492```php
493$myMailNotification = new \MyMailNotification();
494$myMailNotification->setRecipients(
495    [
496        4711, 666
497    ]
498);
499$myMailNotification->send();
500```
501
502If the recipients could only be/are already
503provided as usernames or email addresses,
504you can use the third parameter of `sendMail()`
505and pass a boolean `false`.
506If you pass `true` as third argument or don't pass
507a third argument at all, the elements of the first
508parameter array are considered to be the internal
509user ids of the recipients and the corresponding
510usernames will be determined automatically when
511`sendMail()` is called.
512
513```php
514class MyMailNotification extends \ilMailNotification
515{
516    // [...]
517    public function send()
518    {
519        try
520        {
521            $this->setSubject('Welcome to ILIAS');
522            $this->setBody('Hello World!');
523            $this->appendBody(\ilMail::_getInstallationSignature());
524
525            $this->sendMail($this->getRecipients(), array('system'), false);
526        }
527        catch(\ilMailException $e)
528        {
529            // Error handling
530        }
531    }
532    // [...]
533}
534```
535
536The usage could look like this:
537
538```php
539$myMailNotification = new \MyMailNotification();
540$myMailNotification->setRecipients(
541    [
542        'root', 'dummy@gmail.com'
543    ]
544);
545$myMailNotification->send();
546```
547
548If you explicitly need to send an external email you
549can use/extend from `\ilMimeMailNotification`. This class itself
550also derives from `\ilMailNotification`.
551
552Recipients can be provided as:
553
554* Instances of \ilObjUser
555* The internal user id
556* Email address
557
558```php
559class ilRegistrationMailNotification extends \ilMimeMailNotification
560{
561    // [...]
562    public function send()
563    {
564        try
565        {
566            foreach ($this->getRecipients() as $rcp) {
567                $this->initMail();
568                $this->initLanguage($rcp);
569                $this->setSubject('Welcome to ILIAS');
570                $this->setBody('Hello World!');
571                $this->appendBody(\ilMail::_getInstallationSignature());
572
573                $this->getMail()->appendInstallationSignature(true);
574                $this->sendMail(array($rcp),array('system'));
575            }
576        }
577        catch(\ilMailException $e)
578        {
579            // Error handling
580        }
581    }
582    // [...]
583}
584```
585
586The usage could look like this:
587
588```php
589$myMailNotification = new \ilRegistrationMailNotification();
590$myMailNotification->setRecipients([
591    6,
592    new ilObjUser(6),
593    'dummy@gmail.com'
594]);
595$myMailNotification->send();
596```
597
598## ilSystemNotification
599
600`\ilSystemNotification` is a commonly used implementation
601of the previous explained `\ilMailNotification`.
602
603This class is used to create an email sent by the ILIAS
604system with a more or less given structure and text layout.
605The implementation is used by several modules/services
606to create their own emails.
607
608```php
609$mail = new \ilSystemNotification();
610$mail->setLangModules(array('user'));
611$mail->setRefId($refId);
612$mail->setChangedByUserId($user->getId());
613$mail->setSubjectLangId('my_subject');
614$mail->setIntroductionLangId('my_body');
615$mail->addAdditionalInfo('additional_info', 'The title');
616$mail->setGotoLangId('exc_team_notification_link');
617$mail->setReasonLangId('my_reason');
618$mail->sendMail(array($targetUser->getId()));
619```
620
621## ilAccountMail
622
623An instance of `\ilAccountMail` MUST be used to sent
624external emails whenever a user account was created
625in ILIAS. It's main purpose is to provide user
626account information in the self registration process.
627
628The contents of this email can be configured in
629**Administration » User Management » New Account Mail**.
630Subject and body can be defined for each installed
631language. Furthermore placeholders can be used, being
632replaced with the user's account data when the email
633is sent:
634
635* \[MAIL_SALUTATION\]: Salutation
636* \[FIRST_NAME\]: First Name
637* \[LAST_NAME\]: Last Name
638* \[EMAIL\]: E-Mail
639* \[LOGIN\]: Login Account
640* \[PASSWORD\]: Password
641* \[IF_PASSWORD\]...\[/IF_PASSWORD\]: This text block is only included, if the new user account has been created including a password.
642* \[IF_NO_PASSWORD\]...\[/IF_NO_PASSWORD\]: This text block is only included, if the new user account has been created without a password.
643* \[ADMIN_MAIL\]: Email address of Administrator
644* \[ILIAS_URL\]: URL of ILIAS system
645* \[CLIENT_NAME\]: Client Name
646* \[TARGET\]: URL of target item, e.g. a linked course that is passed to ILIAS from outside.
647* \[TARGET_TITLE\]: Title of target item, e.g. course title.
648* \[TARGET_TYPE\]: Type of target item, e.g. ‘Course’ for a course item.
649* \[IF_TARGET\]...\[/IF_TARGET\]: This text is only included, if a target item is provided.
650* \[IF_TIMELIMIT\]...\[/IF_TIMELIMIT\]: This text is only included, if the user has a limited access period.
651* \[TIMELIMIT\]: User access period
652
653The object tries to determine subject and body based
654on the user's language. If this fails, the system
655language is used as a fallback for determination.
656If this fails again, there is an optional second
657fallback by using the following language variables:
658
659* reg_mail_body_salutation
660* reg_mail_body_text1
661* reg_mail_body_text2
662* reg_mail_body_text3
663
664```php
665global $DIC;
666
667$user = $DIC->user();
668
669$accountMail = new \ilAccountMail();
670$accountMail->setUser($user);
671
672$accountMail->send();
673```
674
675This will create a default message with the look
676of a registration email.
677
678To enable the language variable fallback the
679following mutator has to be called with a
680boolean true as it's argument:
681```php
682$accountMail->useLangVariablesAsFallback(true);
683```
684If a raw password should be included, it MUST be
685explicitly set via:
686```php
687$accountMail->setUserPassword($rawPassword);
688 ```
689
690Internally `\ilAccountMail` makes use of `\ilMimeMail`.
691
692## Manual Mail Templates
693
694The concept of ['Manual Mail Templates'](https://www.ilias.de/docu/goto_docu_wiki_wpage_2703_1357.html) is best described
695as a feature which enables services/modules to
696provide text templates for a 'User-to-User Email' in a
697specific context.
698
699Often tutors / admins send the emails with the same purpose
700and texts to course members, e.g. to ask them if they
701have problems with the course because they have not
702used the course yet.
703
704### Context Registration
705
706A module or service MAY announce its email template
707contexts to the system by adding them to their
708respective *module.xml* or *service.xml*.
709The template context id has to be globally unique.
710An optional path can be added if the module/service
711directory layout differs from the ILIAS standard,
712where most files are located in a `./classes`
713directory.
714
715```xml
716<?xml version = "1.0" encoding = "UTF-8"?>
717<module xmlns="http://www.w3.org" version="$Id$" id="crs">
718    ...
719    <mailtemplates>
720        <context id="crs_context_manual" class="ilCourseMailTemplateContext" />
721    </mailtemplates>
722</module>
723```
724
725If registered once, every email template context
726class defined in a *module.xml* or *service.xml*
727has to extend the base class `\ilMailTemplateContext`.
728All abstract methods MUST be implemented to make
729a template context usable.
730
731* getId(): string
732* getTitle(): string
733* getDescription(): string
734* getSpecificPlaceholders(): array
735* resolveSpecificPlaceholder(string $placeholderId, array $contextParameters, \ilObjUser $recipient = null, $htmlMarkup = false): string
736
737A collection of context specific placeholders
738can be returned by a simple array definition.
739The key of each element should be a unique
740placeholder id.
741Each placeholder contains (beside its id) a
742placeholder string and a label which is used
743in the user interfaced.
744
745```php
746return array(
747    'crs_title' => array(
748        'placeholder' => 'CRS_TITLE',
749        'label' => $lng->txt('crs_title')
750    ),
751    'crs_link' => array(
752        'placeholder' => 'CRS_LINK',
753        'label' => $lng->txt('crs_mail_permanent_link')
754    )
755);
756```
757
758Supposing the context registration succeeded and you
759properly derived a context PHP class providing all
760necessary data and placeholders, you are now
761able to use your registered context in your component
762and build hyperlinks to the mail system, transporting
763your context information.
764
765### Context Usage Example
766
767Given you created a context named `crs_context_tutor_manual` ...
768
769```php
770global $DIC;
771
772class ilCourseMailTemplateTutorContext extends \ilMailTemplateContext
773{
774    // [...]
775    const ID = 'crs_context_tutor_manual';
776    // [...]
777}
778```
779
780... you can provide a hyperlink to the mail system (or
781more precisely to `\ilMailFormGUI`) as follows:
782
783```php
784$DIC->ctrl()->redirectToUrl(
785    \ilMailFormCall::getRedirectTarget(
786        $this, // The referring ILIAS controller aka. GUI when redirecting back to the referrer
787        'participants', // The desired command aka. the method to be called when redirecting back to the referrer
788        array(), // Key/Value array for parameters important for the ilCtrl/GUI context when when redirecting back to the referrer, e.g. a ref_id
789        array(
790           'type' => 'new', // Could also be 'reply' with an additional 'mail_id' paremter provided here
791        ),
792        array(
793            \ilMailFormCall::CONTEXT_KEY => \ilCourseMailTemplateTutorContext::ID, // don't forget this!
794            'ref_id' => $courseRefId,
795            'ts'     => time(),
796            // further parameters which will be later automatically passed to your context class
797        )
798    )
799);
800```
801
802Parameters required by your mail context class
803MUST be provided as a key/value pair array in the
804fifth parameter of `\ilMailFormCall::getRedirectTarget`.
805These parameters will be passed back to
806your context class when the mail system uses
807`\ilMailTemplateContext::resolveSpecificPlaceholder(...)`
808as callback when an email is actually sent and included
809placeholders should be replaced.
810You also MUST add a key `\ilMailFormCall::CONTEXT_KEY`
811with your context id as value to this array.
812