The way it's currently designed, the default value for Captcha description (CAPTCHA_DESCRIPTION) cannot be translated into other languages.

define('CAPTCHA_DESCRIPTION', 'This question is used to make sure you are a human visitor and to prevent spam submissions.');

Comments

soxofaan’s picture

In my original rewrite I tried to address this, but apparently I got it a bit wrong. CAPTCHA_DESCRIPTION occurs at two places (the define() not including).

The first one (line 190 of revision 1.42.2.11 of captcha.module) should be
'#default_value' => variable_get('captcha_description', CAPTCHA_DESCRIPTION),
instead of
'#default_value' => t(variable_get('captcha_description', CAPTCHA_DESCRIPTION)),
(no translation on the settings page)

the second one (line 283 of revision 1.42.2.11 of captcha.module) should be
$captcha_description = t(variable_get('captcha_description', CAPTCHA_DESCRIPTION));
instead of
$captcha_description = variable_get('captcha_description', CAPTCHA_DESCRIPTION);
(translatable on challenge)

Maybe some more description should be added to line 189 to note that the string can/will be translated

soxofaan’s picture

Status: Active » Needs review
StatusFileSize
new1.52 KB

patch to do the thing from #1

robloach’s picture

StatusFileSize
new1.83 KB

That won't do it because you have to pass the string directly to t() as the default for variable_get().... See the attached patch.

robloach’s picture

Status: Needs review » Fixed
soxofaan’s picture

That won't do it because you have to pass the string directly to t() as the default for variable_get()

Why?

