Support from Acquia helps fund testing for Drupal Acquia logo

Comments

AohRveTPV’s picture

Title: password expiration mail » password expiration mail not translatable
Category: Support request » Bug report

It looks to me like the default e-mail subject (expire_warning_email_subject) is not translatable currently. The body (expire_warning_email_message) looks to be empty, so there is nothing to translate.

Recategorizing as a bug since the default subject should be translatable.

I have never really used translations, but my understanding is if you configure a custom e-mail subject or body, it would be stored in a variable, and you would need to use "Variable translation" in the Internationalization module to translate the variable. So we need only to make the default strings translatable. Please correct me if wrong.

Grimreaper’s picture

Talking about translations, I see there is empty form field description with empty t(''), which is useless.

For the default value, I think using a t() function at this level will be good. I didn't test.

But after overriding using custom values. It is saved in the database with the policies config, so not in a variable, and it is not translatable. That why I asked the question.

For strings in t() function and variables, I know how to translate but for strings in configuration objects I didn't know, I have not experienced before.

Grimreaper’s picture

I have taken a look at how rules managed to translate its rules.

In rules_i18n, it uses the i18n_string API. But it needs to indicate to the i18n_string the object to manage. I don't figure if it will be a lot of work or not for password policy to have the same think.

AohRveTPV’s picture

I understand the problem now. These strings aren't stored in Drupal variables so they cannot be translated by Variable Translation. I am not familiar with the Ctools APIs and do not know either how these configurations are typically translated.

The i18n_string API looks promising. Thanks for sharing.

Patches would be welcome. My current focus is on fixing bugs in 1.x.

nicrodgers’s picture

This patch makes the warning email translatable, providing you have i18n_variable enabled.

I've had to change the settings form to use system_settings_form, so that the i18n_variable module can add it's language selection interface in.

Status: Needs review » Needs work

The last submitted patch, 5: password_policy-translate-warning-2444387-05.patch, failed testing.

nicrodgers’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev

Whoops, forgot to change the version. We are using the stable version in prod.

nicrodgers’s picture

Status: Needs work » Needs review
prashant.kabade’s picture

I have achieved this using another contrib module . https://www.drupal.org/project/mail_edit

AohRveTPV’s picture

In 7.x-1.x, the mail subject and body is handled the same as in the core User module.

