/**
  * The content callback for the Blacklist list of current entries.
  *
  * @param string $type
  *   A particular list type to show (based on the entry 'reason').
  */
 function content($type = NULL)
 {
     MollomUtilities::getAdminAPIKeyStatus();
     MollomUtilities::displayMollomTestModeWarning();
     $items = BlacklistStorage::getList($type);
     $rows = array();
     // Edit/delete.
     $header = array();
     if (empty($type)) {
         $header['type'] = $this->t('List');
     }
     $header['context'] = $this->t('Context');
     $header['matches'] = $this->t('Matches');
     $header['value'] = $this->t('Value');
     $header['operations'] = $this->t('Operations');
     foreach ($items as $entry) {
         $data = array($entry['context'], $entry['match'], $entry['value'], array('data' => array('#type' => 'operations', '#links' => array(array('title' => $this->t('Delete'), 'url' => Url::fromRoute('mollom.blacklist.delete', array('entry_id' => $entry['id'])))))));
         if (empty($type)) {
             array_unshift($data, $entry['reason']);
         }
         $rows[] = $data;
     }
     $build['table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows, '#empty' => $this->t('There are no entries in the blacklist.'), '#attributes' => array('id' => 'mollom-blacklist-list'));
     return $build;
 }
 public function content()
 {
     MollomUtilities::getAdminAPIKeyStatus();
     $config = $this->config('mollom.settings');
     $embed_attributes = array('src' => 'https://mollom.com/statistics.swf?key=' . urlencode($config->get('keys.public')), 'quality' => 'high', 'width' => '100%', 'height' => '430', 'name' => 'Mollom', 'align' => 'middle', 'play' => 'true', 'loop' => 'false', 'allowScriptAccess' => 'sameDomain', 'type' => 'application/x-shockwave-flash', 'pluginspage' => 'http://www.adobe.com/go/getflashplayer', 'wmode' => 'transparent');
     return array('#type' => 'markup', '#markup' => '<embed' . new Attribute($embed_attributes) . '></embed>', '#allowed_tags' => ['embed']);
 }
Exemplo n.º 3
0
 /**
  * {@inheritdoc}
  */
 public function buildHeader()
 {
     MollomUtilities::getAdminAPIKeyStatus();
     MollomUtilities::displayMollomTestModeWarning();
     $header['label'] = $this->t('Form');
     $header['protection_mode'] = $this->t('Protection mode');
     return $header + parent::buildHeader();
 }
Exemplo n.º 4
0
 /**
  * Overrides Drupal\Core\Form\FormInterface::buildForm().
  */
 public function buildForm(array $form, FormStateInterface $form_state, $entry_id = NULL)
 {
     MollomUtilities::getAdminAPIKeyStatus();
     MollomUtilities::displayMollomTestModeWarning();
     $entry = $this->setEntryById($entry_id)->getEntry();
     $form['entry_id'] = array('#type' => 'value', '#value' => $entry_id);
     $form['reason'] = array('#type' => 'select', '#title' => $this->t('Type'), '#default_value' => $entry['reason'], '#options' => $this->getBlacklistTypeOptions(), '#required' => TRUE);
     $form['context'] = array('#type' => 'select', '#title' => $this->t('Context'), '#default_value' => $entry['context'], '#options' => $this->getContextOptions(), '#required' => TRUE);
     $form['match'] = array('#type' => 'select', '#title' => $this->t('Matches'), '#default_value' => $entry['match'], '#options' => $this->getMatchesOptions(), '#required' => TRUE);
     $form['value'] = array('#type' => 'textfield', '#title' => $this->t('Value'), '#default_value' => $entry['value'], '#required' => TRUE);
     $form['actions'] = array('#type' => 'actions');
     $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save entry'));
     return $form;
 }
 /**
  * Implements hook_init().
  */
 function onRequest()
 {
     // On all Mollom administration pages, check the module configuration and
     // display the corresponding requirements error, if invalid.
     $url = Url::fromRoute('<current>');
     $current_path = $url->toString();
     if (empty($_POST) && strpos($current_path, 'admin/config/content/mollom') === 0 && \Drupal::currentUser()->hasPermission('administer mollom')) {
         // Re-check the status on the settings form only.
         $status = \Drupal\mollom\Utility\MollomUtilities::getAPIKeyStatus($current_path == 'admin/config/content/mollom/settings');
         if ($status !== TRUE) {
             // Fetch and display requirements error message, without re-checking.
             module_load_install('mollom');
             $requirements = mollom_requirements('runtime', FALSE);
             if (isset($requirements['mollom']['description'])) {
                 drupal_set_message($requirements['mollom']['description'], 'error');
             }
         }
     }
 }
Exemplo n.º 6
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']);
 }