If I get your patch (#3) correctly, your solution won't work either: if the variable captcha_description is set (through the settings page), it will be used as description, while the default value t('This question ....') (which does the localization) won't be used. The variable captcha_description could of course written in the desired language, but if you have a multi-lingual site, you're stuck because the description can only be in one language.

With my patch (#2) however, the description in the settings page is/should be English (no translation), while on the captcha challenge the right translation for the user is picked. Translation is done with the standard drupal localization.

In short: your patch only translates the default value,
while my patch translates the description itself, independent if the default value is overwritten or not.

robloach’s picture

Read the documentation on t() and you'll see why I translate the static string instead of the dynamically changing captcha_description variable in the database. The difference between what you proposed and what I proposed is this:

t(variable_get('captcha_description', 'Default captcha description.'));
// VS
variable_get('captcha_description', t('Default captcha description.'));

You want to translate the default value so that if they have a site in Spanish, they'll see the Spanish translation by default. If they want to change the description, they can. It's assumed that they'd write this new description already in their desired language. Also, you can't use t() to translate something that's dynamic and can change (like variable_get).

If you had read the documentation on t(), you'd understand that it only takes a static string. If you have anything dynamic, you'd pass it into the second argument. If we use your method, using t() properly would turn the call into something like this:

t('!description', array('!description' => variable_get('captcha_description', 'Default captcha description.')));

.... And that's really not right ;-) .

soxofaan’s picture

Status: Fixed » Needs work

Read the documentation on t() and you'll see why I translate the static string instead of the dynamically changing captcha_description variable in the database.

If you had read the documentation on t(), you'd understand that it only takes a static string. If you have anything dynamic, you'd pass it into the second argument.

I read documentation, I even bought the pro drupal development book. So don't worry about that.
The documentation on t($string, ...) does not explicitly state that $string should be static (whatever that could mean). But I understand that it could feel wrong to use a "dynamic-ish" string. The string indeed comes from the database, but it is not that dynamic that it could change every day. My idea is just: on the settings page the admin sets the captcha_description string (in English, like all default strings in drupal), and this string can be translated to all desired languages through the locale module.
The documentation does indeed say something about parts in the string that could change and to use placeholders for that, but in this case it's about the whole string, so placeholders are not a part of the equation..
I understand however that my patch is a bit controversial and wouldn't be accepted in its current state.

On the other hand, the patch that you propose in #3 (and already committed) won't work either for multilingual sites, as I already tried to explain in #5. I, for example, live in Belgium, which has three official languages: Dutch, French and German, so the multilingual capabilities of a CMS are important over here. In your patch the t() is only around the default captcha_description:

 function _captcha_get_description() {
  return variable_get('captcha_description', t('This question is used to make sure you are a human visitor and to prevent spam submissions.'));
}

If an admin defines a different string, there is no t() to catch that, so it can't be translated. Well, it can be translated by the admin in only one language (e.g. Dutch) in the text field directly, but translation to other languages (French and German) is not possible.
You need an "outer" t() around the variable_get() for this (like in my patch).

Conclusion: I think this issue isn't fixed, yet.

soxofaan’s picture

Conclusion: I think this issue isn't fixed, yet.

One simple option is to remove the configurability of the captcha_description and just use a hardcoded but translatable string.
So, no more
variable_get('captcha_description', t('This question is used to make sure you are a human visitor and to prevent spam submissions.'))
but just
t('This question is used to make sure you are a human visitor and to prevent spam submissions.')
and delete all form stuff, database interaction and conditionals for the captcha_description.

For a bit more admin control we could add a toggle 'show captcha description or not' to the settings page.

soxofaan’s picture

@Rob:
I experimented a bit with captcha.module revision 1.42.2.13 (which is with patch from #3).
It appears that this version behaves like I propose after all and not like you intended ;)

// line 103:
function _captcha_get_description() {
  return variable_get('captcha_description', t('This question is used to make sure you are a human visitor and to prevent spam submissions.'));
}
// line 290:
    $captcha_description = _captcha_get_description();
// line 296:
      '#description' => t($captcha_description),

As you see on line 296, the what you call 'dynamic' captcha description $captcha_description still gets passed to the translation function t().
So revision 1.42.2.13 is how I propose to do translation of the captcha description, except that there is one extra (and unneeded) call to t() in line 104. And it works in a multilingual setting (different users with different languages).

robloach’s picture

Status: Needs work » Fixed

Just changing the status of this.

soxofaan’s picture

Just changing the status of this.

Well, that's weird,
because this issue is fixed in the way you heavily argued against:
Line 296 (of captcha.module version 1.42.2.15) still translates a user defined string with t():

        '#description' => t($captcha_description),

(also see #9)

robloach’s picture

Good eyes ;-) .

heine’s picture

Status: Fixed » Active

As far as I can tell, this issue is not fixed.

robloach’s picture

I removed the extra call to t() that you mentioned in #9 and #12. Everything else is fixed because sending in custom user defined strings to t() is evil. That was the major issue here, and it's resolved. I've tested this myself and it works...

heine’s picture

I believe I tried to explain in IRC, but apparantly I failed.

The issue is not that sending user defined strings to t() is evil, it is that the user defined string cannot be translated when another locale is in use. This is troublesome for multilingual sites (Dutch/French, Dutch/Frisian for example) which may even be required by law in certain regions.

soxofaan’s picture

The issue is not that sending user defined strings to t() is evil, it is that the user defined string cannot be translated when another locale is in use. This is troublesome for multilingual sites (Dutch/French, Dutch/Frisian for example) which may even be required by law in certain regions.

I agree completely and I also tried to explain this (see #5 and #7).

A possible (simple) solution (see #8) is to make the captcha description not configurable so it can be fed to t() without problems. However this feels giving up to much flexibility.

This issue is indeed not fixed

robloach’s picture

So please submit a patch to fix it and make Heine review it. Although I do know that this works with a one language site (English, Dutch, etc), I don't know how it performs in a multi-lingual environment (when you could have mysite.com, mysite.eu, mysite.cn, etc). This was a simple little issue that I thought I resolved and I'm honestly quite tired of seeing it on my issue queue.

soxofaan’s picture

Priority: Minor » Normal
Status: Active » Needs review
StatusFileSize
new3.5 KB

This patch makes the captcha module do the following:

When the locale module is not enabled, nothing changes: just one captcha description available/configurable.

When the locale module is enabled (multilingual sites): a captcha description can be set for each enabled language. On challenge generation the description corresponding with the user's locale will be used (default locale for unauthenticated users, chosen locale for authenticated users)

soxofaan’s picture

StatusFileSize
new4.49 KB

minor update of my patch of #19:
added a bit of documentation and tweaked some UI strings

robloach’s picture

Ahh, that's how you do it. Thanks! Note that I haven't reviewed this, just quickly took a look.

robloach’s picture

Priority: Normal » Critical
Status: Needs review » Reviewed & tested by the community

Reviewed and tested..... Nicely going. I never looked at the locale module.

soxofaan’s picture

Status: Reviewed & tested by the community » Fixed

fixed by commit http://drupal.org/cvs?commit=78720 apparently

Anonymous’s picture

Status: Fixed » Closed (fixed)