That's my request, here's the use case:

Anonymous users can post comments on my site, but they have to pass Captcha each time. The configurable description I've entered says something like: "Never see this form again: sign up for a free account"

The account signup form is also protected by Captcha. Wouldn't it be nice if it could display a different message, something like: "Thanks for taking the time to register. This is the last time you'll ever have to answer this question!" As it is, it's pretty silly that it presents a link to the page you're already on.

I've looked into the string overrides modules. Sadly, they have no plans to implement contextual overrides, as it would cause big performance problems. So I'm requesting this feature of the module's developers instead... in terms of the module's UI, the contextual description field could simply be placed in the same row as the form_id and captcha type options, so that the columns would be:
form_id Challenge type Operations Description
Leaving the description field blank would default to the configurable description below (or the default text if nothing is entered there either).

CommentFileSizeAuthor
#9 remove.jpg26.14 KBzhongguo999999

Comments

soxofaan’s picture

Status: Active » Closed (won't fix)

It seems a bit overkill to implement this in the CAPTCHA module itself. Unless a lot of people support this request, I'm flagging this thread as "won't fix".
Note that the description field handling is already complicated in a multilingual setup, where there is a description field for every language. If we add an extra dimension of description per context/form_id, things would get messy and there would not be enough room in the table.

I see two possible solutions for you:

  1. On module level: implement it in a separate module. Implement a hook_form_alter(), look for CAPTCHA elements ($element['#type'] = 'captcha'), and change the '#description' field of the CAPTCHA element to what you want.
  2. On theme level: override the theming of the CAPTCHA element, which is currently done as follows:
     /**
     * Theme function for a CAPTCHA element.
     *
     * Render it in a fieldset if a description of the CAPTCHA
     * is available. Render it as is otherwise.
     */
    function theme_captcha($element) {
      if (!empty($element['#description']) && isset($element['captcha_widgets'])) {
        $fieldset = array(
          '#type' => 'fieldset',
          '#title' => t('CAPTCHA'),
          '#description' => $element['#description'],
          '#children' => $element['#children'],
          '#attributes' => array('class' => 'captcha'),
        );
        return theme('fieldset', $fieldset);
      }
      else {
        return '<div class="captcha">'. $element['#children'] .'</div>';
      }
    }
    

    Here you can change the description too to whatever you like.

Both solutions require a certain level of coding skills and drupal development background, I don't know if this is feasible for you?

colemanw’s picture

Thanks for your help. I'm fairly new to Drupal (and PHP in general), but am trying to learn it as quickly as I can. Stuff like this is a great learning opportunity for me. If I can just ask a couple clarifying questions:

The module-level approach: are you suggesting I write a custom module to look for this form on a specific page and alter the element? I don't have the skill to do that, but if you could point me in the direction of a similar module, I could probably steal the code. I'd like to at least give it a shot.

The theme-level approach: would this require creating a sub-theme and using theme-switcher, etc to enable that theme on the pages I want to alter? That seems like overkill too, but maybe I'm missing something? Would it be possible to use an IF statement to customize the above code depending on the URL? If that were possible it might be the easiest solution. Maybe it would look something like this (pardon my newbie code):

function theme_captcha($element) {
  if (!empty($element['#description']) && isset($element['captcha_widgets'])) {
if (the url says /user/register-what's the code for that?) { 
$fieldset = array(
      '#type' => 'fieldset',
      '#title' => t('CAPTCHA'),
      '#description' => $element['can I just type in my own description like this?'],
      '#children' => $element['#children'],
      '#attributes' => array('class' => 'captcha'),
    );
    return theme('fieldset', $fieldset);
  }
else {
$fieldset = array(
      '#type' => 'fieldset',
      '#title' => t('CAPTCHA'),
      '#description' => $element['#description'],
      '#children' => $element['#children'],
      '#attributes' => array('class' => 'captcha'),
    );
    return theme('fieldset', $fieldset);
  }}
  else {
    return '<div class="captcha">'. $element['#children'] .'</div>';
  }
}

Again, I appreciate you taking the time to help someone along with learning Drupal.

soxofaan’s picture

This is not the place to give you an introduction in Drupal development, but I can give you some clues.

The module you need is actually very simple. The trick is that you can add CAPTCHA's without the admin UI offered by the CAPTCHA module with just a bit of code (you still need the CAPTCHA module as a dependency for the CAPTCHA processing).

This is all you need to add a CAPTCHA (with custom description) to the user registration form: (disclaimer I didn't try this code, so there could be some quirks here or there)

/**
 * Implementation of hook_form_alter().
 */
function your_module_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register') {
    $form['captcha'] = array(
      '#type' = 'captcha',
      '#description' = t("Thanks for taking the time to register. This is the last time you'll ever have to answer this question!"),
    );
  } 
}

