Message sent in interface language instead of set language as MessageTemplate::getText() is not fully respecting the $langcode parameter
>>> [!note] Migrated issue <!-- Drupal.org comment --> <!-- Migrated from issue #3307555. --> Reported by: [tcrawford](https://www.drupal.org/user/3642990) Related to !7 >>> <h3 id="summary-problem-motivation">Problem/Motivation</h3> <p>Messages sent (by the message_notify module) are in the incorrect language. The issue I believe is that the class Drupal\message\Entity\MessageTemplate is not properly respecting the langcode passed to Drupal\message\Entity\MessageTemplate::getText() in the scenario where a user (with an arbitrary interface language) attempts to send a message to a recipient with a different target language.</p> <h4 id="summary-steps-reproduce">Steps to reproduce</h4> <p>Setup multiple languages.<br> Setup the interface language to be determined by some factor, such as a language prefix in the URL.<br> Login as an authenticated user.<br> On a UI with an arbitrary current interface language (e.g. Japanese) trigger a message to a recipient (code below).<br> The recipient receives the email in the interface language of the sender and not the language specified when sending the message.</p> <p>Simplified example code</p> <div class="codeblock"> <pre><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br></span><span style="color: #FF8000">// Site default language EN. <br></span><span style="color: #0000BB">$recipients_language </span><span style="color: #007700">= </span><span style="color: #DD0000">'DE'</span><span style="color: #007700">;<br><br></span><span style="color: #FF8000">// Code below triggered by logged in user with current interface language at runtime of JA<br></span><span style="color: #0000BB">$message </span><span style="color: #007700">= </span><span style="color: #0000BB">Message</span><span style="color: #007700">::</span><span style="color: #0000BB">create</span><span style="color: #007700">([<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #DD0000">'template' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$template</span><span style="color: #007700">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #DD0000">'field_order' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$order</span><span style="color: #007700">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #DD0000">'langcode' </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$recipients_language</span><span style="color: #007700">,<br>&nbsp;&nbsp;&nbsp; ]);<br><br></span><span style="color: #FF8000">// According to the MessageInterface docblock this is the language that should be used for sending the message.<br></span><span style="color: #0000BB">$message</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setLanguage</span><span style="color: #007700">(</span><span style="color: #0000BB">$recipients_language</span><span style="color: #007700">);<br><br></span><span style="color: #0000BB">$message</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">save</span><span style="color: #007700">();<br><br></span><span style="color: #0000BB">$notifierSender </span><span style="color: #007700">= \</span><span style="color: #0000BB">Drupal</span><span style="color: #007700">::</span><span style="color: #0000BB">service</span><span style="color: #007700">(</span><span style="color: #DD0000">'@message_notify.sender'</span><span style="color: #007700">);<br></span><span style="color: #0000BB">$notifierSender</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">send</span><span style="color: #007700">(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$message</span><span style="color: #007700">,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [</span><span style="color: #DD0000">'mail' </span><span style="color: #007700">=&gt; </span><span style="color: #DD0000">'$recipientEmail'</span><span style="color: #007700">],<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #DD0000">'email'<br></span><span style="color: #007700">);<br></span><span style="color: #0000BB">?&gt;</span></span></pre></div> <p>The recipient receives the email in Japanese instead of the specified language of German.</p> <h3 id="summary-proposed-resolution">Proposed resolution</h3> <p>Modify MessageTemplate::getText() as follows:</p> <div class="codeblock"> <pre><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br>&nbsp; </span><span style="color: #FF8000">/**<br>&nbsp;&nbsp; * {@inheritdoc}<br>&nbsp;&nbsp; */<br>&nbsp; </span><span style="color: #007700">public function </span><span style="color: #0000BB">getText</span><span style="color: #007700">(</span><span style="color: #0000BB">$langcode </span><span style="color: #007700">= </span><span style="color: #0000BB">Language</span><span style="color: #007700">::</span><span style="color: #0000BB">LANGCODE_NOT_SPECIFIED</span><span style="color: #007700">, </span><span style="color: #0000BB">$delta </span><span style="color: #007700">= </span><span style="color: #0000BB">NULL</span><span style="color: #007700">) {<br>&nbsp;&nbsp;&nbsp; </span><span style="color: #FF8000">// As config, the message template will likely be loaded in the<br>&nbsp;&nbsp;&nbsp; // current (interface) language, which may not be desired language.<br>&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$text </span><span style="color: #007700">= </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">text</span><span style="color: #007700">;<br><br>&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$language_manager </span><span style="color: #007700">= \</span><span style="color: #0000BB">Drupal</span><span style="color: #007700">::</span><span style="color: #0000BB">languageManager</span><span style="color: #007700">();<br>&nbsp;&nbsp;&nbsp; if (</span><span style="color: #0000BB">$language_manager </span><span style="color: #007700">instanceof </span><span style="color: #0000BB">ConfigurableLanguageManagerInterface</span><span style="color: #007700">) {<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (</span><span style="color: #0000BB">$langcode </span><span style="color: #007700">== </span><span style="color: #0000BB">Language</span><span style="color: #007700">::</span><span style="color: #0000BB">LANGCODE_NOT_SPECIFIED</span><span style="color: #007700">) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #FF8000">// Get the default language code when not specified.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$langcode </span><span style="color: #007700">= </span><span style="color: #0000BB">$language_manager</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getDefaultLanguage</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">getId</span><span style="color: #007700">();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #FF8000">// We always need to translate the text if the text is not in the desired<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // language.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #007700">if (</span><span style="color: #0000BB">$language_manager</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getCurrentLanguage</span><span style="color: #007700">()-&gt;</span><span style="color: #0000BB">getId</span><span style="color: #007700">() !== </span><span style="color: #0000BB">$langcode</span><span style="color: #007700">) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$config_translation </span><span style="color: #007700">= </span><span style="color: #0000BB">$language_manager</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getLanguageConfigOverride</span><span style="color: #007700">(</span><span style="color: #0000BB">$langcode</span><span style="color: #007700">, </span><span style="color: #DD0000">'message.template.' </span><span style="color: #007700">. </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id</span><span style="color: #007700">());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$translated_text </span><span style="color: #007700">= </span><span style="color: #0000BB">$config_translation</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">get</span><span style="color: #007700">(</span><span style="color: #DD0000">'text'</span><span style="color: #007700">);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #FF8000">// If there was no translated text, we return nothing instead of falling<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // back to the default language.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000BB">$text </span><span style="color: #007700">= </span><span style="color: #0000BB">$translated_text </span><span style="color: #007700">?: [];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br></span><span style="color: #0000BB">?&gt;</span></span></pre></div> <p>The above code will be invoked within Message::getText() and passed the recipient's langcode.</p> <p>The issue is that the template and hence the template text is loaded in the interface language and not always translated to the recipient language. The text must be translated whenever the current interface language (which is used to load the template) is not equal to the recipient's language (as defined by the $langcode parameter). </p> <p>I have attached a patch and create an MR shortly.</p> <h3 id="summary-remaining-tasks">Remaining tasks</h3> <p>Submit MR.</p> <h3 id="summary-ui-changes">User interface changes</h3> <p>None.</p> <h3 id="summary-api-changes">API changes</h3> <p>None. </p> <h3 id="summary-data-model-changes">Data model changes</h3>
issue