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