Exemplo n.º 7
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;
         }
     }
 }
Exemplo n.º 8
0
 /**
  * Calls _mollom_status() directly to verify that current API keys are valid.
  */
 protected function assertValidKeys()
 {
     $status = MollomUtilities::getAPIKeyStatus(TRUE);
     $this->assertMollomWatchdogMessages();
     $this->assertIdentical($status['isVerified'], TRUE, t('Mollom servers can be contacted and testing API keys are valid.'));
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $values = $form_state->getValues();
     $config = $this->config('mollom.settings');
     $config->set('keys.public', $values['keys']['public'])->set('keys.private', $values['keys']['private'])->set('fallback', $values['fallback'])->set('languages_expected', $values['languages_expected'])->set('privacy_link', $values['privacy_link'])->set('test_mode.enabled', $values['testing_mode'])->set('log_level', $values['log_level'])->set('captcha.audio.enabled', $values['audio_captcha_enabled'])->set('connection_timeout_seconds', $values['connection_timeout_seconds'])->save();
     parent::submitForm($form, $form_state);
     // Update Mollom site record with local configuration.
     MollomUtilities::getAPIKeyStatus(TRUE, TRUE);
 }
Exemplo n.º 10
0
 /**
  * Gets the status of Mollom's API key configuration and also displays a
  * warning message if the Mollom API keys are not configured.
  *
  * To be used within the Mollom administration pages only.
  *
  * @param bool $force
  *   (optional) Boolean whether to ignore the cached state and re-check.
  *   Defaults to FALSE.
  * @param bool $update
  *   (optional) Whether to update Mollom with locally stored configuration.
  *   Defaults to FALSE.
  *
  * @return array
  *   An associative array describing the current status of the module:
  *   - isConfigured: Boolean whether Mollom API keys have been configured.
  *   - isVerified: Boolean whether Mollom API keys have been verified.
  *   - response: The response error code of the API verification request.
  *   - ...: The full site resource, as returned by the Mollom API.
  *
  * @see Mollom::getAPIKeyStatus().
  */
 public static function getAdminAPIKeyStatus($force = FALSE, $update = FALSE)
 {
     $status = MollomUtilities::getAPIKeyStatus($force, $update);
     if (empty($_POST) && !$status['isVerified']) {
         // Fetch and display requirements error message, without re-checking.
         module_load_install('mollom');
         $requirements = mollom_requirements('runtime', FALSE);
         if (isset($requirements['mollom']['description'])) {
             drupal_set_message($requirements['mollom']['description'], 'error');
         }
     }
     return $status;
 }
