View source
<?php
namespace Drupal\flood_control\Form;
use Drupal\Core\Database\Connection;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\flood_control\FloodUnblockManager;
class FloodUnblockAdminForm extends FormBase {
protected $database;
protected $floodUnblockManager;
protected $dateFormatter;
protected $userFloodConfig;
public function __construct(FloodUnblockManager $floodUnblockManager, Connection $database, DateFormatterInterface $date_formatter) {
$this->floodUnblockManager = $floodUnblockManager;
$this->database = $database;
$this->dateFormatter = $date_formatter;
$this->userFloodConfig = $this
->configFactory()
->get('user.flood');
}
public static function create(ContainerInterface $container) {
return new static($container
->get('flood_control.flood_unblock_manager'), $container
->get('database'), $container
->get('date.formatter'));
}
public function getFormId() {
return 'flood_unblock_admin_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$limit = $form_state
->getValue('limit') ?? 33;
$identifier = $form_state
->getValue('identifier');
$form['top_markup'] = [
'#markup' => $this
->t("<p>List of IP addresses and user ID's that are blocked after multiple failed login attempts. You can remove separate entries. You can configure the login attempt limits and time windows on the <a href=':url'>Flood Control settings page</a>.</p>", [
':url' => Url::fromRoute('flood_control.settings')
->toString(),
]),
];
$form['filter'] = [
'#type' => 'details',
'#title' => $this
->t('Filter'),
'#open' => FALSE,
'limit' => [
'#type' => 'number',
'#title' => $this
->t('Amount'),
'#description' => $this
->t("Number of lines shown in table."),
'#size' => 5,
'#min' => 1,
'#steps' => 10,
'#default_value' => $limit,
],
'identifier' => [
'#type' => 'textfield',
'#title' => $this
->t('Identifier'),
'#default_value' => $identifier,
'#size' => 20,
'#description' => $this
->t('(Part of) identifier: IP address or UID'),
'#maxlength' => 256,
],
'submit' => [
'#type' => 'submit',
'#value' => $this
->t('Filter'),
],
];
$header = [
'identifier' => [
'data' => $this
->t('Identifier'),
'field' => 'identifier',
'sort' => 'asc',
],
'blocked' => $this
->t('Status'),
'event' => [
'data' => $this
->t('Event'),
'field' => 'event',
'sort' => 'asc',
],
'timestamp' => [
'data' => $this
->t('Timestamp'),
'field' => 'timestamp',
'sort' => 'asc',
],
'expiration' => [
'data' => $this
->t('Expiration'),
'field' => 'expiration',
'sort' => 'asc',
],
];
$options = [];
if ($this->database
->schema()
->tableExists('flood')) {
$query = $this->database
->select('flood', 'f')
->extend('Drupal\\Core\\Database\\Query\\TableSortExtender')
->orderByHeader($header);
$query
->fields('f');
if ($identifier) {
$query
->condition('identifier', "%" . $this->database
->escapeLike($identifier) . "%", 'LIKE');
}
$pager = $query
->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender')
->limit($limit);
$execute = $pager
->execute();
$results = $execute
->fetchAll();
$results_identifiers = array_column($results, 'identifier', 'fid');
$identifiers = $this->floodUnblockManager
->fetchIdentifiers(array_unique($results_identifiers));
foreach ($results as $result) {
$is_blocked = $this->floodUnblockManager
->isBlocked($result->identifier, $result->event);
$options[$result->fid] = [
'identifier' => $identifiers[$result->identifier],
'blocked' => $is_blocked ? $this
->t('Blocked') : $this
->t('Not blocked'),
'event' => $this->floodUnblockManager
->getEventLabel($result->event),
'timestamp' => $this->dateFormatter
->format($result->timestamp, 'short'),
'expiration' => $this->dateFormatter
->format($result->expiration, 'short'),
];
}
}
$form['table'] = [
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#empty' => $this
->t('There are no failed logins at this time.'),
];
$form['remove'] = [
'#type' => 'submit',
'#value' => $this
->t('Removed selected items from the flood table'),
'#validate' => [
'::validateRemoveItems',
],
];
if (count($options) == 0) {
$form['remove']['#disabled'] = TRUE;
}
$form['pager'] = [
'#type' => 'pager',
];
$form['#cache'] = [
'tags' => $this->userFloodConfig
->getCacheTags(),
];
return $form;
}
public function validateRemoveItems(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$entries = $form_state
->getValue('table');
$selected_entries = array_filter($entries, function ($selected) {
return $selected !== 0;
});
if (empty($selected_entries)) {
$form_state
->setErrorByName('table', $this
->t('Please make a selection.'));
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
foreach ($form_state
->getValue('table') as $fid) {
if ($fid !== 0) {
$this->floodUnblockManager
->floodUnblockClearEvent($fid);
}
}
$form_state
->setRebuild();
}
}