Make sure you don't set a CAPTCHA with the admin UI of the CAPTCHA module, as this could overwrite this custom CAPTCHA or add another CAPTCHA.

Please report how it turns out.

colemanw’s picture

Thank you so much for your help. After fixing a minor syntax error (lines 8 & 9, = instead of =>), your code worked beautifully. I disabled Captcha on the user register page, installed this new module, and viola! There it is, but with the custom text enabled. In case anyone else wants to use this easy trick, here is the corrected code:

<?php
/**
* Implementation of hook_form_alter().
*/
function your_module_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register') {
    $form['captcha'] = array(
      '#type' => 'captcha',
      '#description' => t("Thanks for taking the time to register. This is the last time you'll ever have to answer this question!"),
    );
  }
}
?>

PS. Is there any way to control the weight of the form we just inserted? It used to be at the bottom, this custom module is sticking it at the top.

Thanks again Stefaan.

colemanw’s picture

Nevermind, I just answered my own question. You control the weight by adding a weight variable and giving it a value, duh. Here's the whole thing:

<?php
// $Id: customreg.module
/**
* Implementation of hook_form_alter().
*/
function customreg_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_register') {
    $form['captcha'] = array(
      '#type' => 'captcha',
      '#description' => t("This checks that you are a real person and not a spam program.<br><em>Thanks for taking the time to register. This is the last time you'll ever have to answer this question!</em>"),
      '#weight' => '10'
    );
  }
}
?>

PS: If anyone decides to use this code, remember to leave the closing ?> tag out of your module.

zhongguo999999’s picture

@colemanw : In your method:

1. How to change the Math type of CAPTHA to Image type of CAPTHA ?

2. How to remove the 'title' or '#description' field of the math(or image) CAPTCHA that say "Math question:Solve this simple math problem and enter the result. E.g. for 1+3, enter " . Note: not the top description that say "This checks that you are a real person and not a spam program.
Thanks for taking the time to register. This is the last time you'll ever have to answer this question!"

3. Why don't see the structures by devel.module's dprint_r() function?

Thank you very much!

soxofaan’s picture

1: see #743056: Document how to add a CAPTCHA programmatically
2 and 3: I don't understand your question

zhongguo999999’s picture

1. I mean removing the description of Image CAPTCHA, take a look at screenshot.
The screenshot is here: http://drupal.org/files/issues/remove_1.jpg

2. What does the my_captcha_element mean In the following code ? Replace the captcha/Math with what if using Image CAPTCHA?

$form['my_captcha_element'] = array(
  '#type' => 'captcha',
  '#captcha_type' => 'captcha/Math',
);

Thanks a lot!

zhongguo999999’s picture

StatusFileSize
new26.14 KB

The screenshot

colemanw’s picture

I recommend studying Drupal's FAPI documentation. It's really good. http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....
I recommend using this life-saver function anytime you're in doubt:

dsm( $form );

In the code in #5 no captcha type is specified, so it uses the default. If image is your default, that's what you'll get. You can make it your default in admin/user/captcha

soxofaan’s picture

@zhongguo999999:

To use the image captcha, use "#captcha_type": "image_captcha/Image" (the format is "$module/$type" with $module="image_captcha" and $type="Image")

