diff --git a/.gitignore b/.gitignore
index 633484b68..b1fe992b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@
# Customization Files
/Web/custom-favicon.png
/Web/img/custom-logo.png
+lang/*/*-custom.tpl
# Upload Directories
/uploads/*
diff --git a/Pages/Admin/ManageEmailTemplatesPage.php b/Pages/Admin/ManageEmailTemplatesPage.php
index c9e07a47b..9605f08ac 100644
--- a/Pages/Admin/ManageEmailTemplatesPage.php
+++ b/Pages/Admin/ManageEmailTemplatesPage.php
@@ -44,6 +44,8 @@ public function SetSaveResult($saveResult);
* @return string
*/
public function GetUpdatedTemplateName();
+
+ public function GetUpdatedLanguage(): string;
}
class ManageEmailTemplatesPage extends ActionPage implements IManageEmailTemplatesPage
@@ -75,6 +77,11 @@ public function ProcessPageLoad()
$this->Display('Admin/Configuration/manage_email_templates.tpl');
}
+ public function GetUpdatedLanguage(): string
+ {
+ return $this->GetForm(FormKeys::EMAIL_TEMPLATE_LANGUAGE);
+ }
+
public function GetLanguage()
{
return $this->GetQuerystring(QueryStringKeys::LANGUAGE);
diff --git a/Pages/HelpPage.php b/Pages/HelpPage.php
index 89d967579..d6783b4d4 100644
--- a/Pages/HelpPage.php
+++ b/Pages/HelpPage.php
@@ -18,20 +18,5 @@ public function PageLoad()
$this->Set('ServerTimezone', date_default_timezone_get());
$this->DisplayLocalized('support-and-credits.tpl');
-
- // $helpType = $this->GetQuerystring('ht');
-//
-// if ($helpType == 'about')
-// {
-//
-// }
-// else if ($helpType == 'admin')
-// {
-// $this->DisplayLocalized('help-admin.tpl');
-// }
-// else
-// {
-// $this->DisplayLocalized('help.tpl');
-// }
}
}
diff --git a/Pages/Page.php b/Pages/Page.php
index 1b975d9c5..11eb6b0e8 100644
--- a/Pages/Page.php
+++ b/Pages/Page.php
@@ -395,13 +395,10 @@ protected function DisplayCsv($templateName, $fileName)
/**
* @param string $templateName
- * @param null $languageCode uses current language is nothing is passed in
*/
- protected function DisplayLocalized($templateName, $languageCode = null)
+ protected function DisplayLocalized($templateName)
{
- if (empty($languageCode)) {
- $languageCode = $this->GetVar('CurrentLanguage');
- }
+ $languageCode = $this->GetVar('CurrentLanguage');
$localizedPath = ROOT_DIR . 'lang/' . $languageCode;
$defaultPath = ROOT_DIR . 'lang/en_us/';
diff --git a/Presenters/Admin/ManageEmailTemplatesPresenter.php b/Presenters/Admin/ManageEmailTemplatesPresenter.php
index 5a09b8e28..b5a44afbd 100644
--- a/Presenters/Admin/ManageEmailTemplatesPresenter.php
+++ b/Presenters/Admin/ManageEmailTemplatesPresenter.php
@@ -117,7 +117,7 @@ public function UpdateEmailTemplate()
try {
Log::Debug('Updating email template. Template=%s', $templateName);
- $templatePath = Paths::EmailTemplates($this->GetSelectedLanguage());
+ $templatePath = Paths::EmailTemplates($this->page->GetUpdatedLanguage());
$saveResult = $this->filesystem->Save($templatePath, str_replace('.tpl', '-custom.tpl', $templateName), $this->page->GetTemplateContents());
$this->filesystem->FlushSmartyCache();
diff --git a/config/config.dist.php b/config/config.dist.php
index 08f2c2102..4b13f843a 100644
--- a/config/config.dist.php
+++ b/config/config.dist.php
@@ -18,6 +18,7 @@
$conf['settings']['default.page.size'] = '50'; // number of records per page
$conf['settings']['enable.email'] = 'true'; // global configuration to enable if any emails will be sent
$conf['settings']['default.language'] = 'en_us'; // find your language in the lang directory
+$conf['settings']['enforce.custom.mail.template'] = 'false'; // Fallback to default.language for missing custom templates, bu only when custom template is available for default.language
$conf['settings']['script.url'] = ''; // public URL to the Web directory of this instance. this is the URL that appears when you are logging in. leave http: or https: off to auto-detect
$conf['settings']['image.upload.directory'] = 'Web/uploads/images'; // full or relative path to where images will be stored
$conf['settings']['image.upload.url'] = 'uploads/images'; // full or relative path to show uploaded images from
diff --git a/lang/du_nl/AccountCreation-custom.tpl b/lang/du_nl/AccountCreation-custom.tpl
deleted file mode 100644
index 0e237d69c..000000000
--- a/lang/du_nl/AccountCreation-custom.tpl
+++ /dev/null
@@ -1,11 +0,0 @@
-
{$To},
-
-
Een nieuwe gebruiker is geregistreerd met de volgende informatie:
-Email: {$EmailAddress}
-Naam: {$FullName}
-Telefoonnummer: {$Phone}
-Organisatie: {$Organization}
-Positie: {$Position}
A new user has registered with the following information:
-Email: {$EmailAddress}
-Name: {$FullName}
-Phone: {$Phone}
-Organization: {$Organization}
-Position: {$Position}
-{if !empty($CreatedBy)}
- Created by: {$CreatedBy}
-{/if}
\ No newline at end of file
diff --git a/lang/es/AccountCreation-custom.tpl b/lang/es/AccountCreation-custom.tpl
deleted file mode 100644
index 19c5317f6..000000000
--- a/lang/es/AccountCreation-custom.tpl
+++ /dev/null
@@ -1,11 +0,0 @@
-
{$To},
-
-
Se ha registrado un nuevo usuario con la siguiente información:
-Correo electrónico: {$EmailAddress}
-Nombre: {$FullName}
-Teléfono: {$Phone}
-Organización: {$Organization}
-Cargo: {$Position}
-{if !empty($CreatedBy)}
- Creado por: {$CreatedBy}
-{/if}
\ No newline at end of file
diff --git a/lang/fr_fr/AccountCreation-custom.tpl b/lang/fr_fr/AccountCreation-custom.tpl
deleted file mode 100644
index 3920effd2..000000000
--- a/lang/fr_fr/AccountCreation-custom.tpl
+++ /dev/null
@@ -1,11 +0,0 @@
-
{$To},
-
-
Un nouvel utilisateur s'est enregistré avec les informations suivantes:
-Email: {$EmailAddress}
-Nom: {$FullName}
-Téléphone: {$Phone}
-Organisation: {$Organization}
-Position: {$Position}
-{if !empty($CreatedBy)}
- Créé par: {$CreatedBy}
-{/if}
\ No newline at end of file
diff --git a/lang/pt_br/AccountCreation-custom.tpl b/lang/pt_br/AccountCreation-custom.tpl
deleted file mode 100644
index 20fb80b9b..000000000
--- a/lang/pt_br/AccountCreation-custom.tpl
+++ /dev/null
@@ -1,18 +0,0 @@
-
- {$To},
-
-
-
-
- Um novo usuário se registrou com as seguintes informações:
-
- E-mail: {$EmailAddress}
-
- Nome: {$FullName}
-
- Organização: {$Organization}
- {if !empty($CreatedBy)}
-
- Criada por: {$CreatedBy}
- {/if}
-
diff --git a/lib/Common/SmartyPage.php b/lib/Common/SmartyPage.php
index 54703ed69..b8244f77e 100644
--- a/lib/Common/SmartyPage.php
+++ b/lib/Common/SmartyPage.php
@@ -76,46 +76,41 @@ public function AddTemplateDirectory($templateDirectory)
}
/**
+ * Fetches template in a specific language. A custom template file might override the default template.
+ * In case the template is not available in the target language it will fall back to en_us.
* @param string $templateName
- * @param null $languageCode uses current language is nothing is passed in
- */
- public function DisplayLocalized($templateName, $languageCode = null)
- {
- if (empty($languageCode)) {
- $languageCode = $this->getTemplateVars('CurrentLanguage');
- }
- $localizedPath = ROOT_DIR . 'lang/' . $languageCode;
- $defaultPath = ROOT_DIR . 'lang/en_us/' . $templateName;
-
- if (file_exists($localizedPath . '/' . $templateName)) {
- $this->AddTemplateDirectory($localizedPath);
- } else {
- $this->AddTemplateDirectory($defaultPath);
- }
-
- $this->Display($templateName);
- }
-
- /**
- * @param string $templateName
- * @param null $languageCode uses current language is nothing is passed in
+ * @param string $languageCode Will be set to template var CurrentLanguage if null
+ * @param bool $enforceCustomTemplate if true uses custom language from default language
+ * if custom template of the target language is not available.
* @return string
*/
- public function FetchLocalized($templateName, $languageCode = null)
+ public function FetchLocalized($templateName, bool $enforceCustomTemplate, string $languageCode = null)
{
- if (empty($languageCode)) {
+ if ($languageCode == null) {
$languageCode = $this->getTemplateVars('CurrentLanguage');
}
- $localizedPath = ROOT_DIR . 'lang/' . $languageCode;
- $defaultPath = ROOT_DIR . 'lang/en_us/';
+ $langPath = ROOT_DIR . 'lang/';
+ $localizedPath = $langPath . $languageCode;
$customTemplateName = str_replace('.tpl', '-custom.tpl', $templateName);
+ $hasCustomTemplate = file_exists($localizedPath . '/' . $customTemplateName);
+
+ if ($enforceCustomTemplate && !$hasCustomTemplate) {
+ $defaultLanguageCode = Configuration::Instance()->GetKey(ConfigKeys::LANGUAGE);
+ $defaultLocalizedPath = $langPath . $defaultLanguageCode;
+ $hasCustomDefaultTemplate = file_exists($defaultLocalizedPath . '/' . $customTemplateName);
+ if ($languageCode != $defaultLanguageCode && $hasCustomDefaultTemplate) {
+ $hasCustomTemplate = true;
+ $localizedPath = $defaultLocalizedPath;
+ }
+ }
- if (file_exists($localizedPath . '/' . $templateName) || file_exists($localizedPath . '/' . $customTemplateName)) {
+ if (file_exists($localizedPath . '/' . $templateName) || $hasCustomTemplate) {
$path = $localizedPath;
$this->AddTemplateDirectory($localizedPath);
} else {
- $path = $defaultPath;
- $this->AddTemplateDirectory($defaultPath);
+ // Fallback path
+ $path = ROOT_DIR . 'lang/en_us/';
+ $this->AddTemplateDirectory($path);
}
if (file_exists($path . '/' . $customTemplateName)) {
diff --git a/lib/Config/ConfigKeys.php b/lib/Config/ConfigKeys.php
index 3d8e7902a..8f3c7800d 100644
--- a/lib/Config/ConfigKeys.php
+++ b/lib/Config/ConfigKeys.php
@@ -18,6 +18,7 @@ class ConfigKeys
public const HOME_URL = 'home.url';
public const INACTIVITY_TIMEOUT = 'inactivity.timeout';
public const LANGUAGE = 'default.language';
+ public const ENFORCE_CUSTOM_MAIL_TEMPLATE = 'enforce.custom.mail.template';
public const LOGOUT_URL = 'logout.url';
public const NAME_FORMAT = 'name.format';
public const SCRIPT_URL = 'script.url';
diff --git a/lib/Email/EmailMessage.php b/lib/Email/EmailMessage.php
index f0eaa2de5..f74193433 100644
--- a/lib/Email/EmailMessage.php
+++ b/lib/Email/EmailMessage.php
@@ -5,7 +5,7 @@ abstract class EmailMessage implements IEmailMessage
/**
* @var SmartyPage
*/
- private $email;
+ protected $email;
/**
* @var string|null
*/
@@ -15,8 +15,11 @@ abstract class EmailMessage implements IEmailMessage
*/
private $attachmentFileName;
+ protected bool $enforceCustomTemplate;
+
protected function __construct($languageCode = null)
{
+ $this->enforceCustomTemplate = Configuration::Instance()->GetKey(ConfigKeys::ENFORCE_CUSTOM_MAIL_TEMPLATE, new BooleanConverter());
$this->email = new SmartyPage($resources);
$resources = Resources::GetInstance();
if (!empty($languageCode)) {
@@ -37,7 +40,7 @@ protected function Set($var, $value)
protected function FetchTemplate($templateName, $includeHeaders = true)
{
$header = $includeHeaders ? $this->email->fetch('Email/emailheader.tpl') : '';
- $body = $this->email->FetchLocalized($templateName);
+ $body = $this->email->FetchLocalized($templateName, $this->enforceCustomTemplate);
$footer = $includeHeaders ? $this->email->fetch('Email/emailfooter.tpl') : '';
return $header . $body . $footer;
diff --git a/lib/Email/Messages/ReportEmailMessage.php b/lib/Email/Messages/ReportEmailMessage.php
index c0cd84ef3..5599848a1 100644
--- a/lib/Email/Messages/ReportEmailMessage.php
+++ b/lib/Email/Messages/ReportEmailMessage.php
@@ -32,7 +32,7 @@ public function __construct($report, $definition, $toAddress, $reportUser, $sele
$this->Set('Definition', $definition);
$this->Set('Report', $report);
$this->Set('ReportCsvColumnView', new ReportCsvColumnView($selectedColumns));
- $contents = $this->FetchTemplate('Reports/custom-csv.tpl', false);
+ $contents = $this->email->FetchLocalized('Reports/custom-csv.tpl', false);
$name = $report->ReportName();
if (!empty($name)) {
diff --git a/lib/Email/Messages/ReservationShareEmail.php b/lib/Email/Messages/ReservationShareEmail.php
index bba5460cd..5d6b0adb1 100644
--- a/lib/Email/Messages/ReservationShareEmail.php
+++ b/lib/Email/Messages/ReservationShareEmail.php
@@ -7,7 +7,7 @@ class ReservationShareEmail extends ReservationEmailMessage
/**
* @var string
*/
- private $email;
+ private $emailToShare;
public function __construct(User $reservationOwner, $emailToShare, ReservationSeries $reservationSeries, IAttributeRepository $attributeRepository, IUserRepository $userRepository)
{
@@ -16,12 +16,12 @@ public function __construct(User $reservationOwner, $emailToShare, ReservationSe
$this->reservationOwner = $reservationOwner;
$this->reservationSeries = $reservationSeries;
$this->timezone = $reservationOwner->Timezone();
- $this->email = $emailToShare;
+ $this->emailToShare = $emailToShare;
}
public function To()
{
- return [new EmailAddress($this->email)];
+ return [new EmailAddress($this->emailToShare)];
}
public function Subject()
diff --git a/lib/Server/FormKeys.php b/lib/Server/FormKeys.php
index 631a3d9fb..1dc168259 100644
--- a/lib/Server/FormKeys.php
+++ b/lib/Server/FormKeys.php
@@ -89,6 +89,7 @@ private function __construct()
public const ENABLE_AUTO_RELEASE = 'ENABLE_AUTO_RELEASE';
public const EMAIL_CONTENTS = 'EMAIL_CONTENTS';
public const EMAIL_TEMPLATE_NAME = 'EMAIL_TEMPLATE_NAME';
+ public const EMAIL_TEMPLATE_LANGUAGE = 'EMAIL_TEMPLATE_LANGUAGE';
public const FIRST_NAME = 'fname';
public const FAVICON_FILE = 'FAVICON_FILE';
diff --git a/tests/Presenters/Admin/ManageEmailTemplatesPresenterTest.php b/tests/Presenters/Admin/ManageEmailTemplatesPresenterTest.php
index f90f5e306..ed428b983 100644
--- a/tests/Presenters/Admin/ManageEmailTemplatesPresenterTest.php
+++ b/tests/Presenters/Admin/ManageEmailTemplatesPresenterTest.php
@@ -74,11 +74,12 @@ public function testUpdatesEmailTemplate()
$this->page->_UpdatedTemplateName = $templateName;
$this->page->_TemplateContents = $contents;
$this->page->_Language = 'en_us';
+ $this->page->_UpdatedLanguage = 'cz';
$this->presenter->UpdateEmailTemplate();
$this->assertEquals($contents, $this->fileSystem->_AddedFileContents);
- $this->assertEquals(Paths::EmailTemplates('en_us'), $this->fileSystem->_AddedFilePath);
+ $this->assertEquals(Paths::EmailTemplates('cz'), $this->fileSystem->_AddedFilePath);
$this->assertEquals('template-custom.tpl', $this->fileSystem->_AddedFileName);
}
}
@@ -91,6 +92,7 @@ class FakeManageEmailTemplatesPage extends ManageEmailTemplatesPage
public $_BoundTemplateContents;
public $_TemplateContents;
public $_Language;
+ public $_UpdatedLanguage;
public $_SaveResult = true;
public function BindTemplateNames($templates)
@@ -123,6 +125,11 @@ public function GetLanguage()
return $this->_Language;
}
+ public function GetUpdatedLanguage(): string
+ {
+ return $this->_UpdatedLanguage;
+ }
+
public function SetSaveResult($saveResult)
{
$this->_SaveResult = $saveResult;
diff --git a/tpl/Admin/Configuration/manage_email_templates.tpl b/tpl/Admin/Configuration/manage_email_templates.tpl
index c7db93147..8a888869b 100644
--- a/tpl/Admin/Configuration/manage_email_templates.tpl
+++ b/tpl/Admin/Configuration/manage_email_templates.tpl
@@ -16,19 +16,19 @@
-