Skip to content

Commit

Permalink
Fix failure to fall back to site default language, if configured
Browse files Browse the repository at this point in the history
This addresses scenario 6 here
#26232 (comment)
  • Loading branch information
eileenmcnaughton committed Jul 11, 2023
1 parent 79cbcf9 commit b4a639e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 10 deletions.
42 changes: 39 additions & 3 deletions CRM/Core/BAO/Translation.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,49 @@ protected static function getTranslatedFieldsForRequest(AbstractAction $apiReque
foreach ($languages as $language => $languageFields) {
if ($language !== $bizLocale->nominal) {
// Merge in any missing entities. Ie we might have a translation for one template in es_MX but
// need to fall back to es_ES for another.
$fields = array_merge($languageFields, $fields);
// need to fall back to es_ES for another. If there is a translation for the site default
// language we should fall back to that rather than the messageTemplate
// see https://github.com/civicrm/civicrm-core/pull/26232
$fields = array_merge(self::getSiteDefaultLanguageTranslations($apiRequest['entity'])['fields'] ?? [], $languageFields, $fields);
}
}
return ['fields' => $fields, 'language' => $bizLocale->nominal];
}
return [];

// Finally fall back to the translation of the site language, if exists.
// ie if the site language is en_US and there is a translation for that, then use it.
// see https://github.com/civicrm/civicrm-core/pull/26232
return self::getSiteDefaultLanguageTranslations($apiRequest['entity']);
}

/**
* Get any translations configured for the site-default language.
*
* @param string $entity
*
* @throws \CRM_Core_Exception
*/
protected static function getSiteDefaultLanguageTranslations(string $entity): array {
if (!isset(\Civi::$statics[__CLASS__]) || !array_key_exists('site_language_translation', \Civi::$statics[__CLASS__])) {
\Civi::$statics[__CLASS__]['site_language_translation'] = [];
$translations = Translation::get(FALSE)
->addWhere('entity_table', '=', CRM_Core_DAO_AllCoreTables::getTableForEntityName($entity))
->setCheckPermissions(FALSE)
->setSelect(['entity_field', 'entity_id', 'string', 'language'])
->addWhere('language', '=', \Civi::settings()->get('lcMessages'))
->execute();
if ($translations !== NULL) {
\Civi::$statics[__CLASS__]['site_language_translation'] = [
'fields' => [],
'language' => \Civi::settings()->get('lcMessages')
];
foreach ($translations as $translatedField) {
\Civi::$statics[__CLASS__]['site_language_translation']['fields'][$translatedField['entity_id'] . $translatedField['entity_field']] = $translatedField;
}
}
}
$b = \Civi::$statics[__CLASS__]['site_language_translation'];
return \Civi::$statics[__CLASS__]['site_language_translation'];
}

}
4 changes: 3 additions & 1 deletion Civi/WorkflowMessage/Traits/LocalizationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ trait LocalizationTrait {
* 1. Your organization serves many similar locales (eg es_MX+es_CR+es_HN or en_GB+en_US+en_NZ).
* 2. You want to write one message (es_MX) for several locales (es_MX+es_CR+es_HN)
* 3. You want to include some conditional content that adapts the recipient's requested locale
* (es_CR) -- _even though_ the template was stored as es_MX.
* (es_CR) -- _even though_ the template was stored as es_MX. For example your front end
* website has more nuanced translations than your workflow messages and you wish
* to redirect the user to a page on your website.
*
* @var string|null
* @scope tokenContext
Expand Down
36 changes: 30 additions & 6 deletions tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ public function getLocaleConfigurations(): array {

// Check that the en_US template is loaded, if exists.
$result['en_US matches en_US (all-tpls; yes-partials)'] = [$yesPartials, $allTemplates, 'en_US', $rendered['en_US']];
// We have no translation for Danish but there IS an en_US one & en_US is the site-default language. We should
// fall back to it rather than the message template. Ref https://github.com/civicrm/civicrm-core/pull/26232
$result['da_DK matches en_US (all-tpls; yes-partials)'] = [$yesPartials, $allTemplates, 'da_DK', $rendered['en_US']];

return $result;
}
Expand Down Expand Up @@ -218,16 +221,24 @@ public function testGetTemplateTranslationIncompleteTemplateSet(): void {
->addWhere('is_default', '=', 1)
->addWhere('workflow_name', 'LIKE', 'contribution_%')
->addSelect('id', 'workflow_name')
->setLimit(2)
->setLimit(3)
->execute()->indexBy('workflow_name');
$firstTemplate = array_key_first($messageTemplates);
$secondTemplate = array_key_last($messageTemplates);
[$firstTemplate, $secondTemplate, $thirdTemplate] = array_keys($messageTemplates);
foreach ($messageTemplates as $workflowName => $messageTemplate) {
// The translation for the site default language is only used when neither of the other 2 exist.
$records = [
['entity_field' => 'msg_subject', 'string' => 'subject - Spanish', 'language' => 'es_ES'],
['entity_field' => 'msg_html', 'string' => 'html -Spanish', 'language' => 'es_ES'],
['entity_field' => 'msg_subject', 'string' => 'subject - site default translation', 'language' => 'en_US'],
['entity_field' => 'msg_html', 'string' => 'html - site default translation', 'language' => 'en_US'],
];
if ($workflowName === $thirdTemplate) {
// All except one template gets a Spanish translation. This should be used where there is no Mexican translation.
$records = [
['entity_field' => 'msg_subject', 'string' => 'subject - Spanish', 'language' => 'es_ES'],
['entity_field' => 'msg_html', 'string' => 'html -Spanish', 'language' => 'es_ES'],
];
}
if ($secondTemplate === $workflowName) {
// One gets a Mexican translation. This should be used.
$records[] = ['entity_field' => 'msg_subject', 'string' => 'subject - Mexican', 'language' => 'es_MX'];
$records[] = ['entity_field' => 'msg_html', 'string' => 'html - Mexican', 'language' => 'es_MX'];
}
Expand All @@ -246,8 +257,9 @@ public function testGetTemplateTranslationIncompleteTemplateSet(): void {
->setTranslationMode('fuzzy')
->execute()->first();
$this->assertEquals('subject - Mexican', $translatedTemplate['msg_subject']);
$this->assertEquals('html - Mexican', $translatedTemplate['msg_html']);

// This SHOULD fall back to Spanish...
// This should fall back to Spanish...
$translatedTemplate = MessageTemplate::get()
->addWhere('is_default', '=', 1)
->addWhere('workflow_name', '=', $firstTemplate)
Expand All @@ -256,6 +268,18 @@ public function testGetTemplateTranslationIncompleteTemplateSet(): void {
->setTranslationMode('fuzzy')
->execute()->first();
$this->assertEquals('subject - Spanish', $translatedTemplate['msg_subject']);
$this->assertEquals('html -Spanish', $translatedTemplate['msg_html']);

// This should fall back to en_US translation...
$translatedTemplate = MessageTemplate::get()
->addWhere('is_default', '=', 1)
->addWhere('workflow_name', '=', $thirdTemplate)
->addSelect('id', 'msg_subject', 'msg_html', 'msg_text')
->setLanguage('es_MX')
->setTranslationMode('fuzzy')
->execute()->first();
$this->assertEquals('subject - site default translation', $translatedTemplate['msg_subject']);
$this->assertEquals('html - site default translation', $translatedTemplate['msg_html']);
}

/**
Expand Down

0 comments on commit b4a639e

Please sign in to comment.