Index: mollom.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.admin.inc,v retrieving revision 1.40 diff -u -p -r1.40 mollom.admin.inc --- mollom.admin.inc 22 Sep 2010 10:33:14 -0000 1.40 +++ mollom.admin.inc 24 Sep 2010 15:37:17 -0000 @@ -153,6 +153,21 @@ function mollom_admin_configure_form($fo ); if (!empty($mollom_form['elements'])) { + // By default, Mollom module rejects all posts that did not successfully + // pass mollom.checkContent. Instead of rejecting posts, site admins + // can optionally configure that posts shall be unpublished instead, so + // they can go through manual moderation. The negated form widget may + // look odd, but users can rather relate to more common terms like + // "unpublish" or "moderation". Furthermore, this setting should stay + // optional and disabled by default, as Mollom should reject bad posts. + $form['mollom']['reject'] = array( + '#type' => 'checkbox', + '#title' => t('Unpublish bad posts for manual moderation instead of rejecting them'), + '#default_value' => !$mollom_form['reject'], + // Only possible for forms supporting moderation of unpublished posts. + '#access' => !empty($mollom_form['reject callback']), + ); + // If not re-configuring an existing protection, make it the default. if (!isset($mollom_form['mode'])) { $form['mollom']['mode']['#default_value'] = MOLLOM_MODE_ANALYSIS; Index: mollom.api.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.api.php,v retrieving revision 1.6 diff -u -p -r1.6 mollom.api.php --- mollom.api.php 12 Sep 2010 22:05:55 -0000 1.6 +++ mollom.api.php 24 Sep 2010 15:35:24 -0000 @@ -150,6 +150,9 @@ * $form_info = array( * // Optional: User permission list to skip Mollom's protection for. * 'bypass access' => array('administer instant messages'), + * // Optional: Function to invoke to unpublish a bad form submission + * // instead of rejecting it. + * '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 "][" @@ -205,6 +208,16 @@ * Additionally, the "post_id" data property always needs to be mapped to a form * element that holds the entity id. * + * When registering a 'reject callback', then the registered function needs to + * be available when the form is validated, and it is responsible for changing + * the submitted form values in a way that results in an unpublished post ending + * up in a moderation queue: + * @code + * function im_mollom_reject(&$form, &$form_state) { + * $form_state['values']['status'] = 0; + * } + * @endcode + * * @see mollom_node * @see mollom_comment * @see mollom_user @@ -276,6 +289,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.27 diff -u -p -r1.27 mollom.install --- mollom.install 21 Sep 2010 15:59:39 -0000 1.27 +++ mollom.install 24 Sep 2010 15:42:13 -0000 @@ -159,6 +159,13 @@ function mollom_schema() { 'not null' => FALSE, 'serialize' => TRUE, ), + 'reject' => array( + 'description' => 'Whether to reject (1) or unpublish (0) bad form submissions.', + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 1, + ), 'enabled_fields' => array( 'description' => 'Form elements to analyze.', 'type' => 'text', @@ -596,3 +603,17 @@ function mollom_update_7006() { ->condition('form_id', 'comment_form') ->execute(); } + +/** + * Add {mollom_form}.reject column to form configuration. + */ +function mollom_update_7007() { + if (!db_field_exists('mollom_form', 'reject')) { + db_add_field('mollom_form', 'reject', array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 1, + )); + } +} Index: mollom.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/mollom/mollom.module,v retrieving revision 1.84 diff -u -p -r1.84 mollom.module --- mollom.module 24 Sep 2010 15:29:49 -0000 1.84 +++ mollom.module 24 Sep 2010 15:44:47 -0000 @@ -624,6 +624,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_post'; // Add a submit handler to remove form state storage. $form['#submit'][] = 'mollom_form_submit'; @@ -752,6 +753,7 @@ function mollom_form_info($form_id, $mod 'module' => $module, 'entity' => NULL, 'mode' => NULL, + 'reject' => TRUE, 'bypass access' => array(), 'elements' => array(), 'mapping' => array(), @@ -1220,6 +1222,13 @@ function mollom_process_mollom($element, } $form_state['mollom'] += $element['#mollom_form']; + // By default, bad form submissions are rejected, unless the form was + // configured to unpublish bad posts. 'reject' may only be FALSE, if there is + // a valid 'reject callback'. Otherwise, it must be TRUE. + if (empty($form_state['mollom']['reject callback']) || !function_exists($form_state['mollom']['reject callback'])) { + $form_state['mollom']['reject'] = TRUE; + } + // Add the Mollom session element. $element['session_id'] = array( '#type' => 'hidden', @@ -1346,7 +1355,9 @@ function mollom_validate_analysis(&$form case MOLLOM_ANALYSIS_SPAM: $form_state['mollom']['require_captcha'] = FALSE; - form_set_error('mollom', t('Your submission has triggered the spam filter and will not be accepted.')); + if ($form_state['mollom']['reject']) { + form_set_error('mollom', t('Your submission has triggered the spam filter and will not be accepted.')); + } _mollom_watchdog(array( 'Spam: %teaser' => array('%teaser' => $teaser), 'Data:
@data' => array('@data' => $data), @@ -1472,6 +1483,26 @@ function mollom_validate_captcha(&$form, } /** + * Form validation handler to perform post-validation tasks. + * + * Since our individual form validation handlers are not re-run after positive + * validation, any changes applied to form values will not persist across + * multiple form submission attempts and rebuilds. + */ +function mollom_validate_post(&$form, &$form_state) { + // Unpublish a post instead of rejecting it. If 'reject' is not TRUE, then + // the 'reject callback' is responsible for altering $form_state in a way that + // the post ends up unpublished in a moderation queue. Most callbacks will + // only want to set a value in $form_state. Technically, modules do not need + // to implement a 'reject callback' to achieve this, they may simply add a + // custom form validation handler (or use an existing one). + if (!$form_state['mollom']['reject']) { + $function = $form_state['mollom']['reject callback']; + $function($form, $form_state); + } +} + +/** * Form submit handler to flush Mollom session and form information from cache. */ function mollom_form_submit($form, &$form_state) { @@ -1992,6 +2023,7 @@ function node_mollom_form_info($form_id) // @todo This is incompatible with node access. 'bypass access' => array('bypass node access', 'edit any ' . $type->type . ' content'), 'bundle' => $type->type, + 'reject callback' => 'node_mollom_reject', 'elements' => array(), 'mapping' => array( 'post_id' => 'nid', @@ -2016,6 +2048,13 @@ function node_mollom_form_info($form_id) } /** + * Mollom reject callback. + */ +function node_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = 0; +} + +/** * Implements hook_form_FORMID_alter(). */ function mollom_form_node_multiple_delete_confirm_alter(&$form, &$form_state) { @@ -2070,6 +2109,7 @@ function comment_mollom_form_info($form_ $form_info = array( 'mode' => MOLLOM_MODE_ANALYSIS, 'bypass access' => array('administer comments'), + 'reject callback' => 'comment_mollom_reject', 'elements' => array( 'subject' => t('Subject'), // @todo Update for Field API. @@ -2144,6 +2184,7 @@ function user_mollom_form_info($form_id) $form_info = array( 'mode' => MOLLOM_MODE_CAPTCHA, 'bypass access' => array('administer users'), + 'reject callback' => 'user_mollom_reject', 'mapping' => array( 'post_id' => 'uid', 'author_name' => 'name', @@ -2168,6 +2209,13 @@ function user_mollom_form_info($form_id) } /** + * Mollom reject callback. + */ +function comment_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = COMMENT_NOT_PUBLISHED; +} + +/** * Implements hook_form_FORMID_alter(). */ function mollom_form_user_multiple_cancel_confirm_alter(&$form, &$form_state) { @@ -2190,6 +2238,13 @@ function mollom_form_user_multiple_cance } /** + * Mollom reject callback. + */ +function user_mollom_reject(&$form, &$form_state) { + $form_state['values']['status'] = 0; +} + +/** * @} End of "name mollom_user". */