Ejemplo n.º 1
0
 /**
  * Get the HTML markup for a Mollom CAPTCHA and add it to the Mollom element.
  *
  * @param array $element
  *   The Mollom custom form element passed by reference.
  */
 public static function addMollomCaptcha(&$element)
 {
     // Load the CAPTCHA from the Mollom API.
     $data = array('type' => in_array($element['captcha_required']['#value'], array('image', 'audio')) ? $element['captcha_required']['#value'] : 'image', 'ssl' => (int) (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'));
     // If the requested type is audio, make sure it is enabled for the site.
     if ($data['type'] == 'audio') {
         if (!\Drupal::config('mollom.settings')->get('captcha.audio.enabled')) {
             $data['type'] = 'image';
         }
     }
     if (!empty($element['contentId']['#value'])) {
         $data['contentId'] = $element['contentId']['#value'];
     }
     /** @var \Drupal\mollom\API\DrupalClient $mollom */
     $mollom_service = \Drupal::service('mollom.client');
     $captcha_result = $mollom_service->createCaptcha($data);
     // Add a log message to prevent the request log from appearing without a
     // message on CAPTCHA-only protected forms.
     \Drupal::logger('mollom')->notice('Retrieved new CAPTCHA: @id', array('@id' => isset($captcha_result['id']) ? $captcha_result['id'] : 'error'));
     // Check the response is valid.
     if (is_array($captcha_result) && isset($captcha_result['url'])) {
         $element['response']['captcha']['#value'] = $captcha_result;
     } else {
         $element['captcha']['#access'] = FALSE;
         \Drupal\mollom\Utility\MollomUtilities::handleFallback();
         $element['captchaId']['#value'] = 'invalid';
         return FALSE;
     }
     // Theme CAPTCHA output.
     // $element['captcha']['#theme'] = 'mollom_captcha';
     $element['captcha']['captcha_display'] = array('#theme' => $data['type'] == 'audio' ? 'mollom_captcha_audio' : 'mollom_captcha_image', '#captcha_url' => $captcha_result['url'], '#weight' => 20);
     // Add the CAPTCHA and its data to the element.
     $element['captcha']['#access'] = TRUE;
     //$element['captcha']['#field_prefix'] = $captcha_rendered;
     $element['captcha']['captcha_input']['#attributes'] = array('title' => t('Enter the characters from the verification above.'));
     // The mollom.swfobject library is only added if swfobject is available on the site.
     // @see mollom_library_info_build().
     if (\Drupal::service('library.discovery')->getLibraryByName('mollom', 'mollom.swfobject')) {
         $element['captcha']['#attached']['library'][] = 'mollom/mollom.swfobject';
     }
     // Ensure that the latest CAPTCHA ID is output as value.
     $element['captchaId']['#value'] = $captcha_result['id'];
     // The form element cannot be marked as #required, since _form_validate()
     // would throw an element validation error on an empty value otherwise,
     // before the form-level validation handler is executed.
     // #access cannot default to FALSE, since the $form may be cached, and
     // Form API ignores user input for all elements that are not accessible.
     $element['captcha']['captcha_input']['#required'] = TRUE;
     return !empty($captcha_result['url']);
 }
Ejemplo n.º 2
0
 /**
  * Form validation handler to perform textual analysis on submitted form values.
  */
 public static function validateAnalysis(&$form, FormState $form_state)
 {
     if (!static::shouldValidate($form, $form_state)) {
         return;
     }
     /** @var \Drupal\mollom\Entity\Form $mollom_form */
     $mollom = $form_state->getValue('mollom');
     if (!$mollom['require_analysis']) {
         return FALSE;
     }
     // Perform textual analysis.
     $all_data = self::extractMollomValues($form_state->cleanValues(), $mollom['enabled_fields'], $mollom['mapping']);
     // Cancel processing upon invalid UTF-8 data.
     if ($all_data === FALSE) {
         return FALSE;
     }
     $data = $all_data;
     // Remove postId property; only used by submitForm().
     if (isset($data['postId'])) {
         unset($data['postId']);
     }
     $contentId = isset($mollom['contentId']) ? $mollom['contentId'] : NULL;
     if (!empty($contentId)) {
         $data['id'] = $contentId;
     }
     if (is_array($mollom['checks'])) {
         $data['checks'] = $mollom['checks'];
     }
     $data['strictness'] = $mollom['strictness'];
     if (isset($mollom['type'])) {
         $data['type'] = $mollom['type'];
     }
     if (in_array('spam', $data['checks']) && $mollom['unsure'] == 'binary') {
         $data['unsure'] = 0;
     }
     // Allow modules to alter data sent.
     \Drupal::moduleHandler()->alter('mollom_content', $data);
     /** @var \Drupal\mollom\API\DrupalClient $mollom */
     $mollom_service = \Drupal::service('mollom.client');
     $result = $mollom_service->checkContent($data);
     // Use all available data properties for log messages below.
     $data += $all_data;
     // Trigger global fallback behavior if there is a unexpected result.
     if (!is_array($result) || !isset($result['id'])) {
         return MollomUtilities::handleFallback();
     }
     // Set form values accordingly. Do not overwrite the entity ID.
     // @todo Rename 'id' to 'entity_id'.
     $result['contentId'] = $result['id'];
     unset($result['id']);
     // Store the response returned by Mollom.
     $form_state->setValue(array('mollom', 'response', 'content'), $result);
     $form_state->setValue('mollom', array_merge($mollom, $result));
     // Ensure the latest content ID is output as value.
     // form_set_value() is effectless, as this is not a element-level but a
     // form-level validation handler.
     $form['mollom']['contentId']['#value'] = $result['contentId'];
     // Prepare watchdog message teaser text.
     $teaser = '--';
     if (isset($data['postTitle'])) {
         $teaser = Unicode::truncate(strip_tags($data['postTitle']), 40);
     } elseif (isset($data['postBody'])) {
         $teaser = Unicode::truncate(strip_tags($data['postBody']), 40);
     }
     // Handle the profanity check result.
     if (isset($result['profanityScore']) && $result['profanityScore'] >= 0.5) {
         if ($mollom['discard']) {
             $form_state->setError($form, t('Your submission has triggered the profanity filter and will not be accepted until the inappropriate language is removed.'));
         } else {
             $form_state->setValue(['mollom', 'require_moderation'], TRUE);
         }
         Logger::addMessage(array('message' => 'Profanity: %teaser', 'arguments' => array('%teaser' => $teaser)));
     }
     // Handle the spam check result.
     // The Mollom API takes over state tracking for each content ID/session. The
     // spamClassification will usually turn into 'ham' after solving a CAPTCHA.
     // It may also change to 'spam', if the user replaced the values with very
     // spammy content. In any case, we always do what we are told to do.
     $form_state->setValue(['mollom', 'require_captcha'], FALSE);
     $form['mollom']['captcha']['#access'] = FALSE;
     if (isset($result['spamClassification'])) {
         switch ($result['spamClassification']) {
             case 'ham':
                 $message = SafeMarkup::format('Ham: %teaser', array('%teaser' => $teaser));
                 \Drupal::logger('mollom')->notice($message);
                 break;
             case 'spam':
                 if ($mollom['discard']) {
                     $form_state->setError($form, t('Your submission has triggered the spam filter and will not be accepted. @fp_message', array('@fp_message' => MollomUtilities::formatFalsePositiveMessage($form_state, $data))));
                 } else {
                     $form_state->setValue(array('mollom', 'require_moderation'), TRUE);
                 }
                 $message = SafeMarkup::format('Spam: %teaser', array('%teaser' => $teaser));
                 \Drupal::logger('mollom')->notice($message);
                 break;
             case 'unsure':
                 if ($mollom['unsure'] == 'moderate') {
                     $form_state->setValue(array('mollom', 'require_moderation'), TRUE);
                 } else {
                     $form_state->setValue(['mollom', 'captcha_response_id'], NULL);
                     $form['mollom']['captcha_response_id']['#value'] = NULL;
                     $form_state->setValue(array('mollom', 'require_captcha'), TRUE);
                     // Require a new CAPTCHA and throw an error.
                     $had_captcha = $form_state->get('mollom_had_captcha');
                     $form_state->setCached(FALSE);
                     // Set the CAPTCHA type required indicator.
                     $form_state->setValue(array('mollom', 'captcha_required'), $mollom['captcha_type']);
                     $form['mollom']['captcha_required']['#value'] = $mollom['captcha_type'];
                     $form['mollom']['captcha']['#access'] = TRUE;
                     if (!empty($had_captcha)) {
                         $form_state->setErrorByName('mollom][captcha', t('The word verification was not completed correctly. Please complete this new word verification and try again.  @fp_message', array('@fp_message' => MollomUtilities::formatFalsePositiveMessage($form_state, $data))));
                     } else {
                         $form_state->setErrorByName('mollom][captcha', t('To complete this form, please complete the word verification.'));
                     }
                 }
                 $message = SafeMarkup::format('Unsure: %teaser', array('%teaser' => $teaser));
                 \Drupal::logger('mollom')->notice($message);
                 break;
             case 'unknown':
             default:
                 // If we end up here, Mollom responded with a unknown spamClassification.
                 // Normally, this should not happen, but if it does, log it. As there
                 // could be multiple reasons for this, it is not safe to trigger the
                 // fallback mode.
                 $message = SafeMarkup::format('Unknown: %teaser', array('%teaser' => $teaser));
                 \Drupal::logger('mollom')->notice($message);
                 break;
         }
     }
 }