Exemplo n.º 11
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     // Get anything we need form the base class.
     $form = parent::buildForm($form, $form_state);
     // Display any API key errors.
     MollomUtilities::getAdminAPIKeyStatus();
     MollomUtilities::displayMollomTestModeWarning();
     /* @var $entity \Drupal\mollom\Entity\FormInterface */
     $entity = $this->getEntity();
     $form_id = '';
     if ($entity->isNew()) {
         // Determine if the form id selection just changed.
         $input = $form_state->getUserInput();
         if (!empty($input['id'])) {
             $form_id = $input['id'];
             $mollom_form = $entity->initialize($form_id);
         } else {
             if ($query_form_id = \Drupal::request()->query->get('form_id', '')) {
                 $form_id = $query_form_id;
                 $mollom_form = $entity->initialize($form_id);
             }
         }
     } else {
         $form_id = $entity->id();
         $mollom_form = $entity->initialize();
     }
     $enabled_fields = [];
     if ($entity->isNew() && !empty($input['id'])) {
         foreach ($mollom_form['enabled_fields'] as $value) {
             $enabled_fields[] = rawurlencode($value);
         }
         // Set defaults back.
         // See https://www.drupal.org/node/1100170
         $input['checks'] = $entity->getChecks();
         $input['enabled_fields'] = $enabled_fields;
         $form_state->setUserInput($input);
     } else {
         foreach ($entity->getEnabledFields() as $value) {
             $enabled_fields[] = rawurldecode($value);
         }
     }
     // Build the form.
     if ($entity->isNew()) {
         $options = $this->getProtectableFormOptions();
         if (empty($options)) {
             return $this->redirect('entity.mollom_form.list');
         }
         $form['#attributes']['id'] = $this->getFormId();
         $form['id'] = array('#type' => 'select', '#title' => $this->t('Mollom Form'), '#maxlength' => 255, '#options' => $options, '#default_value' => $form_id, '#empty_option' => t('Select a form to configure...'), '#required' => TRUE, '#ajax' => array('callback' => array($this, 'ajaxFormHandler'), 'wrapper' => $this->getFormId()));
         // Must select the form to protect prior to continuing.
         if (empty($form_id)) {
             return $form;
         }
     } else {
         $form['label'] = array('#title' => t('Protected form'), '#type' => 'textfield', '#default_value' => $entity->label(), '#disabled' => TRUE);
     }
     // Protection mode
     $modes = array(FormInterface::MOLLOM_MODE_ANALYSIS => $this->t('@option <em>(@recommended)</em>', array('@option' => $this->t('Text analysis'), '@recommended' => $this->t('recommended'))), FormInterface::MOLLOM_MODE_CAPTCHA => t('CAPTCHA only'));
     $form['mode'] = array('#type' => 'radios', '#title' => t('Protection mode'), '#options' => $modes, '#default_value' => isset($entity->mode) ? $entity->mode : key($modes));
     $form['mode'][FormInterface::MOLLOM_MODE_ANALYSIS] = array('#description' => t('Mollom will analyze the post and will only show a CAPTCHA when it is unsure.'));
     $form['mode'][FormInterface::MOLLOM_MODE_CAPTCHA] = array('#description' => t('A CAPTCHA will be shown for every post. Only choose this if there are too few text fields to analyze.'));
     $form['mode'][FormInterface::MOLLOM_MODE_CAPTCHA]['#description'] .= '<br />' . t('Note: Page caching is disabled on all pages containing a CAPTCHA-only protected form.');
     $all_permissions = $this->permissionHandler->getPermissions();
     // Prepend Mollom's global permission to the list.
     if (empty($mollom_form['bypass access']) || !is_array($mollom_form['bypass access'])) {
         $mollom_form['bypass access'] = [];
     }
     array_unshift($mollom_form['bypass access'], 'bypass mollom protection');
     $permissions = array();
     if (isset($mollom_form['bypass access'])) {
         foreach ($mollom_form['bypass access'] as $permission) {
             $permissions[Html::getClass($permission)] = array('title' => $all_permissions[$permission]['title'], 'url' => Url::fromRoute('user.admin_permissions'), 'fragment' => 'module-' . $all_permissions[$permission]['provider']);
         }
     }
     $form['mode']['#description'] = t('The protection is omitted for users having any of the permissions: @permission-list', array('@permission-list' => \Drupal::theme()->render('links', array('links' => $permissions))));
     // Textual analysis filters.
     $form['checks'] = array('#type' => 'checkboxes', '#title' => t('Text analysis checks'), '#options' => array('spam' => t('Spam'), 'profanity' => t('Profanity')), '#default_value' => $entity->getChecks(), '#states' => array('visible' => array('[name="mode"]' => array('value' => (string) FormInterface::MOLLOM_MODE_ANALYSIS))));
     // Profanity check requires text to analyze; unlike the spam check, there
     // is no fallback in case there is no text.
     $form['checks']['profanity']['#access'] = !empty($mollom_form['elements']);
     // Form elements defined by hook_mollom_form_info() use the
     // 'parent][child' syntax, which Form API also uses internally for
     // form_set_error(), and which allows us to recurse into nested fields
     // during processing of submitted form values. However, since we are using
     // those keys also as internal values to configure the fields to use for
     // textual analysis, we need to encode them. Otherwise, a nested field key
     // would result in the following checkbox attribute:
     //   '#name' => 'mollom[enabled_fields][parent][child]'
     // This would lead to a form validation error, because it is a valid key.
     // By encoding them, we prevent this from happening:
     //   '#name' => 'mollom[enabled_fields][parent%5D%5Bchild]'
     $elements = array();
     if (isset($mollom_form['elements']) && is_array($mollom_form['elements'])) {
         foreach ($mollom_form['elements'] as $key => $value) {
             $elements[rawurlencode($key)] = $value;
         }
     }
     $enabled_field_selections = [];
     foreach ($enabled_fields as $key => $value) {
         $enabled_field_selections[rawurlencode($key)] = rawurlencode($value);
     }
     $form['enabled_fields'] = array('#type' => 'checkboxes', '#title' => t('Text fields to analyze'), '#options' => $elements, '#default_value' => $enabled_field_selections, '#description' => t('Only enable fields that accept text (not numbers). Omit fields that contain sensitive data (e.g., credit card numbers) or computed/auto-generated values, as well as author information fields (e.g., name, e-mail).'), '#access' => !empty($mollom_form['elements']), '#states' => array('visible' => array('[name="mode"]' => array('value' => (string) FormInterface::MOLLOM_MODE_ANALYSIS))));
     $form['mapping'] = array('#type' => 'value', '#value' => $mollom_form['mapping']);
     if ($entity->isNew()) {
         $form['module'] = array('#type' => 'value', '#value' => $mollom_form['module']);
         $form['label'] = array('#type' => 'value', '#value' => $mollom_form['title']);
         $form['entity'] = array('#type' => 'value', '#value' => $mollom_form['entity']);
         $form['bundle'] = array('#type' => 'value', '#value' => $mollom_form['bundle']);
     }
     $form['strictness'] = array('#type' => 'radios', '#title' => t('Text analysis strictness'), '#options' => array('normal' => t('@option <em>(@recommended)</em>', array('@option' => t('Normal'), '@recommended' => $this->t('recommended'))), 'strict' => t('Strict: Posts are more likely classified as spam'), 'relaxed' => t('Relaxed: Posts are more likely classified as ham')), '#default_value' => $entity->getStrictness(), '#states' => array('visible' => array('[name="mode"]' => array('value' => (string) FormInterface::MOLLOM_MODE_ANALYSIS))));
     $form['unsure'] = array('#type' => 'radios', '#title' => t('When text analysis is unsure'), '#default_value' => $entity->getUnsure(), '#options' => array('captcha' => t('@option <em>(@recommended)</em>', array('@option' => t('Show a CAPTCHA'), '@recommended' => $this->t('recommended'))), 'moderate' => t('Retain the post for manual moderation'), 'binary' => t('Accept the post')), '#required' => $entity->getProtectionMode() == FormInterface::MOLLOM_MODE_ANALYSIS, '#states' => array('visible' => array('[name="mode"]' => array('value' => (string) FormInterface::MOLLOM_MODE_ANALYSIS), '[name="checks[spam]"]' => array('checked' => TRUE))));
     // Only possible for forms supporting moderation of unpublished posts.
     $form['unsure']['moderate']['#access'] = !empty($mollom_form['moderation callback']);
     $form['discard'] = array('#type' => 'radios', '#title' => t('When text analysis identifies spam'), '#default_value' => $entity->getDiscard(), '#options' => array(1 => t('@option <em>(@recommended)</em>', array('@option' => t('Discard the post'), '@recommended' => $this->t('recommended'))), 0 => t('Retain the post for manual moderation')), '#required' => $entity->getProtectionMode() == FormInterface::MOLLOM_MODE_ANALYSIS, '#states' => array('visible' => array('[name="mode"]' => array('value' => (string) FormInterface::MOLLOM_MODE_ANALYSIS), '[name="checks[spam]"]' => array('checked' => TRUE))));
     // Return the form.
     return $form;
 }