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