I would like the ability to disable mollom for comments on certain content types. Reading the code it seems that I could try to set $form_state['mollom']['#require_analysis'] to FALSE but that feels like a hack.

Comments

greggles’s picture

Title: disable mollom for comments on certain content types » allow modules to disable mollom for certain situations
Category: support » feature

So, I was able to get this to work by adding a #process handler to the form to set the $form_state['mollom'] value.

I think it would be better to add a hook in mollom_expand_element that allows other modules to provide feedback on whether or not mollom should be used / and how.

greggles’s picture

For anyone else who is in the same position, below is my solution. It prevents mollom from running either CAPTCHA or text analysis on comments on nodes of "api" type.


/**
 * A form element processor intended solely to disable mollom in certain situations.
 */
function early_mollom_maybe($element, $edit, &$form_state) {
  $form_state['mollom'] = array(
    '#session_id' => NULL,
    '#form_id' => $form_state['values']['form_id'],
    '#require_analysis' => MOLLOM_MODE_DISABLED,
    '#require_captcha' => MOLLOM_MODE_DISABLED,
    '#passed_captcha' => FALSE,
    '#user_session_id' => session_id(),
  );

  return $element;
}

/**
 * Implementation of hook_form_alter().
 *
 */
function early_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'comment_form') {
    $type = db_result(db_query("SELECT type FROM {node} WHERE nid = %d", $form['nid']['#value']));
    // ADD YOUR OWN CUSTOM IF STATEMENT HERE.
    if ($type == 'api') {
      $form['early_mollom_disabler'] = array(
       '#type' => 'value',
        '#process' => array(
          'early_mollom_maybe',
        ),
      );
    }
  }
}

dries’s picture

@greggles: I haven't tested your code but that is indeed the proper way to do this (thanks to the fact that the Mollom module implements a new form element). I'll keep this snippet in the issue for a while, but then I might migrate it to a documentation page.

sun’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Active » Postponed

For this to happen, we need to implement hook_forms() for comment.module in Drupal core, so that we have a unique $form_id to configure Mollom for.

That would make totally sense. Unfortunately, it's late. Probably too late for D7... :-/

sun’s picture

Title: allow modules to disable mollom for certain situations » Allow modules to disable mollom for certain situations
Status: Postponed » Active

Also taking into account #706180: Fire a hook before Mollom adds its stuff in hook_form_alter(), I think the proper way to do this would be to implement something along the lines of

  'dry run' => TRUE,

for Mollom's form processing, and, a hook that allows modules to return whether this mode should be enabled.

If enabled, Mollom would operate as always under the hood, i.e. still communicating with the servers for textual analysis, but wouldn't ever trigger a form validation error.

dave reid’s picture

Status: Active » Needs review
StatusFileSize
new1.1 KB

If we just make this small change, all a module would need to do is this:

function mymodule_mollom_form_info_alter(&$form_info, $form_id) {
  // Perform appropriate check here:
  if (!user_access('administer mollom') && user_access('my special permission')) {
    // Disable Mollom protection for all forms.
    $form_info['mode'] = MOLLOM_MODE_DISABLED;
  }
}

The only thing I can think of is if we start to store results of mollom_form_info() in cache, then this won't work.

The only other thing is you'd need to explicitly check that the user doesn't have the 'administer mollom' permission so this doesn't screw up editing form protections.

dries’s picture

This looks good. Can we add your example snippet to mollom.api.php?

pwolanin’s picture

I've run into a similar problem - but I was thinking it should be something a the form building function can control.

For example, I might build the form differently for anonymous users (need you e-mail + captcha) versus registered users (never need a captcha) - or even more specific. I guess the patch above allows the same logic - but it has to live within this alter hook instead of inside the form building function itself.

Something like this (for Drupal 6):