Removing the description and title is not possible through (image) CAPTCHA settings, but possible solutions/workaround:
* CSS (which you don't want)
* something like http://drupal.org/project/stringoverrides
* custom form_altering as pointed out by colemanw in #10

zhongguo999999’s picture

@soxofaan
Thanks for your answer.

function mymenu_form_alter(&$form, $form_state, $form_id) {
$form['captcha'] = array(
#type' => 'captcha',
'#captcha_type' => 'image_captcha/Image',
}
The snippet works for me

* custom form_altering as pointed out by colemanw in #10
But the dpm(),dprint_r(),dsm() couldn't display the structure of the description(or title) on the following line(in screenshot), only display the structure of the description on the first line(in screenshot). So I couldn't alter the them.
* something like http://drupal.org/project/stringoverrides
I don't want use too many module, I want to wrint my custom module.
* CSS
I don't want to use.

How to remove it using alter? help me!

colemanw’s picture

It may not be possible using hook_form_alter if the captcha module gets to execute its code after you get to execute yours. String overrides may be the way to go. You don't have to use the string overrides module, you can just put the overrides in your settings.php file.

/**
 * String overrides:
 *
 * To override specific strings on your site with or without enabling locale
 * module, add an entry to this list. This functionality allows you to change
 * a small number of your site's default English language interface strings.
 *
 * Remove the leading hash signs to enable.
 */
# $conf['locale_custom_strings_en'] = array(
#   'forum'      => 'Discussion board',
#   '@count min' => '@count minutes',
# );

Another (bad) solution would be to grep for the text you're looking for and remove it from the module's code. While I don't recommend hacking contrib modules, the grep might be useful in tracking down where that string is coming from.

zhongguo999999’s picture

@colemanw, soxofaan: Thanks for your answer.

1. According to your method, It don't works, something must be wrong. help!

 $conf['form']['captcha_response'] = array( 
   '#title' => t('1111What code is in the image?'),
 );

2. I can alter the first line description on the screenshot, but couldn't alter the following line description on the screenshot. Something is wrong. Can someone give me help?

function mymenu_form_alter(&$form, $form_state, $form_id) {
      $form['captcha'] = array(
            #type' => 'captcha',
            '#captcha_type' => 'image_captcha/Image',
           '#children' => $element['#children'], //It display the following line description on the screenshot.
           '#description' => t('This question is for testing whether you are a human visitor and to prevent automated spam submissions.6666, I alter it'), //It works. I can alter the first line description in the screenshot.
           $form['captcha']['captcha_response']['#description'] =t('Enter the characters shown in the image.I couldn't alter it'), //It don't works. I couldn't alter the fllowing line description in the screenshot
        )
}

BTW: I don't want to hacking contrib modules, so I don't modify the code below. I just wanna override by using my custom module.

function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
...
$result['form']['captcha_response'] = array(
          '#type' => 'textfield',
          '#title' => t('What code is in the image?'), //you can modify it if you want hacking.
          '#description' => t('Enter the characters shown in the image.'),//you can modify it if you want hacking.
          '#weight' => 0,
          '#required' => TRUE,
          '#size' => 15,
...
}
colemanw’s picture

This is starting to push the limits (and patience) of friendly community support. I recommend taking a PHP class at a local community college, or joining a local Drupal users group.

zhongguo999999’s picture

OK,Thank you, but I think Drupal community is a good community college.

ThouArtJay’s picture

In your custom module, implement hook_captcha which calls image_captcha_captcha:

/**
 * Implementation of hook_captcha().
 */
function custommodule_captcha($op, $captcha_type='', $captcha_sid=NULL) {
	$result = image_captcha_captcha($op, $captcha_type, $captcha_sid);
	
	if($op == 'generate') {
		$result['form']['captcha_response']['#title'] = t('Code');
	}
	
	return $result;
}

After adding the hook, go to captcha admin settings and change the challenge type to that from your custom module.

It's not the best solution, but it worked for me.

phponwebsites’s picture

How to diable captcha field using hook_form_alter(). I've tried both access and disable but no one is worked for me. I can only hide captcha field from the form. When i submit the form, it displays error message "The answer you entered for the CAPTCHA was not correct.".
This is my code at hook_form_alter():

        $form['captcha']['#access'] = FALSE;
        $form['captcha']['#disabled'] = TRUE;