OpenCraft
Follow OC!
  • Home
  • About
  • Solutions
  • Portfolio
  • Clients
  • Blog
  • Contact

Reverse-translating a string back into English in Drupal

Thu, 2009-07-09 10:36
Tags:
  • drupal
  • i18n
By: 
Karim Ratib

While writing the security component for Views Bulk Operations, I needed to create a permission for the execution of each action declared in the system. This would allow the admin to decide which user groups would be able to execute which actions.

In Drupal, permissions are stored as strings. To make a string for each action, that the admin would understand, I decided to use the format "execute [action label] ([action callback])". The label is a human-friendly name while the callback is the name of the action's function. The problem occurred when the action label was translated to another language, or overridden using a module like String Overrides: the permission string no longer looked the same, therefore losing the admin's setting! Not good.

My solution was brute-force: reverse-translate the action label back into its original formulation. It took some digging into Drupal internals, which is always fun to do. Here's the result:

/**
 * Reverse translation: find English string given translated string.
 * WARNING: Will not work for strings with params.
 */
function rt($string) {
  global $language;
  $langcode = $language->language;
 
  // 1. Lookup custom strings.
  static $custom_strings;
  if (!isset($custom_strings[$langcode])) {
    $custom_strings[$langcode] = variable_get('locale_custom_strings_'. $langcode, array());
  }
  if ($source = array_search($string, $custom_strings[$langcode])) {
    return $source;
  }
 
  // 2. Lookup locale translations.
  if (!function_exists('locale') || $langcode == 'en') return $string;
  if (variable_get('locale_cache_strings', 1) == 1) {
    // Cache is on: this string is in the static cache for sure since we have its translated version.
    $locale_t = locale();
    if (isset($locale_t[$langcode]) && ($source = array_search($string, $locale_t[$langcode], TRUE))) {
      return $source;
    }
    else {
      return $string;
    }
  }
  else {
    // Cache is off: look it up in the database.
    $source = db_result(db_query("SELECT s.source FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = '%s' WHERE t.translation = '%s' AND s.textgroup = 'default'", $langcode, $string));
    return $source ? $source : $string;
  }
}

As warned, this will not work for strings with % parameters. I don't know what to do in those cases, but as far as action labels are concerned, this shouldn't be a common occurrence. Otherwise, I tested this function with many scenarios and it seems to be working!

  • kratib's blog

Comments

by Pasqualle (not verified) | Thu, 2009-07-09 18:38

Drupal 7

hopefully it won't be an issue in Drupal 7, with the new hook_permission

  • reply
by DamZ (not verified) | Mon, 2009-07-13 01:25

Not a good idea...

That's not a good idea, because translation is not a bijection: different source strings can potentially result in the same translated text.

I'm not sure I understand the original issue, but don't you have a unique key available that would be more stable then the action label?

  • reply
by kratib | Tue, 2009-07-14 02:48

You're right, it's not 100%

You're right, it's not 100% fool-proof.

But because permission strings are their own keys, there wasn't another option, AFAICT. As mentioned by the other poster, hook_permission should solve this issue in D7.

  • reply

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

Our work

African Network for Localisation

Building a community driven drupal site to support the African...

CMIC Wireframe
CMIC BookWeb

CMIC approached OpenCraft to design the user experience for one...

View our complete portfolio

Related posts

  • Diwan launches its website and online bookstore
  • ArabTechies Code Sprint
  • African Network for Localisation
  • Drupal development
  • SSRDP Portal

More posts by this author

  • Who needs Google Spreadsheets: Use Sheetnode!
  • Code contribution: Views Bulk Operations (VBO)
  • The Automatic Resource Destructor pattern
  • Where in the world is open source?
  • Beware PHP $_REQUEST!

OpenCraft

  • About
  • Team
  • Process
  • Community
  • Media Kit
  • Portfolio
  • Clients
  • Industries
    • Social economic development
    • Multimedia culture
  • Services
    • Drupal development
    • Information architecture
    • Open source software development
    • Social network engineering
  • Request quote
  • Contact
  • Search
Blog

Our profiles at:

Drupal Google
rss

Creative Commons License
search