From 30659a254b7dbfb5c578bd266a387905e6de0ffa Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Wed, 25 Feb 2026 14:33:14 +0100 Subject: [PATCH 1/4] [Improvement] Mail: Adapter for Mustache Engine --- .../Sender/class.ilMailMimeSenderFactory.php | 8 ++-- .../Sender/class.ilMailMimeSenderUser.php | 6 ++- ...ass.ilMailMimeSenderUserByEmailAddress.php | 6 ++- .../Sender/class.ilMailMimeSenderUserById.php | 6 ++- .../class.ilMailTemplateContextAdapter.php | 12 +++-- .../Mail/classes/Service/MailService.php | 18 +++++-- .../Mail/classes/Service/MimeMailService.php | 12 ++--- .../Signature/MailSignatureService.php | 6 +-- .../Mail/classes/class.ilAccountMail.php | 6 +-- ...lass.ilMailTemplatePlaceholderResolver.php | 8 ++-- .../classes/class.ilMailTemplateService.php | 11 +++-- .../ILIAS/Mail/classes/class.ilObjMailGUI.php | 7 +-- .../Mustache/MustacheTemplateEngine.php | 41 ++++++++++++++++ .../MustacheTemplateEngineFactory.php} | 12 +++-- .../TemplateEngineFactoryInterface.php} | 25 +++++----- .../TemplateEngineInterface.php | 37 ++++++++++++++ .../MustacheTemplateEngineFactoryTest.php | 48 +++++++++++++++++++ .../ILIAS/Mail/tests/ilMailMimeTest.php | 17 +++---- .../Mail/tests/ilMailTemplateContextTest.php | 5 +- .../Mail/tests/ilMailTemplateServiceTest.php | 10 ++-- components/ILIAS/Mail/tests/ilMailTest.php | 10 ++-- .../AdditionalInformationGenerator.php | 5 +- components/ILIAS/Test/src/TestDIC.php | 2 +- .../User/classes/class.ilObjUserFolderGUI.php | 7 +-- .../NewAccountMail/class.SettingsGUI.php | 5 +- 25 files changed, 243 insertions(+), 87 deletions(-) create mode 100644 components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngine.php rename components/ILIAS/Mail/{classes/Mustache/class.ilMustacheFactory.php => src/TemplateEngine/Mustache/MustacheTemplateEngineFactory.php} (59%) mode change 100755 => 100644 rename components/ILIAS/Mail/{tests/Mustache/ilMustacheFactoryTest.php => src/TemplateEngine/TemplateEngineFactoryInterface.php} (55%) mode change 100755 => 100644 create mode 100644 components/ILIAS/Mail/src/TemplateEngine/TemplateEngineInterface.php create mode 100644 components/ILIAS/Mail/tests/TemplateEngine/MustacheTemplateEngineFactoryTest.php diff --git a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderFactory.php b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderFactory.php index 76dc0649c93f..6673f6797ebc 100755 --- a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderFactory.php +++ b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderFactory.php @@ -18,6 +18,8 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; + class ilMailMimeSenderFactory { /** @var array */ @@ -26,7 +28,7 @@ class ilMailMimeSenderFactory public function __construct( protected ilSetting $settings, - protected ilMustacheFactory $mustache_factory, + protected TemplateEngineFactoryInterface $template_engine_factory, ?int $anonymous_usr_id = null ) { if ($anonymous_usr_id === null && defined('ANONYMOUS_USER_ID')) { @@ -68,11 +70,11 @@ public function system(): ilMailMimeSenderSystem public function user(int $usr_id): ilMailMimeSenderUser { - return new ilMailMimeSenderUserById($this->settings, $usr_id, $this->mustache_factory); + return new ilMailMimeSenderUserById($this->settings, $usr_id, $this->template_engine_factory); } public function userByEmailAddress(string $email_address): ilMailMimeSenderUser { - return new ilMailMimeSenderUserByEmailAddress($this->settings, $email_address, $this->mustache_factory); + return new ilMailMimeSenderUserByEmailAddress($this->settings, $email_address, $this->template_engine_factory); } } diff --git a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUser.php b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUser.php index eb6b8b5ea52e..14e8b8173eea 100755 --- a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUser.php +++ b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUser.php @@ -18,12 +18,14 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; + abstract class ilMailMimeSenderUser implements ilMailMimeSender { public function __construct( protected ilSetting $settings, protected ilObjUser $user, - protected ilMustacheFactory $mustache_factory + protected TemplateEngineFactoryInterface $template_engine_factory ) { } @@ -82,7 +84,7 @@ public function getFromName(): string ]; $template = $from; - $interpolated = $this->mustache_factory->getBasicEngine()->render($template, $placeholders); + $interpolated = $this->template_engine_factory->getBasicEngine()->render($template, $placeholders); if ($template !== $interpolated) { return $interpolated; diff --git a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserByEmailAddress.php b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserByEmailAddress.php index a55952d0ecee..673fb9dac051 100755 --- a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserByEmailAddress.php +++ b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserByEmailAddress.php @@ -18,13 +18,15 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; + class ilMailMimeSenderUserByEmailAddress extends ilMailMimeSenderUser { - public function __construct(ilSetting $settings, string $email_address, ilMustacheFactory $mustache_factory) + public function __construct(ilSetting $settings, string $email_address, TemplateEngineFactoryInterface $template_engine_factory) { $user = new ilObjUser(); $user->setEmail($email_address); - parent::__construct($settings, $user, $mustache_factory); + parent::__construct($settings, $user, $template_engine_factory); } } diff --git a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserById.php b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserById.php index 74e1eb4411c4..e37d11e5ddea 100755 --- a/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserById.php +++ b/components/ILIAS/Mail/classes/Mime/Sender/class.ilMailMimeSenderUserById.php @@ -18,18 +18,20 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; + class ilMailMimeSenderUserById extends ilMailMimeSenderUser { /** @var array */ protected static array $user_instances = []; - public function __construct(ilSetting $settings, int $usr_id, ilMustacheFactory $mustache_factory) + public function __construct(ilSetting $settings, int $usr_id, TemplateEngineFactoryInterface $template_engine_factory) { if (!array_key_exists($usr_id, self::$user_instances)) { self::$user_instances[$usr_id] = new ilObjUser($usr_id); } - parent::__construct($settings, self::$user_instances[$usr_id], $mustache_factory); + parent::__construct($settings, self::$user_instances[$usr_id], $template_engine_factory); } public static function addUserToCache(int $usr_id, ilObjUser $user): void diff --git a/components/ILIAS/Mail/classes/Mustache/class.ilMailTemplateContextAdapter.php b/components/ILIAS/Mail/classes/Mustache/class.ilMailTemplateContextAdapter.php index 6aea8e41eccc..8d9b7c51deda 100755 --- a/components/ILIAS/Mail/classes/Mustache/class.ilMailTemplateContextAdapter.php +++ b/components/ILIAS/Mail/classes/Mustache/class.ilMailTemplateContextAdapter.php @@ -18,14 +18,16 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineInterface; + /** - * This class forms an interface between the existing ILIAS mail contexts and the requirements of Mustache. + * This class forms an interface between the existing ILIAS mail contexts and the requirements of the template engine. * In the old system, it was possible to gradually replace individual placeholders via the contexts. - * This is now done by Mustache and requires a single source. If a placeholder does not exist in this source, + * This is now done by the template engine and requires a single source. If a placeholder does not exist in this source, * then it will be replaced with NULL. Mustache takes two steps to find the placeholder. * On the one hand the check whether it would be theoretically possible and the actual query for the value * if the check is successful. This is done in this class using the two magic methods. - * With the introduction of this interface, the ILIAS mail contexts do not have to be changed for Mustache. + * With the introduction of this interface, the ILIAS mail contexts do not have to be changed for the template engine. */ class ilMailTemplateContextAdapter { @@ -33,7 +35,7 @@ public function __construct( /** @var ilMailTemplateContext[] $contexts */ protected array $contexts, protected array $context_parameter, - protected readonly Mustache_Engine $mustache_engine, + protected readonly TemplateEngineInterface $template_engine, protected ?ilObjUser $recipient = null ) { } @@ -67,7 +69,7 @@ public function __get(string $name): string foreach ($this->contexts as $context) { $ret = $context->resolvePlaceholder($name, $this->context_parameter, $this->recipient); if (in_array($name, $context->getNestedPlaceholders(), true)) { - $ret = $this->mustache_engine->render($ret, $this); + $ret = $this->template_engine->render($ret, $this); } if ($ret !== '') { return $ret; diff --git a/components/ILIAS/Mail/classes/Service/MailService.php b/components/ILIAS/Mail/classes/Service/MailService.php index 7c87b70eb88a..fa9ae3562459 100755 --- a/components/ILIAS/Mail/classes/Service/MailService.php +++ b/components/ILIAS/Mail/classes/Service/MailService.php @@ -23,11 +23,13 @@ use ILIAS\DI\Container; use ILIAS\Mail\Autoresponder\AutoresponderServiceImpl; use ILIAS\Mail\Autoresponder\AutoresponderService; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; use ilMailTemplateService; use ILIAS\Data\Factory as DataFactory; use ILIAS\Mail\Autoresponder\AutoresponderDatabaseRepository; use ilMailTemplateRepository; use ilMailTemplateServiceInterface; +use ILIAS\Mail\TemplateEngine\Mustache\MustacheTemplateEngineFactory; class MailService { @@ -37,7 +39,7 @@ public function __construct(protected Container $dic) $this->dic[ilMailTemplateServiceInterface::class] = static function (Container $c): ilMailTemplateServiceInterface { return new ilMailTemplateService( new ilMailTemplateRepository($c->database()), - $c->mail()->mustacheFactory() + $c->mail()->templateEngineFactory() ); }; } @@ -69,7 +71,7 @@ public function textTemplates(): ilMailTemplateServiceInterface public function placeholderResolver(): \ilMailTemplatePlaceholderResolver { return new \ilMailTemplatePlaceholderResolver( - $this->mustacheFactory()->getBasicEngine() + $this->templateEngineFactory()->getBasicEngine() ); } @@ -78,15 +80,21 @@ public function placeholderToEmptyResolver(): \ilMailTemplatePlaceholderToEmptyR return new \ilMailTemplatePlaceholderToEmptyResolver(); } - public function mustacheFactory(): \ilMustacheFactory + public function templateEngineFactory(): TemplateEngineFactoryInterface { - return new \ilMustacheFactory(); + if (!isset($this->dic['mail.template_engine.factory'])) { + $this->dic['mail.template_engine.factory'] = static function (Container $c): MustacheTemplateEngineFactory { + return new MustacheTemplateEngineFactory(); + }; + } + + return $this->dic['mail.template_engine.factory']; } public function signature(): MailSignatureService { return new MailSignatureService( - $this->mustacheFactory(), + $this->templateEngineFactory(), $this->dic->clientIni(), $this->dic->language(), $this->dic->settings() diff --git a/components/ILIAS/Mail/classes/Service/MimeMailService.php b/components/ILIAS/Mail/classes/Service/MimeMailService.php index ae3e8f257028..b55ec30bc50b 100755 --- a/components/ILIAS/Mail/classes/Service/MimeMailService.php +++ b/components/ILIAS/Mail/classes/Service/MimeMailService.php @@ -38,7 +38,7 @@ public function __construct(protected Container $dic) $this->dic['mail.mime.sender.factory'] = static function (Container $c): ilMailMimeSenderFactory { return new ilMailMimeSenderFactory( $c->settings(), - $c->mail()->mustacheFactory() + $c->mail()->templateEngineFactory() ); }; } @@ -47,21 +47,15 @@ public function __construct(protected Container $dic) $this->dic['mail.texttemplates.service'] = static function (Container $c): \ilMailTemplateService { return new \ilMailTemplateService( new \ilMailTemplateRepository($c->database()), - $this->dic['mail.mustache.factory'] + $c->mail()->templateEngineFactory() ); }; } - if (!isset($this->dic['mail.mustache.factory'])) { - $this->dic["mail.mustache.factory"] = static function (Container $c): \ilMustacheFactory { - return new \ilMustacheFactory(); - }; - } - if (!isset($this->dic['mail.template.placeholder.resolver'])) { $this->dic["mail.template.placeholder.resolver"] = static function (Container $c): \ilMailTemplatePlaceholderResolver { return new \ilMailTemplatePlaceholderResolver( - $c["mail.mustache.factory"]->getBasicEngine() + $c->mail()->templateEngineFactory()->getBasicEngine() ); }; } diff --git a/components/ILIAS/Mail/classes/Signature/MailSignatureService.php b/components/ILIAS/Mail/classes/Signature/MailSignatureService.php index a2e75eeda53e..87933b49575b 100644 --- a/components/ILIAS/Mail/classes/Signature/MailSignatureService.php +++ b/components/ILIAS/Mail/classes/Signature/MailSignatureService.php @@ -21,7 +21,7 @@ namespace ILIAS\Mail\Service; use ilIniFile; -use ilMustacheFactory; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; use ILIAS\Mail\Signature\Signature; use ILIAS\Mail\Signature\MailInstallationSignature; use ILIAS\Mail\Signature\MailUserSignature; @@ -37,7 +37,7 @@ class MailSignatureService { public function __construct( - private readonly ilMustacheFactory $mustache_factory, + private readonly TemplateEngineFactoryInterface $template_engine_factory, private readonly ilIniFile $client_ini_file, private readonly ilLanguage $lng, private readonly ilSetting $settings @@ -64,7 +64,7 @@ private function processSignature(Placeholder $placeholder, Signature $signature { $placeholders = $placeholder->handle($signature); - return "\n\n\n" . $this->mustache_factory->getBasicEngine()->render($signature->getSignature(), $placeholders); + return "\n\n\n" . $this->template_engine_factory->getBasicEngine()->render($signature->getSignature(), $placeholders); } public function getPlaceholder(int $user_id = 0): Placeholder diff --git a/components/ILIAS/Mail/classes/class.ilAccountMail.php b/components/ILIAS/Mail/classes/class.ilAccountMail.php index 2e3cf17545ab..21c9bad0776c 100755 --- a/components/ILIAS/Mail/classes/class.ilAccountMail.php +++ b/components/ILIAS/Mail/classes/class.ilAccountMail.php @@ -193,12 +193,12 @@ public function replacePlaceholders(string $a_string, ilObjUser $a_user, NewAcco { global $DIC; $settings = $DIC->settings(); - $mustache_factory = $DIC->mail()->mustacheFactory(); + $template_engine_factory = $DIC->mail()->templateEngineFactory(); $replacements = []; // determine salutation - $replacements['MAIL_SALUTATION'] = $mustache_factory->getBasicEngine()->render( + $replacements['MAIL_SALUTATION'] = $template_engine_factory->getBasicEngine()->render( match ($a_user->getGender()) { 'f' => trim($a_amail->getSalutationFemale()), 'm' => trim($a_amail->getSalutationMale()), @@ -252,6 +252,6 @@ public function replacePlaceholders(string $a_string, ilObjUser $a_user, NewAcco } } - return $mustache_factory->getBasicEngine()->render($a_string, $replacements); + return $template_engine_factory->getBasicEngine()->render($a_string, $replacements); } } diff --git a/components/ILIAS/Mail/classes/class.ilMailTemplatePlaceholderResolver.php b/components/ILIAS/Mail/classes/class.ilMailTemplatePlaceholderResolver.php index 80493d440f66..306967746cc0 100755 --- a/components/ILIAS/Mail/classes/class.ilMailTemplatePlaceholderResolver.php +++ b/components/ILIAS/Mail/classes/class.ilMailTemplatePlaceholderResolver.php @@ -18,9 +18,11 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineInterface; + class ilMailTemplatePlaceholderResolver { - public function __construct(protected Mustache_Engine $mustache_engine) + public function __construct(protected TemplateEngineInterface $template_engine) { } @@ -33,12 +35,12 @@ public function resolve( ?ilObjUser $user = null, array $context_parameters = [] ): string { - return $this->mustache_engine->render( + return $this->template_engine->render( $message, new ilMailTemplateContextAdapter( [$context], $context_parameters, - $this->mustache_engine, + $this->template_engine, $user ) ); diff --git a/components/ILIAS/Mail/classes/class.ilMailTemplateService.php b/components/ILIAS/Mail/classes/class.ilMailTemplateService.php index 9ac4705c68a8..e24029acd9e2 100755 --- a/components/ILIAS/Mail/classes/class.ilMailTemplateService.php +++ b/components/ILIAS/Mail/classes/class.ilMailTemplateService.php @@ -18,6 +18,7 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; use ILIAS\Mail\Templates\TemplateSubjectSyntaxException; use ILIAS\Mail\Templates\TemplateMessageSyntaxException; @@ -25,7 +26,7 @@ class ilMailTemplateService implements ilMailTemplateServiceInterface { public function __construct( protected ilMailTemplateRepository $repository, - protected ilMustacheFactory $mustache_factory + protected TemplateEngineFactoryInterface $template_engine_factory ) { } @@ -37,13 +38,13 @@ public function createNewTemplate( string $language ): ilMailTemplate { try { - $this->mustache_factory->getBasicEngine()->render($subject, []); + $this->template_engine_factory->getBasicEngine()->render($subject, []); } catch (Exception) { throw new TemplateSubjectSyntaxException('Invalid mail template for subject'); } try { - $this->mustache_factory->getBasicEngine()->render($message, []); + $this->template_engine_factory->getBasicEngine()->render($message, []); } catch (Exception) { throw new TemplateMessageSyntaxException('Invalid mail template for message'); } @@ -69,13 +70,13 @@ public function modifyExistingTemplate( string $language ): void { try { - $this->mustache_factory->getBasicEngine()->render($subject, []); + $this->template_engine_factory->getBasicEngine()->render($subject, []); } catch (Exception) { throw new TemplateSubjectSyntaxException('Invalid mail template for subject'); } try { - $this->mustache_factory->getBasicEngine()->render($message, []); + $this->template_engine_factory->getBasicEngine()->render($message, []); } catch (Exception) { throw new TemplateMessageSyntaxException('Invalid mail template for message'); } diff --git a/components/ILIAS/Mail/classes/class.ilObjMailGUI.php b/components/ILIAS/Mail/classes/class.ilObjMailGUI.php index d39f6d9645a4..a09c401eaace 100755 --- a/components/ILIAS/Mail/classes/class.ilObjMailGUI.php +++ b/components/ILIAS/Mail/classes/class.ilObjMailGUI.php @@ -23,6 +23,7 @@ use ILIAS\Mail\Signature\Signature; use ILIAS\Mail\Signature\MailInstallationSignature; use ILIAS\Mail\Service\MailSignatureService; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; /** * @ilCtrl_Calls ilObjMailGUI: ilPermissionGUI @@ -34,7 +35,7 @@ class ilObjMailGUI extends ilObjectGUI private const string PASSWORD_PLACE_HOLDER = '***********************'; private readonly ilTabsGUI $tabs; - private readonly ilMustacheFactory $mustache_factory; + private readonly TemplateEngineFactoryInterface $template_engine_factory; private readonly MailSignatureService $mail_signature_service; public function __construct($a_data, int $a_id, bool $a_call_by_reference) @@ -44,7 +45,7 @@ public function __construct($a_data, int $a_id, bool $a_call_by_reference) parent::__construct($a_data, $a_id, $a_call_by_reference, false); $this->tabs = $DIC->tabs(); - $this->mustache_factory = $DIC->mail()->mustacheFactory(); + $this->template_engine_factory = $DIC->mail()->templateEngineFactory(); $this->mail_signature_service = $DIC->mail()->signature(); $this->lng->loadLanguageModule('mail'); @@ -660,7 +661,7 @@ protected function saveExternalSettingsFormObject(): void // If all forms in ILIAS use the UI/KS forms (here and in Services/Mail), we should move this to a proper constraint/trafo $is_valid_template_syntax = $this->refinery->custom()->constraint(function ($value): bool { try { - $this->mustache_factory->getBasicEngine()->render((string) $value, []); + $this->template_engine_factory->getBasicEngine()->render((string) $value, []); return true; } catch (Exception) { return false; diff --git a/components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngine.php b/components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngine.php new file mode 100644 index 000000000000..38c87691fef3 --- /dev/null +++ b/components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngine.php @@ -0,0 +1,41 @@ +engine->render($template, $context); + } +} diff --git a/components/ILIAS/Mail/classes/Mustache/class.ilMustacheFactory.php b/components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngineFactory.php old mode 100755 new mode 100644 similarity index 59% rename from components/ILIAS/Mail/classes/Mustache/class.ilMustacheFactory.php rename to components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngineFactory.php index 5d85e11ff37e..0903d4c65b50 --- a/components/ILIAS/Mail/classes/Mustache/class.ilMustacheFactory.php +++ b/components/ILIAS/Mail/src/TemplateEngine/Mustache/MustacheTemplateEngineFactory.php @@ -18,10 +18,16 @@ declare(strict_types=1); -class ilMustacheFactory +namespace ILIAS\Mail\TemplateEngine\Mustache; + +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; +use ILIAS\Mail\TemplateEngine\TemplateEngineInterface; +use Mustache_Engine; + +class MustacheTemplateEngineFactory implements TemplateEngineFactoryInterface { - public function getBasicEngine(): Mustache_Engine + public function getBasicEngine(): TemplateEngineInterface { - return new Mustache_Engine(); + return new MustacheTemplateEngine(new Mustache_Engine()); } } diff --git a/components/ILIAS/Mail/tests/Mustache/ilMustacheFactoryTest.php b/components/ILIAS/Mail/src/TemplateEngine/TemplateEngineFactoryInterface.php old mode 100755 new mode 100644 similarity index 55% rename from components/ILIAS/Mail/tests/Mustache/ilMustacheFactoryTest.php rename to components/ILIAS/Mail/src/TemplateEngine/TemplateEngineFactoryInterface.php index 554da23251b4..fc2fd83ba680 --- a/components/ILIAS/Mail/tests/Mustache/ilMustacheFactoryTest.php +++ b/components/ILIAS/Mail/src/TemplateEngine/TemplateEngineFactoryInterface.php @@ -18,20 +18,17 @@ declare(strict_types=1); -use PHPUnit\Framework\TestCase; +namespace ILIAS\Mail\TemplateEngine; -class ilMustacheFactoryTest extends TestCase +/** + * Factory interface for creating template engine instances. + * Enables dependency inversion: consumers depend on this interface, + * not on a concrete implementation like Mustache. + */ +interface TemplateEngineFactoryInterface { - public function testCreatInstance(): void - { - $f = new ilMustacheFactory(); - $this->assertInstanceOf(ilMustacheFactory::class, $f); - } - - public function testCreateBasicEngine(): void - { - $f = new ilMustacheFactory(); - $engine = $f->getBasicEngine(); - $this->assertInstanceOf(Mustache_Engine::class, $engine); - } + /** + * Returns a template engine instance for basic rendering operations. + */ + public function getBasicEngine(): TemplateEngineInterface; } diff --git a/components/ILIAS/Mail/src/TemplateEngine/TemplateEngineInterface.php b/components/ILIAS/Mail/src/TemplateEngine/TemplateEngineInterface.php new file mode 100644 index 000000000000..c6c97d22d00a --- /dev/null +++ b/components/ILIAS/Mail/src/TemplateEngine/TemplateEngineInterface.php @@ -0,0 +1,37 @@ +|object $context The context data for placeholder replacement + */ + public function render(string $template, array|object $context): string; +} diff --git a/components/ILIAS/Mail/tests/TemplateEngine/MustacheTemplateEngineFactoryTest.php b/components/ILIAS/Mail/tests/TemplateEngine/MustacheTemplateEngineFactoryTest.php new file mode 100644 index 000000000000..cb7b6ad89b9f --- /dev/null +++ b/components/ILIAS/Mail/tests/TemplateEngine/MustacheTemplateEngineFactoryTest.php @@ -0,0 +1,48 @@ +assertInstanceOf(TemplateEngineFactoryInterface::class, $f); + } + + public function testGetBasicEngineReturnsTemplateEngine(): void + { + $f = new MustacheTemplateEngineFactory(); + $engine = $f->getBasicEngine(); + $this->assertInstanceOf(TemplateEngineInterface::class, $engine); + } + + public function testEngineRendersMustacheTemplates(): void + { + $f = new MustacheTemplateEngineFactory(); + $engine = $f->getBasicEngine(); + $result = $engine->render('Hello {{name}}!', ['name' => 'World']); + $this->assertSame('Hello World!', $result); + } +} diff --git a/components/ILIAS/Mail/tests/ilMailMimeTest.php b/components/ILIAS/Mail/tests/ilMailMimeTest.php index eaf0a9e0b664..4d5f8b798ed5 100755 --- a/components/ILIAS/Mail/tests/ilMailMimeTest.php +++ b/components/ILIAS/Mail/tests/ilMailMimeTest.php @@ -19,6 +19,7 @@ declare(strict_types=1); use ILIAS\Refinery\Factory; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; class ilMailMimeTest extends ilMailBaseTestCase { @@ -156,9 +157,9 @@ public function testFactoryWillReturnSystemSenderForAnonymousUserId(): void 'set', 'get', ])->getMock(); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); - $factory = new ilMailMimeSenderFactory($settings, $mustache_factory); + $factory = new ilMailMimeSenderFactory($settings, $template_engine_factory); $this->assertInstanceOf(ilMailMimeSenderSystem::class, $factory->getSenderByUsrId(ANONYMOUS_USER_ID)); } @@ -168,9 +169,9 @@ public function testFactoryWillReturnSystemSenderWhenExplicitlyRequested(): void 'set', 'get', ])->getMock(); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); - $factory = new ilMailMimeSenderFactory($settings, $mustache_factory); + $factory = new ilMailMimeSenderFactory($settings, $template_engine_factory); $this->assertInstanceOf(ilMailMimeSenderSystem::class, $factory->system()); } @@ -191,9 +192,9 @@ public function testFactoryWillReturnUserSenderForExistingUserId(): void 'set', 'get', ])->getMock(); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); - $factory = new ilMailMimeSenderFactory($settings, $mustache_factory); + $factory = new ilMailMimeSenderFactory($settings, $template_engine_factory); $this->assertInstanceOf(ilMailMimeSenderUser::class, $factory->getSenderByUsrId(self::USER_ID)); } @@ -203,9 +204,9 @@ public function testFactoryWillReturnUserSenderWhenExplicitlyRequested(): void 'set', 'get', ])->getMock(); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); - $factory = new ilMailMimeSenderFactory($settings, $mustache_factory); + $factory = new ilMailMimeSenderFactory($settings, $template_engine_factory); $this->assertInstanceOf(ilMailMimeSenderUser::class, $factory->user(self::USER_ID)); } } diff --git a/components/ILIAS/Mail/tests/ilMailTemplateContextTest.php b/components/ILIAS/Mail/tests/ilMailTemplateContextTest.php index d6b4aae88a3e..699b2f1079ec 100755 --- a/components/ILIAS/Mail/tests/ilMailTemplateContextTest.php +++ b/components/ILIAS/Mail/tests/ilMailTemplateContextTest.php @@ -23,6 +23,7 @@ use OrgUnit\PublicApi\OrgUnitUserService; use OrgUnit\User\ilOrgUnitUser; use PHPUnit\Framework\Attributes\DataProvider; +use ILIAS\Mail\TemplateEngine\Mustache\MustacheTemplateEngineFactory; class ilMailTemplateContextTest extends ilMailBaseTestCase { @@ -231,8 +232,8 @@ static function (ilOrgUnitUser $user): \PHPUnit\Framework\Constraint\Traversable $lng_helper ); - $mustache = new Mustache_Engine(); - $placeholder_resolver = new ilMailTemplatePlaceholderResolver($mustache); + $template_engine = (new MustacheTemplateEngineFactory())->getBasicEngine(); + $placeholder_resolver = new ilMailTemplatePlaceholderResolver($template_engine); $message = implode('', [ '{{MAIL_SALUTATION}}', diff --git a/components/ILIAS/Mail/tests/ilMailTemplateServiceTest.php b/components/ILIAS/Mail/tests/ilMailTemplateServiceTest.php index 73a6a6fddf3e..67eb204021c6 100755 --- a/components/ILIAS/Mail/tests/ilMailTemplateServiceTest.php +++ b/components/ILIAS/Mail/tests/ilMailTemplateServiceTest.php @@ -18,6 +18,8 @@ declare(strict_types=1); +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; + class ilMailTemplateServiceTest extends ilMailBaseTestCase { public function testDefaultTemplateCanBeSetByContext(): void @@ -45,8 +47,8 @@ public function testDefaultTemplateCanBeSetByContext(): void $repo->expects($this->once())->method('findByContextId')->with($template->getContext())->willReturn($all); $repo->expects($this->exactly(count($all)))->method('store'); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); - $service = new ilMailTemplateService($repo, $mustache_factory); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); + $service = new ilMailTemplateService($repo, $template_engine_factory); $service->setAsContextDefault($template); @@ -65,8 +67,8 @@ public function testDefaultTemplateForContextCanBeUnset(): void $template->setContext('phpunit'); $repo->expects($this->once())->method('store')->with($template); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); - $service = new ilMailTemplateService($repo, $mustache_factory); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); + $service = new ilMailTemplateService($repo, $template_engine_factory); $service->unsetAsContextDefault($template); diff --git a/components/ILIAS/Mail/tests/ilMailTest.php b/components/ILIAS/Mail/tests/ilMailTest.php index d760de21aff2..4f6574aa4993 100755 --- a/components/ILIAS/Mail/tests/ilMailTest.php +++ b/components/ILIAS/Mail/tests/ilMailTest.php @@ -26,6 +26,8 @@ use ILIAS\Data\Result\Ok; use ILIAS\Mail\Service\MailSignatureService; use PHPUnit\Framework\Attributes\DataProvider; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; +use ILIAS\Mail\TemplateEngine\Mustache\MustacheTemplateEngineFactory; class ilMailTest extends ilMailBaseTestCase { @@ -199,7 +201,7 @@ public function getAddress(): ilMailAddress $mail_options = $this->getMockBuilder(ilMailOptions::class)->disableOriginalConstructor()->getMock(); $mail_box = $this->getMockBuilder(ilMailbox::class)->disableOriginalConstructor()->getMock(); $actor = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock(); - $mustache_factory = $this->getMockBuilder(ilMustacheFactory::class)->getMock(); + $template_engine_factory = $this->getMockBuilder(TemplateEngineFactoryInterface::class)->getMock(); $mail_service = new ilMail( $sender_usr_id, @@ -212,13 +214,15 @@ public function getAddress(): ilMailAddress $mail_file_data, $mail_options, $mail_box, - new ilMailMimeSenderFactory($settings, $mustache_factory), + new ilMailMimeSenderFactory($settings, $template_engine_factory), static fn(string $login): int => $all_users_login_to_id_map[$login] ?? 0, $this->createMock(AutoresponderService::class), 0, 4711, $actor, - new ilMailTemplatePlaceholderResolver(new Mustache_Engine()) + new ilMailTemplatePlaceholderResolver( + (new MustacheTemplateEngineFactory())->getBasicEngine() + ) ); $old_transport = ilMimeMail::getDefaultTransport(); diff --git a/components/ILIAS/Test/src/Logging/AdditionalInformationGenerator.php b/components/ILIAS/Test/src/Logging/AdditionalInformationGenerator.php index 0ab305597fb8..e466d9f7cbc9 100644 --- a/components/ILIAS/Test/src/Logging/AdditionalInformationGenerator.php +++ b/components/ILIAS/Test/src/Logging/AdditionalInformationGenerator.php @@ -20,6 +20,7 @@ namespace ILIAS\Test\Logging; +use ILIAS\Mail\TemplateEngine\TemplateEngineInterface; use ILIAS\TestQuestionPool\Questions\GeneralQuestionPropertiesRepository; use ILIAS\UI\Factory as UIFactory; use ILIAS\UI\Component\Listing\Descriptive as DescriptiveListing; @@ -255,7 +256,7 @@ class AdditionalInformationGenerator private array $tags; public function __construct( - private readonly \Mustache_Engine $mustache, + private readonly TemplateEngineInterface $template_engine, private readonly \ilLanguage $lng, private readonly UIFactory $ui_factory, private readonly Refinery $refinery, @@ -415,7 +416,7 @@ private function buildDefaultValueString( ->setTimezone($environment['timezone']) ->format($environment['date_format']); } - return $this->mustache->render( + return $this->template_engine->render( $this->refinery->string()->stripTags()->transform($value), $this->tags ); diff --git a/components/ILIAS/Test/src/TestDIC.php b/components/ILIAS/Test/src/TestDIC.php index 3aca83d2cc2e..632039d2a69a 100755 --- a/components/ILIAS/Test/src/TestDIC.php +++ b/components/ILIAS/Test/src/TestDIC.php @@ -178,7 +178,7 @@ protected static function buildDIC(ILIASContainer $DIC): self $dic['logging.information_generator'] = static fn($c): Logging\AdditionalInformationGenerator => new Logging\AdditionalInformationGenerator( - (new \ilMustacheFactory())->getBasicEngine(), + $DIC->mail()->templateEngineFactory()->getBasicEngine(), $DIC['lng'], $DIC['ui.factory'], $DIC['refinery'], diff --git a/components/ILIAS/User/classes/class.ilObjUserFolderGUI.php b/components/ILIAS/User/classes/class.ilObjUserFolderGUI.php index 095b13388f1d..4c2c429bc94b 100755 --- a/components/ILIAS/User/classes/class.ilObjUserFolderGUI.php +++ b/components/ILIAS/User/classes/class.ilObjUserFolderGUI.php @@ -36,6 +36,7 @@ use ILIAS\Filesystem\Filesystem; use ILIAS\FileUpload\FileUpload; use ILIAS\ResourceStorage\Services as ResourceStorage; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; ; @@ -78,7 +79,7 @@ class ilObjUserFolderGUI extends ilObjectGUI private AdminTabs $admin_tabs; private int $user_owner_id = 0; private ilDBInterface $db; - private \ilMustacheFactory $mail_mustache_factory; + private TemplateEngineFactoryInterface $mail_template_engine_factory; private ilLogger $log; private ilAppEventHandler $event; private Filesystem $filesystem; @@ -102,7 +103,7 @@ public function __construct( $this->filesystem = $DIC->filesystem()->storage(); $this->upload = $DIC['upload']; $this->db = $DIC['ilDB']; - $this->mail_mustache_factory = $DIC->mail()->mustacheFactory(); + $this->mail_template_engine_factory = $DIC->mail()->templateEngineFactory(); $this->archives = $DIC->legacyArchives(); $this->irss = $DIC['resource_storage']; @@ -263,7 +264,7 @@ public function executeCommand(): void $this->ctrl, $this->access, $this->tpl, - $this->mail_mustache_factory, + $this->mail_template_engine_factory, $this->ui_factory, $this->ui_renderer, $this->refinery, diff --git a/components/ILIAS/User/src/Settings/NewAccountMail/class.SettingsGUI.php b/components/ILIAS/User/src/Settings/NewAccountMail/class.SettingsGUI.php index 15cf1be3a024..2f7cce48f626 100755 --- a/components/ILIAS/User/src/Settings/NewAccountMail/class.SettingsGUI.php +++ b/components/ILIAS/User/src/Settings/NewAccountMail/class.SettingsGUI.php @@ -29,6 +29,7 @@ use ILIAS\Refinery\Transformation; use Psr\Http\Message\ServerRequestInterface; use ILIAS\ResourceStorage\Services as ResourceStorage; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; /** * @ilCtrl_Calls ILIAS\User\Settings\NewAccountMail\SettingsGUI: ILIAS\User\Settings\NewAccountMail\UploadHandlerGUI @@ -45,7 +46,7 @@ public function __construct( private readonly \ilCtrl $ctrl, private readonly \ilAccess $access, private readonly \ilGlobalTemplateInterface $tpl, - private readonly \ilMustacheFactory $mail_mustache_factory, + private readonly TemplateEngineFactoryInterface $mail_template_engine_factory, private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly Refinery $refinery, @@ -204,7 +205,7 @@ private function buildValidateMailBodyConstraint(): Constraint return $this->refinery->custom()->constraint( function ($v): bool { try { - $this->mail_mustache_factory->getBasicEngine()->render($v, []); + $this->mail_template_engine_factory->getBasicEngine()->render($v, []); return true; } catch (\Exception) { return false; From e349171b7e70f36007cf6c75ebf5a2d309a99c81 Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Mon, 2 Mar 2026 11:01:14 +0100 Subject: [PATCH 2/4] [Improvement] Mail: MailService DIC as array access --- components/ILIAS/DI/src/Container.php | 2 +- .../ILIAS/Init/classes/class.ilInitialisation.php | 7 +++++++ components/ILIAS/Mail/classes/Service/MailService.php | 11 +++++++++++ components/ILIAS/Test/src/TestDIC.php | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/components/ILIAS/DI/src/Container.php b/components/ILIAS/DI/src/Container.php index 389adef09147..24176b14d2d7 100755 --- a/components/ILIAS/DI/src/Container.php +++ b/components/ILIAS/DI/src/Container.php @@ -450,7 +450,7 @@ public function cron(): \ILIAS\Cron\CronServices public function mail(): \ILIAS\Mail\Service\MailService { - return new \ILIAS\Mail\Service\MailService($this); + return $this[\ILIAS\Mail\Service\MailService::class]; } public function certificate(): \ILIAS\Certificate\Service\CertificateService diff --git a/components/ILIAS/Init/classes/class.ilInitialisation.php b/components/ILIAS/Init/classes/class.ilInitialisation.php index f0a501e47f1a..dffeb5c9f10b 100755 --- a/components/ILIAS/Init/classes/class.ilInitialisation.php +++ b/components/ILIAS/Init/classes/class.ilInitialisation.php @@ -764,6 +764,12 @@ protected static function initLegalDocuments(Container $c): void $c['legalDocuments'] = static fn(Container $c) => new Conductor($c); } + protected static function initMail(Container $c): void + { + $mail_service = new \ILIAS\Mail\Service\MailService($c); + $mail_service->populate(); + } + protected static function initAccessibilityControlConcept(\ILIAS\DI\Container $c): void { $c['acc.criteria.type.factory'] = function (\ILIAS\DI\Container $c) { @@ -1312,6 +1318,7 @@ protected static function initClient(): void self::initAvatar($GLOBALS['DIC']); self::initCustomObjectIcons($GLOBALS['DIC']); self::initLegalDocuments($GLOBALS['DIC']); + self::initMail($GLOBALS['DIC']); self::initAccessibilityControlConcept($GLOBALS['DIC']); self::initLearningObjectMetadata($GLOBALS['DIC']); diff --git a/components/ILIAS/Mail/classes/Service/MailService.php b/components/ILIAS/Mail/classes/Service/MailService.php index fa9ae3562459..70d767177aaf 100755 --- a/components/ILIAS/Mail/classes/Service/MailService.php +++ b/components/ILIAS/Mail/classes/Service/MailService.php @@ -34,6 +34,11 @@ class MailService { public function __construct(protected Container $dic) + { + $this->dic[self::class] = $this; + } + + public function populate(): void { if (!isset($this->dic[ilMailTemplateServiceInterface::class])) { $this->dic[ilMailTemplateServiceInterface::class] = static function (Container $c): ilMailTemplateServiceInterface { @@ -43,6 +48,12 @@ public function __construct(protected Container $dic) ); }; } + + if (!isset($this->dic[TemplateEngineFactoryInterface::class])) { + $this->dic[TemplateEngineFactoryInterface::class] = static function (Container $c): TemplateEngineFactoryInterface { + return $c->mail()->templateEngineFactory(); + }; + } } public function mime(): MimeMailService diff --git a/components/ILIAS/Test/src/TestDIC.php b/components/ILIAS/Test/src/TestDIC.php index 632039d2a69a..1fcef8585ec3 100755 --- a/components/ILIAS/Test/src/TestDIC.php +++ b/components/ILIAS/Test/src/TestDIC.php @@ -178,7 +178,7 @@ protected static function buildDIC(ILIASContainer $DIC): self $dic['logging.information_generator'] = static fn($c): Logging\AdditionalInformationGenerator => new Logging\AdditionalInformationGenerator( - $DIC->mail()->templateEngineFactory()->getBasicEngine(), + $DIC[\ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface::class]->getBasicEngine(), $DIC['lng'], $DIC['ui.factory'], $DIC['refinery'], From a4f9d91d61c222d009740d0c73b9765d354166a3 Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Mon, 2 Mar 2026 12:28:31 +0100 Subject: [PATCH 3/4] [Improvement] Mail: MailService DIC fix Unit Tests --- components/ILIAS/Mail/tests/ilMailBaseTestCase.php | 3 +++ components/ILIAS/Test/tests/ilTestBaseTestCase.php | 1 + components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/components/ILIAS/Mail/tests/ilMailBaseTestCase.php b/components/ILIAS/Mail/tests/ilMailBaseTestCase.php index cccfb348bf9b..ecd5c35347b5 100644 --- a/components/ILIAS/Mail/tests/ilMailBaseTestCase.php +++ b/components/ILIAS/Mail/tests/ilMailBaseTestCase.php @@ -50,6 +50,9 @@ protected function setUp(): void $DIC = new Container(); $DIC['legalDocuments'] = fn() => $this->getMockBuilder(Conductor::class)->disableOriginalConstructor()->getMock(); + $mail_service = new \ILIAS\Mail\Service\MailService($DIC); + $mail_service->populate(); + parent::setUp(); } diff --git a/components/ILIAS/Test/tests/ilTestBaseTestCase.php b/components/ILIAS/Test/tests/ilTestBaseTestCase.php index eea367c1dcdd..1086e16d5ed1 100755 --- a/components/ILIAS/Test/tests/ilTestBaseTestCase.php +++ b/components/ILIAS/Test/tests/ilTestBaseTestCase.php @@ -109,6 +109,7 @@ private function addGlobals(): void $this->addGlobal_resourceStorage(); $this->addGlobal_objectMetadata(); $this->addGlobal_user(); + $this->addGlobal_mail(); $this->defineGlobalConstants(); diff --git a/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php b/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php index b9548338843d..68eeb7923d18 100644 --- a/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php +++ b/components/ILIAS/Test/tests/ilTestBaseTestCaseTrait.php @@ -424,6 +424,14 @@ protected function addGlobal_uiUploadLimitResolver(): void $this->setGlobalVariable('ui.upload_limit_resolver', $this->createMock(\ILIAS\UI\Implementation\Component\Input\UploadLimitResolver::class)); } + protected function addGlobal_mail(): void + { + $this->setGlobalVariable( + \ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface::class, + $this->createMock(\ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface::class) + ); + } + protected function getFileDelivery(): \ILIAS\FileDelivery\Services { $data_signer = new ILIAS\FileDelivery\Token\DataSigner( From 0ce573fecb71defb1bdf6c1c7acd8e5e944baf86 Mon Sep 17 00:00:00 2001 From: Fabian Helfer Date: Tue, 3 Mar 2026 12:53:28 +0100 Subject: [PATCH 4/4] [Improvement] Mail: MailService all services as DIC array access --- .../Init/classes/class.ilInitialisation.php | 4 +- .../Mail/classes/Service/MailService.php | 143 ++++++++++++------ .../Mail/classes/Service/MimeMailService.php | 31 ---- .../ILIAS/Mail/tests/ilMailBaseTestCase.php | 4 +- 4 files changed, 98 insertions(+), 84 deletions(-) diff --git a/components/ILIAS/Init/classes/class.ilInitialisation.php b/components/ILIAS/Init/classes/class.ilInitialisation.php index dffeb5c9f10b..2a03db43213f 100755 --- a/components/ILIAS/Init/classes/class.ilInitialisation.php +++ b/components/ILIAS/Init/classes/class.ilInitialisation.php @@ -35,6 +35,7 @@ use ILIAS\LegalDocuments\Conductor; use ILIAS\ILIASObject\Properties\AdditionalProperties\Icon\Factory as CustomIconFactory; use ILIAS\User\PublicInterface as UserPublicInterface; +use ILIAS\Mail\Service\MailService; // needed for slow queries, etc. if (!isset($GLOBALS['ilGlobalStartTime']) || !$GLOBALS['ilGlobalStartTime']) { @@ -766,8 +767,7 @@ protected static function initLegalDocuments(Container $c): void protected static function initMail(Container $c): void { - $mail_service = new \ILIAS\Mail\Service\MailService($c); - $mail_service->populate(); + MailService::init($c); } protected static function initAccessibilityControlConcept(\ILIAS\DI\Container $c): void diff --git a/components/ILIAS/Mail/classes/Service/MailService.php b/components/ILIAS/Mail/classes/Service/MailService.php index 70d767177aaf..44e029ffa7d7 100755 --- a/components/ILIAS/Mail/classes/Service/MailService.php +++ b/components/ILIAS/Mail/classes/Service/MailService.php @@ -21,57 +21,115 @@ namespace ILIAS\Mail\Service; use ILIAS\DI\Container; -use ILIAS\Mail\Autoresponder\AutoresponderServiceImpl; -use ILIAS\Mail\Autoresponder\AutoresponderService; -use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; use ilMailTemplateService; -use ILIAS\Data\Factory as DataFactory; -use ILIAS\Mail\Autoresponder\AutoresponderDatabaseRepository; +use ilMailMimeSenderFactory; use ilMailTemplateRepository; +use ilMailMimeTransportFactory; use ilMailTemplateServiceInterface; +use ILIAS\Data\Factory as DataFactory; +use ilMailTemplatePlaceholderResolver; +use ilMailTemplatePlaceholderToEmptyResolver; +use ILIAS\Mail\Autoresponder\AutoresponderService; +use ILIAS\Mail\Autoresponder\AutoresponderServiceImpl; +use ILIAS\Mail\Autoresponder\AutoresponderDatabaseRepository; +use ILIAS\Mail\TemplateEngine\TemplateEngineFactoryInterface; use ILIAS\Mail\TemplateEngine\Mustache\MustacheTemplateEngineFactory; class MailService { public function __construct(protected Container $dic) { - $this->dic[self::class] = $this; } - public function populate(): void + public static function init(Container $container): void { - if (!isset($this->dic[ilMailTemplateServiceInterface::class])) { - $this->dic[ilMailTemplateServiceInterface::class] = static function (Container $c): ilMailTemplateServiceInterface { - return new ilMailTemplateService( - new ilMailTemplateRepository($c->database()), - $c->mail()->templateEngineFactory() - ); - }; - } - - if (!isset($this->dic[TemplateEngineFactoryInterface::class])) { - $this->dic[TemplateEngineFactoryInterface::class] = static function (Container $c): TemplateEngineFactoryInterface { - return $c->mail()->templateEngineFactory(); - }; - } + $container[self::class] = static function (Container $c): self { + return new self($c); + }; + + $container[ilMailTemplateServiceInterface::class] = static function (Container $c): ilMailTemplateServiceInterface { + return new ilMailTemplateService( + new ilMailTemplateRepository($c->database()), + $c->mail()->templateEngineFactory() + ); + }; + + $container[TemplateEngineFactoryInterface::class] = static function (Container $c): TemplateEngineFactoryInterface { + return $c->mail()->templateEngineFactory(); + }; + + $container[MimeMailService::class] = static function (Container $c): MimeMailService { + return new MimeMailService($c); + }; + + $container['mail.mime.transport.factory'] = static function (Container $c): ilMailMimeTransportFactory { + return new ilMailMimeTransportFactory($c->settings(), $c->event()); + }; + + $container['mail.mime.sender.factory'] = static function (Container $c): ilMailMimeSenderFactory { + return new ilMailMimeSenderFactory( + $c->settings(), + $c->mail()->templateEngineFactory() + ); + }; + + $container['mail.texttemplates.service'] = static function (Container $c): ilMailTemplateService { + return new ilMailTemplateService( + new ilMailTemplateRepository($c->database()), + $c->mail()->templateEngineFactory() + ); + }; + + $container['mail.template.placeholder.resolver'] = static function (Container $c): ilMailTemplatePlaceholderResolver { + return new ilMailTemplatePlaceholderResolver( + $c->mail()->templateEngineFactory()->getBasicEngine() + ); + }; + + $container[AutoresponderService::class] = static function (Container $c): AutoresponderService { + return new AutoresponderServiceImpl( + (int) $c->settings()->get( + 'mail_auto_responder_idle_time', + (string) AutoresponderService::AUTO_RESPONDER_DEFAULT_IDLE_TIME + ), + false, + new AutoresponderDatabaseRepository($c->database()), + (new DataFactory())->clock()->utc() + ); + }; + + $container[ilMailTemplatePlaceholderResolver::class] = static function (Container $c): ilMailTemplatePlaceholderResolver { + return new ilMailTemplatePlaceholderResolver( + $c->mail()->templateEngineFactory()->getBasicEngine() + ); + }; + + $container[ilMailTemplatePlaceholderToEmptyResolver::class] = static function (Container $c): ilMailTemplatePlaceholderToEmptyResolver { + return new ilMailTemplatePlaceholderToEmptyResolver(); + }; + + $container['mail.template_engine.factory'] = static function (Container $c): MustacheTemplateEngineFactory { + return new MustacheTemplateEngineFactory(); + }; + + $container['mail.signature.service'] = static function (Container $c): MailSignatureService { + return new MailSignatureService( + $c->mail()->templateEngineFactory(), + $c->clientIni(), + $c->language(), + $c->settings() + ); + }; } public function mime(): MimeMailService { - return new MimeMailService($this->dic); + return $this->dic[MimeMailService::class]; } public function autoresponder(): AutoresponderService { - return new AutoresponderServiceImpl( - (int) $this->dic->settings()->get( - 'mail_auto_responder_idle_time', - (string) AutoresponderService::AUTO_RESPONDER_DEFAULT_IDLE_TIME - ), - false, - new AutoresponderDatabaseRepository($this->dic->database()), - (new DataFactory())->clock()->utc() - ); + return $this->dic[AutoresponderService::class]; } public function textTemplates(): ilMailTemplateServiceInterface @@ -79,36 +137,23 @@ public function textTemplates(): ilMailTemplateServiceInterface return $this->dic[ilMailTemplateServiceInterface::class]; } - public function placeholderResolver(): \ilMailTemplatePlaceholderResolver + public function placeholderResolver(): ilMailTemplatePlaceholderResolver { - return new \ilMailTemplatePlaceholderResolver( - $this->templateEngineFactory()->getBasicEngine() - ); + return $this->dic[ilMailTemplatePlaceholderResolver::class]; } - public function placeholderToEmptyResolver(): \ilMailTemplatePlaceholderToEmptyResolver + public function placeholderToEmptyResolver(): ilMailTemplatePlaceholderToEmptyResolver { - return new \ilMailTemplatePlaceholderToEmptyResolver(); + return $this->dic[ilMailTemplatePlaceholderToEmptyResolver::class]; } public function templateEngineFactory(): TemplateEngineFactoryInterface { - if (!isset($this->dic['mail.template_engine.factory'])) { - $this->dic['mail.template_engine.factory'] = static function (Container $c): MustacheTemplateEngineFactory { - return new MustacheTemplateEngineFactory(); - }; - } - return $this->dic['mail.template_engine.factory']; } public function signature(): MailSignatureService { - return new MailSignatureService( - $this->templateEngineFactory(), - $this->dic->clientIni(), - $this->dic->language(), - $this->dic->settings() - ); + return $this->dic['mail.signature.service']; } } diff --git a/components/ILIAS/Mail/classes/Service/MimeMailService.php b/components/ILIAS/Mail/classes/Service/MimeMailService.php index b55ec30bc50b..1dd1ff833d53 100755 --- a/components/ILIAS/Mail/classes/Service/MimeMailService.php +++ b/components/ILIAS/Mail/classes/Service/MimeMailService.php @@ -28,37 +28,6 @@ class MimeMailService { public function __construct(protected Container $dic) { - if (!isset($this->dic['mail.mime.transport.factory'])) { - $this->dic['mail.mime.transport.factory'] = static function (Container $c): ilMailMimeTransportFactory { - return new ilMailMimeTransportFactory($c->settings(), $c->event()); - }; - } - - if (!isset($this->dic['mail.mime.sender.factory'])) { - $this->dic['mail.mime.sender.factory'] = static function (Container $c): ilMailMimeSenderFactory { - return new ilMailMimeSenderFactory( - $c->settings(), - $c->mail()->templateEngineFactory() - ); - }; - } - - if (!isset($this->dic['mail.texttemplates.service'])) { - $this->dic['mail.texttemplates.service'] = static function (Container $c): \ilMailTemplateService { - return new \ilMailTemplateService( - new \ilMailTemplateRepository($c->database()), - $c->mail()->templateEngineFactory() - ); - }; - } - - if (!isset($this->dic['mail.template.placeholder.resolver'])) { - $this->dic["mail.template.placeholder.resolver"] = static function (Container $c): \ilMailTemplatePlaceholderResolver { - return new \ilMailTemplatePlaceholderResolver( - $c->mail()->templateEngineFactory()->getBasicEngine() - ); - }; - } } public function transportFactory(): ilMailMimeTransportFactory diff --git a/components/ILIAS/Mail/tests/ilMailBaseTestCase.php b/components/ILIAS/Mail/tests/ilMailBaseTestCase.php index ecd5c35347b5..1195f363ffce 100644 --- a/components/ILIAS/Mail/tests/ilMailBaseTestCase.php +++ b/components/ILIAS/Mail/tests/ilMailBaseTestCase.php @@ -21,6 +21,7 @@ use ILIAS\DI\Container; use PHPUnit\Framework\TestCase; use ILIAS\LegalDocuments\Conductor; +use ILIAS\Mail\Service\MailService; abstract class ilMailBaseTestCase extends TestCase { @@ -50,8 +51,7 @@ protected function setUp(): void $DIC = new Container(); $DIC['legalDocuments'] = fn() => $this->getMockBuilder(Conductor::class)->disableOriginalConstructor()->getMock(); - $mail_service = new \ILIAS\Mail\Service\MailService($DIC); - $mail_service->populate(); + MailService::init($DIC); parent::setUp(); }