Index: mollom.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.admin.inc,v retrieving revision 1.1.2.33 diff -u -p -r1.1.2.33 mollom.admin.inc --- mollom.admin.inc 11 Aug 2010 00:47:10 -0000 1.1.2.33 +++ mollom.admin.inc 30 Aug 2010 18:11:55 -0000 @@ -138,6 +138,24 @@ function mollom_admin_configure_form(&$f ), '#default_value' => $mollom_form['mode'], ); + // The negated form widget and value handling looks a bit weird, but users + // can rather relate to more common "unpublish" and "moderation" terms, + // and by default, Mollom should operate correctly and therefore also + // reject spam posts, so this setting should stay optional and disabled by + // default. The internally stored value for 'reject' is technically smart, + // since a value of 1 means to reject spam posts, and 0 means to unpublish + // posts; the value therefore represents "rejection" and a "publishing + // status" at the same time. + // @todo Is this checkbox limited to spam? (what about profanity?) + $form['mollom']['reject'] = array( + '#type' => 'checkbox', + '#title' => t('Unpublish spam posts instead of rejecting'), + '#default_value' => !$mollom_form['reject'], + ); + if (!isset($mollom_form['mapping']['post_status'])) { + $form['mollom']['reject']['#disabled'] = TRUE; + $form['mollom']['reject']['#description'] = t('This form does not support moderation of unpublished posts.'); + } if (!empty($mollom_form['elements'])) { // Add the text analysis protection mode as first, suggested option. @@ -236,10 +254,9 @@ function mollom_admin_configure_form_sub $mollom_form = $form_state['values']['mollom']; // Merge in form information from $form_state. $mollom_form += $form_state['storage']['mollom_form']; - // Update form information in $form_state for potential rebuilds. - $form_state['storage']['mollom_form'] = $mollom_form; // Prepare selected fields for storage. + $mollom_form['reject'] = !$mollom_form['reject']; $enabled_fields = array(); foreach (array_keys(array_filter($mollom_form['enabled_fields'])) as $field) { $enabled_fields[] = rawurldecode($field); Index: mollom.api.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.api.php,v retrieving revision 1.1.2.6 diff -u -p -r1.1.2.6 mollom.api.php --- mollom.api.php 18 Aug 2010 00:43:27 -0000 1.1.2.6 +++ mollom.api.php 31 Aug 2010 10:54:02 -0000 @@ -153,6 +153,8 @@ * 'entity' => 'im', * // Optional: User permission list to skip Mollom's protection for. * 'bypass access' => array('administer instant messages'), + * // @todo + * 'reject callback' => 'im_mollom_reject', * // Optional: To allow textual analysis of the form values, the form * // elements needs to be registered individually. The keys are the * // field keys in $form_state['values']. Sub-keys are noted using "][" @@ -275,6 +277,10 @@ function hook_mollom_form_list() { * current user to determine whether to protect the form with Mollom or do * not validate submitted form values. If the current user has at least one * of the listed permissions, the form will not be protected. + * - reject callback: (optional) A function name to invoke when a form + * submission would normally be rejected. This allows modules to put such + * posts into a moderation queue (i.e., accept but not publish them) by + * altering the $form or $form_state information being passed by reference. * - mail ids: (optional) An array of mail IDs that will be sent as a result * of this form being submitted. When these mails are sent, a 'report to * Mollom' link will be included at the bottom of the mail body. Be sure to Index: mollom.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.install,v retrieving revision 1.2.2.31 diff -u -p -r1.2.2.31 mollom.install --- mollom.install 6 Apr 2010 22:17:51 -0000 1.2.2.31 +++ mollom.install 30 Aug 2010 18:11:55 -0000 @@ -118,6 +118,13 @@ function mollom_schema() { 'not null' => TRUE, 'default' => 0, ), + 'reject' => array( + 'description' => 'Whether to reject (1) or unpublish (0) spam submissions.', + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 1, + ), 'enabled_fields' => array( 'description' => 'A list of form elements configured for textual analysis.', 'type' => 'text', @@ -382,3 +389,19 @@ function mollom_update_6112() { } return $ret; } + +/** + * Add {mollom_form}.reject column to form configuration. + */ +function mollom_update_6113() { + $ret = array(); + if (!db_column_exists('mollom_form', 'reject')) { + db_add_field($ret, 'mollom_form', 'reject', array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 1, + )); + } + return $ret; +} Index: mollom.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.module,v retrieving revision 1.2.2.156 diff -u -p -r1.2.2.156 mollom.module --- mollom.module 7 Aug 2010 02:49:44 -0000 1.2.2.156 +++ mollom.module 31 Aug 2010 10:53:22 -0000 @@ -400,7 +400,6 @@ function mollom_data_load($entity, $id) * - session: The session ID returned by the Mollom server. * - quality: A quality rating assigned to the content to tell whether or not * it's spam. - * - reputation: The reputation of the author. * - languages: An array containing language codes the content might be * written in. * @@ -418,7 +417,7 @@ function mollom_data_load($entity, $id) */ function mollom_data_save($entity, $id) { // Nothing to do, if we do not have a valid Mollom response. - if (!isset($GLOBALS['mollom_response']['session_id'])) { + if (empty($GLOBALS['mollom_response']['session_id'])) { return FALSE; } $data = $GLOBALS['mollom_response']; @@ -632,6 +631,7 @@ function mollom_form_alter(&$form, &$for // Add Mollom form validation handlers. $form['#validate'][] = 'mollom_validate_analysis'; $form['#validate'][] = 'mollom_validate_captcha'; + $form['#validate'][] = 'mollom_validate_status'; // Add a submit handler to remove form state storage. $form['#submit'][] = 'mollom_form_submit'; @@ -779,6 +779,7 @@ function mollom_form_info($form_id, $mod 'entity' => NULL, 'title' => $form_id, 'mode' => NULL, + 'reject' => FALSE, 'bypass access' => array(), 'elements' => array(), 'mapping' => array(), @@ -1226,18 +1227,15 @@ function mollom_process_mollom($element, // Setup initial Mollom session and form information. if (empty($form_state['mollom'])) { $form_state['mollom'] = array( - 'form_id' => $element['#mollom_form']['form_id'], 'require_analysis' => $element['#mollom_form']['mode'] == MOLLOM_MODE_ANALYSIS, 'require_captcha' => $element['#mollom_form']['mode'] == MOLLOM_MODE_CAPTCHA, 'passed_captcha' => FALSE, - 'entity' => $element['#mollom_form']['entity'], - 'enabled_fields' => $element['#mollom_form']['enabled_fields'], - 'mapping' => $element['#mollom_form']['mapping'], 'response' => array( 'session_id' => '', ), ); } + $form_state['mollom'] += $element['#mollom_form']; // Add the Mollom session element. $element['session_id'] = array( @@ -1265,6 +1263,12 @@ function mollom_process_mollom($element, // $form_state['mollom'] will be carried over to the element for rendering. $element['#mollom'] = &$form_state['mollom']; + // Make Mollom form and session information available to entirely different + // functions. + // @todo Rename 'mollom_form' into 'mollom', and remove 'mollom_response'. + $GLOBALS['mollom_response'] = &$form_state['mollom']['response']; + $GLOBALS['mollom_form'] = &$form_state['mollom']; + return $element; } @@ -1343,9 +1347,6 @@ function mollom_validate_analysis(&$form } // Store the response returned by Mollom. $form_state['mollom']['response'] = $result; - // @todo Only used for Contact module and mail integration in general. - $GLOBALS['mollom_response'] = $form_state['mollom']['response']; - $GLOBALS['mollom_form'] = $form['mollom']['#mollom_form']; switch ($result['spam']) { case MOLLOM_ANALYSIS_HAM: @@ -1353,13 +1354,20 @@ function mollom_validate_analysis(&$form break; case MOLLOM_ANALYSIS_SPAM: - form_set_error('mollom', t('Your submission has triggered the spam filter and will not be accepted.')); + // By default, the submission is rejected, unless the form was configured + // to unpublish spam posts, which requires a valid 'reject callback'. + // @see mollom_validate_status() + if (!isset($form_state['mollom']['reject callback']) || !function_exists($form_state['mollom']['reject callback'])) { + form_set_error('mollom', t('Your submission has triggered the spam filter and will not be accepted.')); + } + else { + $form_state['mollom']['reject'] = TRUE; + } watchdog('mollom', 'Spam:
@message
Result:
@result
', array('@message' => print_r($data, TRUE), '@result' => print_r($result, TRUE))); break; - default: - // Fall back to a CAPTCHA. - form_set_error('mollom', t("To complete this form, please complete the word verification below.")); + case MOLLOM_ANALYSIS_UNSURE: + form_set_error('mollom][captcha', t('To complete this form, please complete the word verification below.')); watchdog('mollom', 'Unsure:
@message
Result:
@result
', array('@message' => print_r($data, TRUE), '@result' => print_r($result, TRUE))); $form_state['mollom']['require_captcha'] = TRUE; @@ -1378,11 +1386,10 @@ function mollom_validate_captcha(&$form, // When re-validating a form that already passed a CAPTCHA in a previous // request, we need to re-populate our global variable for mollom_data_save(). if ($form_state['mollom']['passed_captcha']) { - $GLOBALS['mollom_response'] = $form_state['mollom']['response']; return; } - // Bail out if no value was provided. + // Nothing to validate if there is no value. if (empty($form_state['values']['mollom']['captcha'])) { form_set_error('mollom][captcha', t('The word verification field is required.')); return; @@ -1400,9 +1407,7 @@ function mollom_validate_captcha(&$form, 'author_id' => isset($data['author_id']) ? $data['author_id'] : NULL, )); // Store the response for #submit handlers. - $form_state['mollom']['response']['spam'] = (int) $result; - $GLOBALS['mollom_response'] = $form_state['mollom']['response']; - $GLOBALS['mollom_form'] = $form['mollom']['#mollom_form']; + $form_state['mollom']['response']['captcha'] = $result; // Explictly check for TRUE, since mollom.checkCaptcha() can also return an // error message (e.g. expired or invalid session_id). @@ -1418,6 +1423,20 @@ function mollom_validate_captcha(&$form, } /** + * Form validation handler to perform post-validation tasks. + * + * Required, since our individual form validation handlers may not be re-run + * after positive validation. Thus, any changes applied to form values may not + * persist across multiple submission attempts/form rebuilds. + */ +function mollom_validate_status(&$form, &$form_state) { + if (!$form_state['mollom']['reject']) { + $function = $form_state['mollom']['reject callback']; + $function($form, $form_state); + } +} + +/** * Form element #pre_render callback for CAPTCHA element. * * Conditionally alters the #type of the CAPTCHA form element into a 'hidden' @@ -1902,6 +1921,7 @@ function node_mollom_form_info($form_id) 'bypass access' => array('administer nodes', 'edit any ' . $type->type . ' content'), 'entity' => 'node', 'bundle' => $type->type, + 'reject callback' => 'node_mollom_reject', 'elements' => array(), 'mapping' => array( 'post_id' => 'nid', @@ -1944,6 +1964,13 @@ function mollom_nodeapi($node, $op) { } /** + * Mollom reject callback. + */ +function node_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = 0; +} + +/** * Implements hook_form_FORMID_alter(). * * Hook into the mass comment administration page and add some operations to @@ -2004,6 +2031,7 @@ function comment_mollom_form_info($form_ 'mode' => MOLLOM_MODE_ANALYSIS, 'bypass access' => array('administer comments'), 'entity' => 'comment', + 'reject callback' => 'comment_mollom_reject', 'elements' => array( 'subject' => t('Subject'), 'comment' => t('Comment'), @@ -2081,6 +2109,13 @@ function mollom_comment($comment, $op) { } /** + * Mollom reject callback. + */ +function comment_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = COMMENT_NOT_PUBLISHED; +} + +/** * Implements hook_form_FORMID_alter(). * * Hook into the mass comment administration page and add some operations to @@ -2146,6 +2181,7 @@ function user_mollom_form_info($form_id) 'title' => t('User registration form'), 'mode' => MOLLOM_MODE_CAPTCHA, 'bypass access' => array('administer users'), + 'reject callback' => 'user_mollom_reject', 'entity' => 'user', 'mapping' => array( 'post_id' => 'uid', @@ -2160,6 +2196,7 @@ function user_mollom_form_info($form_id) 'title' => t('User password request form'), 'mode' => MOLLOM_MODE_CAPTCHA, 'bypass access' => array('administer users'), + 'reject callback' => 'user_mollom_reject', 'entity' => 'user', 'mapping' => array( 'post_id' => 'uid', @@ -2173,6 +2210,13 @@ function user_mollom_form_info($form_id) } /** + * Mollom reject callback. + */ +function user_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = 0; +} + +/** * @} End of "name mollom_user". */