user.module:

 if ($admin_setting = variable_get('user_mail_' . $key, FALSE)) {
    // An admin setting overrides the default string.
    $text = $admin_setting;
  }
  else {
    // No override, return default string.
    switch ($key) {
      case 'register_no_approval_required_subject':
        $text = t('Account details for [user:name] at [site:name]', array(), array('langcode' => $langcode));
        break;
      case 'register_no_approval_required_body':
        $text = t("[user:name],

password_policy.module:

  if ($admin_setting = variable_get('password_policy_' . $key, FALSE)) {
    // An admin setting overrides the default string.
    $text = $admin_setting;
  }
  else {
    // No override, return default string.
    switch ($key) {
      case 'warning_subject':
        $text = t('Password expiration warning for [user:name] at [site:name]', array(), array('langcode' => $langcode));
        break;

      case 'warning_body':
        $text = t("[user:name],\n\nYour password at [site:name] will expire in less than [password-policy:days-left] day(s).\n\nPlease go to [password-policy:password-edit-url] to change your password.", array(), array('langcode' => $langcode));
        break;

Both just use variable_get() when a custom mail subject and body has been set. The User module mail must be translatable somehow without implementing hook_variable_info(). Why then does Password Policy need to implement hook_variable_info() when User module does not?

nicrodgers’s picture

hi @AohRveTPV

If you only use D7 core, then no, the mail variables are not translatable unless you install some contrib modules.

To translate them, you install i18n and enable i18n_variable. This depends in the contrib module 'variable'. It's the variable contrib module that makes the core variables translatable, see http://cgit.drupalcode.org/variable/tree/includes/user.variable.inc?id=7... - basically by implementing hook_variable_info.

attached is a re-rolled patch for latest 7.x-1.x-dev

AohRveTPV’s picture

Thanks for explaining.

Minor changes after a first-pass, superficial review:
- Changed function_exists() to module_exists(). It seems to me like module_exists() is kind of self-documenting and avoids the need for an inline comment explaining why we are using function_exists()?
- Fixed indentation on a line.
- Removed some trailing spaces.

Two things I'm not sure on:
- Is it OK to call both variable_del() and variable_delete() for the same variables (as is done in the reset callback)?
- Does variable_delete() need to be called by hook_uninstall()?

I'm also wondering how the variable modules can translate the core mails without modifying core. If it's not necessary to modify core to translate the core mails, why is it necessary to modify Password Policy to translate its mails? Don't necessarily need an answer on that, just something I'm wondering.

AohRveTPV’s picture

Also I believe "Email" should be "E-mail" in Drupal 7. Or at least for consistency with the rest of Password Policy. It's "Email" in Drupal 8. I'll update patch later.

AohRveTPV’s picture

Minor changes:
- Fixed two Coder errors due to consecutive blank lines.
- Changed "email" to "e-mail" per Drupal 7 convention.
- Changed "e-mail body" to just "body" for consistency with "subject".

nicrodgers’s picture

Hi @AohRveTPV - thanks for your work on this and sorry for taking a while to come back to you. I'm working on a D8 project at the mo, and don't have much time spare for D7 stuff,.

I can't find any evidence to suggest issues with variable_del and variable_delete being called at the same time, but I think you're right that it'd probably be better to refactor the reset code so the deletion of those two variables are in an if/else block.

About uninstallation, from what I can see, variables set using variable API are automatically deleted by the variable module when the *variable* module is uninstalled. So yes, it's probably worth adding a variable_delete call in password_policy's hook_uninstall to tidy things up.

Re your question/pondering about how variable module can translate core without modifying core, that's sort of the point of the module. There's specific code within the variable module that makes core variables translatable. Take a look at that user.variable.inc file to see how it works. As well as making core variables translatable, the purpose of the variable module is to enable contrib modules to also have their variables translated. To do that, you must implement hook_variable_info (as per this patch). More info here: http://cgit.drupalcode.org/variable/tree/README.txt?id=7.x-1.x

Sorry I've not had a chance to create an updated patch to do this stuff, I will try to do that in a few weeks after this current project, if it hasn't been picked up in the meantime.

AohRveTPV’s picture

Generally I do not commit patches that integrate directly with other contributed modules because I feel it produces spaghetti code. (It adds unnecessary coupling that makes the code complex and hard to understand/maintain/test.) Usually there's a way to integrate without adding module-specific code. But I think an exception is warranted here since the module is otherwise not internationalizable.

It might be better to move the hook_variable_info() implementation to password_policy.variable.inc. password_policy.module is overly long. Will update patch to do this if I get a chance.

AohRveTPV’s picture

nicrodgers, did you try using the 'mail_text' variable type? I was just working on this and it looks like other mails use that type. Here's what I have so far (not working):

  $variables['password_policy_warning_[mail_part]'] = array(
    'title' => t('Password Policy warning e-mail'),
    'type' => 'mail_text',
    'group' => 'user_mails',
  );
AohRveTPV’s picture

Untested patch that moves hook_variable_info() implementation to password_policy.variable.inc. Also changes the variables to type 'mail_text'. There seems to be no need to set the 'localize' key because it is set TRUE for the 'mail_text' variable type in the Variable module.

AohRveTPV’s picture

Changes:
- Made variable description more consistent with fields descriptions, and more consistent with User module email descriptions. Now shows list of available variables.
- Changed module_exists('variable') back to function_exists('variable_delete'). This seems more defensive against possible Variable module API changes, however unlikely.
- Added function to eliminate duplicate definitions of warning email tokens help.

I tested this manually with two languages, and verified the correct warning e-mail translation was sent according to the user's chosen language.

If this passes testing, and no one sees any issues with this patch, will plan to commit soon.

  • AohRveTPV committed ab24adb on 7.x-1.x authored by nicrodgers
    Issue #2444387 by AohRveTPV, nicrodgers: password expiration mail not...
AohRveTPV’s picture

Status: Needs review » Fixed
AohRveTPV’s picture

Fixed bug found in previous commit.

  • AohRveTPV committed 45282ab on 7.x-1.x authored by nicrodgers
    Issue #2444387 by AohRveTPV, nicrodgers: password expiration mail not...
  • AohRveTPV committed 81a4044 on 7.x-1.x
    Revert "Issue #2444387 by AohRveTPV, nicrodgers: password expiration...
AohRveTPV’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev
Status: Fixed » Active

Setting back to 7.x-2.x, where this bug still exists.