Index: mollom.module
===================================================================
--- mollom.module	(revision 16318)
+++ mollom.module	(working copy)
@@ -533,7 +533,10 @@ function mollom_form_alter(&$form, &$form_state, $
   if ($status !== TRUE) {
     return;
   }
-
+  // Allow form builders to independently bypass mollom.
+  if (isset($form['bypass mollom protection']) && !empty($form['bypass mollom protection']['#value'])) {
+    return;
+  }
   // Site administrators don't have their content checked with Mollom.
   if (!user_access('bypass mollom protection')) {
     // Retrieve a list of all protected forms once.
pwolanin’s picture

daviereid helpfully explained what's going on in addition to the context of the patch. Seems reasonable.

The patch applies cleanly with offset to the 6.x-1.13 version too.

pwolanin’s picture

Status: Needs review » Needs work

Looking in more detail at the code - the 'mode' will always be overwritten with the value from the DB.

sun’s picture

+++ mollom.module	6 May 2010 17:32:33 -0000
@@ -528,6 +528,10 @@ function mollom_form_alter(&$form, &$for
     if (isset($protected_forms[$form_id]) && $mollom_form = mollom_form_load($form_id)) {

@@ -685,7 +689,7 @@ function mollom_form_info($form_id, $mod
-    'mode' => NULL,
+    'mode' => MOLLOM_MODE_DISABLED,

$mollom_form, resp., mollom_form_load() and mollom_form_info() are completely separate and detached operations. Hence, this 'mode' has no effect.

Powered by Dreditor.

dave reid’s picture

Yeah it doesn't work. It would make sense to support a form property of #mollom_mode or something that can be set manually.

sun’s picture

Title: Allow modules to disable mollom for certain situations » Allow modules to conditionally disable mollom
Status: Needs work » Needs review
StatusFileSize
new1.92 KB

Test-driven development.

sun’s picture

StatusFileSize
new2.07 KB

Ignore :P

sun’s picture

That must have contained a typo somewhere? Or I'd like to know why.

Status: Needs review » Needs work

The last submitted patch, mollom-HEAD.form-alter.15.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
StatusFileSize
new2.75 KB

The original post precisely describes the current possibilities within Form API.

For now, there's little point in converting two $form_state properties into one other global property on $form or $form_state. What effectively counts is the module weight.

dries’s picture

Status: Needs review » Reviewed & tested by the community

sun's example is clean and elegant. It is more of an example but it doesn't hurt to have an example test as we can point other people to it. Marking this RTBC. Comments from anyone else?

dave reid’s picture

Way cleaner. +1 from me.

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD.

sun’s picture

Version: 7.x-1.x-dev » 6.x-1.x-dev
Status: Fixed » Needs review
StatusFileSize
new2.67 KB
sun’s picture

Status: Needs review » Reviewed & tested by the community
dries’s picture

Status: Reviewed & tested by the community » Fixed

Looks good. Same as HEAD. Committed to CVS HEAD. Thanks sun and Dave.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

leksat’s picture

Here is how I disable mollom for comment form of particular content types:

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function mymodule_form_comment_form_alter(&$form, $form_state) {
  $types = array(
    'my_content_type_1',
    'my_content_type_2',
    //...
  );
  $type = db_result(db_query("SELECT type FROM {node} WHERE nid = %d", $form['nid']['#value']));
  if (in_array($type, $types)) {

    // Bypass mollom protection for comment form.
    $form['#after_build'][] = '_mymodule_bypass_mollom';
  }
}

/**
 * Add this function to "#afret_build" list of a form to bypass mollom protection.
 */
function _mymodule_bypass_mollom($form, $form_state) {
  unset($form['mollom']);
  foreach (array('#validate', '#submit') as $op) {
    foreach ($form[$op] as $key => $callback) {
      if (strstr($callback, 'mollom')) {
        unset($form[$op][$key]);
      }
    }
  }
  return $form;
}

True for D6.

jjesus’s picture

+1 Thanks for this one.

  • Commit 4a91444 on master, fai6, 8.x-2.x, fbajs, actions by Dries:
    - Patch #376009 by sun, Dave Reid: allow modules to conditionally...

  • Commit 4a91444 on master, fai6, 8.x-2.x, fbajs, actions by Dries:
    - Patch #376009 by sun, Dave Reid: allow modules to conditionally...