View source
<?php
namespace Drupal\email_confirmer\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Path\PathValidatorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
class EmailConfirmerSettingsForm extends ConfigFormBase {
const SECONDS_PER_HOUR = 3600;
const SECONDS_PER_DAY = 86400;
const SECONDS_PER_WEEK = 604800;
protected $pathValidator;
protected $moduleHandler;
public function __construct(PathValidatorInterface $path_validator, ModuleHandlerInterface $module_handler) {
$this->pathValidator = $path_validator;
$this->moduleHandler = $module_handler;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('path.validator'), $container
->get('module_handler'));
}
public function getFormId() {
return 'email_confirmer_settings';
}
protected function getEditableConfigNames() {
return [
'email_confirmer.settings',
];
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$config = $this
->config('email_confirmer.settings');
$form['hash_expiration'] = [
'#type' => 'select',
'#title' => $this
->t('Response time limit'),
'#description' => $this
->t('Maximum time to attend the confirmation request from its creation.'),
'#options' => [
'1' => $this
->t('1 hour'),
],
'#default_value' => $config
->get('hash_expiration') ? round($config
->get('hash_expiration') / self::SECONDS_PER_HOUR) : 24,
'#required' => TRUE,
];
for ($i = 2; $i <= 48; $i++) {
$form['hash_expiration']['#options'][$i] = $this
->t('@count hours', [
'@count' => $i,
]);
if ($i > 11) {
$i++;
if ($i > 23) {
$i += 2;
}
}
}
$confirmation_lifetime = $config
->get('confirmation_lifetime');
$form['confirmation_lifetime'] = [
'#type' => 'select',
'#title' => $this
->t('Maximum confirmation lifetime'),
'#description' => $this
->t('Confirmations older than this value will be purged from database.'),
'#options' => [
'1' => $this
->t('1 week'),
],
'#default_value' => $confirmation_lifetime > 0 ? round($confirmation_lifetime / self::SECONDS_PER_WEEK) : $confirmation_lifetime,
'#required' => TRUE,
];
for ($i = 2; $i <= 7; $i++) {
$form['confirmation_lifetime']['#options'][$i] = $this
->t('@count weeks', [
'@count' => $i,
]);
}
for ($i = 2; $i <= 11; $i++) {
$form['confirmation_lifetime']['#options'][round($i * 4.33)] = $this
->t('@count months', [
'@count' => $i,
]);
}
$form['confirmation_lifetime']['#options'][52] = $this
->t('1 year');
$form['confirmation_lifetime']['#options'][0] = $this
->t('- Do not purge -');
$form['resendrequest_delay'] = [
'#type' => 'select',
'#title' => $this
->t('Delay before re-send request'),
'#description' => $this
->t('Time lapse between same confirmation request sendings.'),
'#options' => [],
'#default_value' => $config
->get('resendrequest_delay') ? round($config
->get('resendrequest_delay') / 60) : 15,
'#required' => TRUE,
];
for ($i = 5; $i <= 60; $i += 5) {
$form['resendrequest_delay']['#options'][$i] = $this
->t('@count minutes', [
'@count' => $i,
]);
}
$form['restrict_same_ip'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Accept email confirmation responses only from the same IP address that was requested'),
'#default_value' => $config
->get('restrict_same_ip') || FALSE,
];
$form['confirmationrequest_mail'] = [
'#type' => 'details',
'#title' => $this
->t('Confirmation email'),
];
$form['confirmationrequest_mail']['confirmationrequest_subject'] = [
'#type' => 'textfield',
'#title' => $this
->t('Subject'),
'#default_value' => $config
->get('confirmation_request.subject'),
'#maxlength' => 180,
];
$form['confirmationrequest_mail']['confirmationrequest_body'] = [
'#type' => 'textarea',
'#title' => $this
->t('Body text'),
'#default_value' => $config
->get('confirmation_request.body'),
'#rows' => 6,
];
if ($this->moduleHandler
->moduleExists('token')) {
$form['confirmationrequest_mail']['token_help'] = [
'#title' => $this
->t('Replacement patterns'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
];
$form['confirmationrequest_mail']['token_help']['browser'] = [
'#theme' => 'token_tree_link',
'#token_types' => [
'email-confirmer',
],
];
}
$form['confirmationresponse'] = [
'#type' => 'details',
'#title' => $this
->t('Response form'),
];
$form['confirmationresponse']['confirmationresponse_skipform'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Skip response form'),
'#description' => $this
->t('Performs a direct confirmation of the email address when the user opens the confirmation URL. This disables the explicit cancellation feature and may result in false confirmations if the link is opened some way else, like by antivirus or anti-SPAM software.'),
'#default_value' => $config
->get('confirmation_response.skip_confirmation_form') || FALSE,
];
foreach ([
'pending',
'expired',
'cancelled',
'confirmed',
] as $status) {
$form['confirmationresponse']['confirmationresponse_' . $status] = [
'#type' => 'textfield',
'#title' => $this
->t('Indications for @status confirmations', [
'@status' => $status,
]),
'#description' => $this
->t('A text displayed in the response form for @status confirmations.', [
'@status' => $status,
]),
'#default_value' => $config
->get('confirmation_response.questions.' . $status),
'#maxlength' => 255,
'#states' => [
'invisible' => [
':input[name="confirmationresponse_skipform"]' => [
'checked' => TRUE,
],
],
],
];
}
$form['response_url'] = [
'#type' => 'details',
'#title' => $this
->t('Confirmation pages'),
];
$form['response_url']['confirmationresponse_url_confirm'] = [
'#type' => 'textfield',
'#title' => $this
->t('On confirmation URL'),
'#description' => $this
->t('Default Drupal path or URL to go after an email is confirmed. Default to the front page.'),
'#default_value' => $config
->get('confirmation_response.url.confirm'),
];
$form['response_url']['confirmationresponse_url_cancel'] = [
'#type' => 'textfield',
'#title' => $this
->t('On cancellation URL'),
'#description' => $this
->t('Default Drupal path or URL to go after an email is cancelled. Default to the front page.'),
'#default_value' => $config
->get('confirmation_response.url.cancel'),
];
$form['response_url']['confirmationresponse_url_error'] = [
'#type' => 'textfield',
'#title' => $this
->t('On error URL'),
'#description' => $this
->t('Default Drupal path or URL to go where a confirmation error takes pace. Default to the front page.'),
'#default_value' => $config
->get('confirmation_response.url.error'),
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this
->config('email_confirmer.settings');
foreach ([
'pending',
'expired',
'cancelled',
'confirmed',
] as $status) {
$config
->set('confirmation_response.questions.' . $status, $form_state
->getValue('confirmationresponse_' . $status));
}
$config
->set('hash_expiration', intval($form_state
->getValue('hash_expiration')) * self::SECONDS_PER_HOUR)
->set('confirmation_lifetime', intval($form_state
->getValue('confirmation_lifetime')) * self::SECONDS_PER_WEEK)
->set('restrict_same_ip', $form_state
->getValue('restrict_same_ip') || FALSE)
->set('resendrequest_delay', intval($form_state
->getValue('resendrequest_delay')) * 60)
->set('confirmation_request.subject', $form_state
->getValue('confirmationrequest_subject'))
->set('confirmation_request.body', $form_state
->getValue('confirmationrequest_body'))
->set('confirmation_response.skip_confirmation_form', $form_state
->getValue('confirmationresponse_skipform') || FALSE)
->set('confirmation_response.url.confirm', $form_state
->getValue('confirmationresponse_url_confirm'))
->set('confirmation_response.url.cancel', $form_state
->getValue('confirmationresponse_url_cancel'))
->set('confirmation_response.url.error', $form_state
->getValue('confirmationresponse_url_error'))
->save();
parent::submitForm($form, $form_state);
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$hash_expiration = intval($form_state
->getValue('hash_expiration'));
if ($hash_expiration < 1) {
$form_state
->setErrorByName('hash_expiration', $this
->t('The miminum hash expiration time is @min_value.', [
'@min_value' => $this
->t('one hour'),
]));
}
elseif ($hash_expiration > 48) {
$form_state
->setErrorByName('hash_expiration', $this
->t('The maximum hash expiration time is @max_value.', [
'@max_value' => $this
->t('@count days', [
'@count' => 2,
]),
]));
}
$lifetime = intval($form_state
->getValue('confirmation_lifetime'));
if ($lifetime > 52) {
$form_state
->setErrorByName('confirmation_lifetime', $this
->t('The maximum confirmation lifetime is @max_value.', [
'@max_value' => $this
->t('one year'),
]));
}
$resendrequest_delay = intval($form_state
->getValue('resendrequest_delay'));
if ($resendrequest_delay < 5) {
$form_state
->setErrorByName('resendrequest_delay', $this
->t('The miminum confirmation request resend delay is @min_value.', [
'@min_value' => $this
->t('@count minutes', [
'@count' => 5,
]),
]));
}
elseif ($resendrequest_delay > 60) {
$form_state
->setErrorByName('resendrequest_delay', $this
->t('The maximum confirmation request resend delay is @max_value.', [
'@max_value' => $this
->t('one hour'),
]));
}
foreach ([
'confirm',
'cancel',
'error',
] as $page) {
$path = $form_state
->getValue("confirmationresponse_url_{$page}", '<front>');
if ($path != '<front>' && !$this->pathValidator
->isValid($path)) {
$form_state
->setErrorByName("confirmationresponse_url_{$page}", $this
->t("The path '%path' is either invalid or you do not have access to it.", [
'%path' => $path,
]));
}
}
}
}