Need help with node/add panel override and CAPTCHA

Events happening in the community are now at Drupal community events on www.drupal.org.
laken's picture

While I've been using Panels 2 extensively, I've only just started with overriding the node/add form and have run into a bit of trouble.

The use case is simple: we have a Volunteer node type and want anon users to be able to submit this form and create unpublished nodes for later admin review. We use panels for layout and sidebars for all the user-facing pages on the site, so we wanted this form to be in a panel as well.

I set up a panel with path node/add/%, under context added "Node add form" argument, configured it for the Volunteer content type, and under content added the "general form". Worked like a charm: node add form wrapped in a panel, and without any of the extraneous form bits (log message, input format, etc) that I don't want on this form.

Then I installed and configured Mollom to keep a lid on spam submissions. For those who might not be familiar with Mollom, it sends the submissions to a web service which responds with a message saying "Spam", "Ham (not spam), or "Unsure". If "unsure" then Mollom sets a drupal warning message and redisplays the form with a CAPTCHA.

Problem is, when mollom is unsure, and redisplays the form, the CAPTCHA isn't appearing when the form is displayed through the panel. Just to check, I disabled the node/add panel override and just ran the straight form: sure enough, the CAPTCHA appeared.

It seems like Panels explodes the form into several chunks, making each available in the Add Content pop-up under "Form". My guess is that adding the "general form" pane like I did is not sufficient to display add-ons to the form like the CAPTCHA. But there is no panel pane in the "Form" list that looks like it would handle additions other modules made to the form (see attached screenshot). (I looked for an equivalent of Panels' node override "No Extras" checkbox to disable, but found nothing.)

Can anyone help here?

AttachmentSize
panels-2-node-add-override-form-panes.png119.39 KB

Comments

You might be able to do

dwees's picture

You might be able to do something silly and handle this at the theming layer. Basically theme the form, and ensure it includes the Captcha form as necessary. Not sure if this will work, but it's worth a try.

#pre_render

laken's picture

Looks like Mollom adds the CAPTCHA to the form as a #prerender. Would that affect Panels' ability to grab the CAPTCHA?

<?php
function mollom_form_alter($form_id, &$form) {
 
// Catch all handlers -- this makes it easy to protect all forms
  // with Mollom.  Site administrators don't have their content
  // checked with Mollom.
 
if (!user_access('post with no checking')) {
   
$form['#pre_render'][] = 'mollom_captcha_prerender';
   
$form['#validate']['mollom_validate'] = array();
  }
  .
  .
  .
function
mollom_captcha_prerender($form_id, &$form)  {
  .
  .
  .
     
// We add an image captcha to the form. We can't do this from the
      // validate hook, hence the need for the #pre_render trick. In
      // Drupal 6, we can simply use $form_state['rebuild'] = TRUE in
      // the validate-hook, and rebuild the form from there but in
      // Drupal 5, we have to use this prerender-hook hack.
      // Because we're already past the prepare state of the form API,
      // we have a little bit more work to do ...:
     
$form['captcha-solution'] = array(
         
'#type' => 'textfield',
         
'#name' => 'captcha-solution',
         
'#id' => 'edit-captcha-solution',
         
'#parents' => array(),
         
'#title' => t('Word verification'),
         
'#field_prefix' => '<div id="captcha"><a href="http://mollom.com"><img src="'. url($response['url']) .'" alt="Mollom CAPTCHA" /></a> (<a href="#" id="audio-captcha">'. t('play audio CAPTCHA') .'</a>)</div>',
         
'#required' => TRUE,
         
'#size' => 10,
         
'#value' => $form['#post']['captcha'],
         
'#description' => t("Type the characters shown in the picture above; if you can't read them, submit the form and a new image will be generated."),
         
'#weight' => min($form['submit']['#weight'], $form['preview']['#weight']) + 1);

     
// Move the preview and/or submit button below the captcha:
     
$form['preview']['#weight'] += 2;
     
$form['submit']['#weight'] += 2;

     
// The weights changed so we re-sort the array:
     
uasort($form, "_element_sort");
?>

Have you checked to see if

dwees's picture

Have you checked to see if the Mollom code is being run or not when it wants to present the new captcha? Like for instance, is the #validate being added, and the form not being added? Does changing

<?php
$form
['#pre_render'][] = 'mollom_captcha_prerender';
?>

to

<?php
mollom_captcha_prerender
($form_id, $form);
?>

do anything?

Hey dwees, thanks for the

laken's picture

Hey dwees, thanks for the help!

But I'm not sure what you mean by

Like for instance, is the #validate being added, and the form not being added?

Where would I put in debug code to check for this stuff? Where would you suggest I try the code change you suggested?

To check to see if a part of

dwees's picture

To check to see if a part of a function is even being called, I usually throw something like print 'boo'; into a section.

For example the beginning of the code you pasted above:

<?php
function mollom_form_alter($form_id, &$form) {
 
// Catch all handlers -- this makes it easy to protect all forms
  // with Mollom.  Site administrators don't have their content
  // checked with Mollom.
 
if (!user_access('post with no checking')) {
   
$form['#pre_render'][] = 'mollom_captcha_prerender';
   
$form['#validate']['mollom_validate'] = array();
  }
?>

I would try the following instead:

<?php
function mollom_form_alter($form_id, &$form) {
 
// Catch all handlers -- this makes it easy to protect all forms
  // with Mollom.  Site administrators don't have their content
  // checked with Mollom.
 
if (!user_access('post with no checking')) {
   
mollom_captcha_prerender($form_id, $form);
   
$form['#validate']['mollom_validate'] = array();
  }
?>

If this doesn't work, try checking to see if that function is even being called:

<?php
function mollom_form_alter($form_id, &$form) {
 
// Catch all handlers -- this makes it easy to protect all forms
  // with Mollom.  Site administrators don't have their content
  // checked with Mollom.
 
if (!user_access('post with no checking')) {
   
$form['#pre_render'][] = 'mollom_captcha_prerender';
   
$form['#validate']['mollom_validate'] = array();
    print
'testing 1 2 3 ';
  }
?>

If no testing 1 2 3 appears in the text of the displayed page when the Mollom capture SHOULD be present (like when a form contains obvious spam) then the problem doesn't exist with this form, it exists somewhere else since the logic on this form is pretty simple.

Dave

Panels

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week