View source
<?php
namespace Drupal\agreement\Form;
use Drupal\agreement\AgreementHandlerInterface;
use Drupal\agreement\Entity\Agreement;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Mail\MailManagerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Routing\LocalRedirectResponse;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class AgreementForm implements FormInterface, ContainerInjectionInterface {
use StringTranslationTrait;
protected $agreementHandler;
protected $routeMatch;
protected $languageManager;
protected $account;
protected $messenger;
protected $mailManager;
public function __construct(AgreementHandlerInterface $agreementHandler, RouteMatchInterface $routeMatch, LanguageManagerInterface $languageManager, AccountProxyInterface $account, MessengerInterface $messenger, MailManagerInterface $mailManager) {
$this->agreementHandler = $agreementHandler;
$this->routeMatch = $routeMatch;
$this->languageManager = $languageManager;
$this->account = $account;
$this->messenger = $messenger;
$this->mailManager = $mailManager;
}
public function getFormId() {
$agreement = $this->routeMatch
->getParameter('agreement');
return 'agreement_' . $agreement
->id() . '_form';
}
public function title(RouteMatchInterface $routeMatch, Agreement $agreement) {
$settings = $agreement
->getSettings();
return $this
->t('@title', [
'@title' => $settings['title'],
]);
}
public function buildForm(array $form, FormStateInterface $form_state, Agreement $agreement = NULL) {
$settings = $agreement
->getSettings();
$agreed = $this->agreementHandler
->hasAgreed($agreement, $this->account);
$canAgree = $this->agreementHandler
->canAgree($agreement, $this->account);
$canRevoke = $this->account
->hasPermission('revoke own agreement');
$form_state
->setStorage([
'agreement' => $agreement,
'agreed' => $agreed,
]);
$form['agreement'] = [
'#type' => 'container',
'#tree' => TRUE,
'text' => [
'#type' => 'processed_text',
'#text' => $agreement
->get('agreement'),
'#format' => $settings['format'],
'#language' => $this->languageManager
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId(),
],
'agree' => [
'#type' => 'checkbox',
'#title' => $this
->t('@agree', [
'@agree' => $settings['checkbox'],
]),
'#default_value' => $agreed,
'#access' => (!$agreed || $canRevoke) && $canAgree,
'#parents' => [
'agree',
],
],
];
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#name' => 'submit',
'#value' => $this
->t('@agree_submit', [
'@agree_submit' => $settings['submit'],
]),
'#access' => (!$agreed || $canRevoke) && $canAgree,
],
];
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$storage = $form_state
->getStorage();
if (!$form_state
->getValue('agree') && !$storage['agreed']) {
$settings = $storage['agreement']
->getSettings();
$form_state
->setErrorByName('agree', $this
->t('@agree_error', [
'@agree_error' => $settings['failure'],
]));
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$storage = $form_state
->getStorage();
$agreement = $storage['agreement'];
$settings = $agreement
->getSettings();
$destination = '/';
$agree = $form_state
->getValue('agree');
if ($settings['destination']) {
$destination = $settings['destination'];
}
elseif (isset($_SESSION['agreement_destination'])) {
$destination = $_SESSION['agreement_destination'];
}
$successfulResponse = $this
->processAgreement($agreement, $agree, $storage, $destination);
if ($successfulResponse) {
$message = $agree ? $settings['success'] : $settings['revoked'];
$this->messenger
->addStatus($this
->t('@success', [
'@success' => $message,
]));
if ($settings['recipient'] && (!$storage['agreed'] || !$agree)) {
$mail_key = $agree ? 'notice' : 'revoked';
$this
->notify($agreement, $this->account, $settings['recipient'], $mail_key);
}
$form_state
->setResponse($successfulResponse);
}
elseif (!$storage['agreed']) {
$this->messenger
->addError($this
->t('An error occurred accepting the agreement. Please try again.'));
}
}
protected function processAgreement(Agreement $agreement, int $agree, array $storage, string $destination) {
$successfulResponse = new LocalRedirectResponse($destination);
if ($this->agreementHandler
->isAnonymousAgreement($agreement, $this->account)) {
$cookie = $this->agreementHandler
->agree($agreement, $this->account, $agree);
if (!$cookie) {
return FALSE;
}
$successfulResponse->headers
->setCookie($cookie);
$successfulResponse
->addCacheableDependency((new CacheableMetadata())
->addCacheContexts([
'cookies:' . $cookie
->getName(),
]));
return $successfulResponse;
}
elseif ($this->agreementHandler
->agree($agreement, $this->account, $agree)) {
return $successfulResponse;
}
return FALSE;
}
protected function notify(Agreement $agreement, AccountInterface $account, $mail = '', $key = 'notice') {
if ($mail) {
$params = [
'context' => [
'agreement' => $agreement,
],
'account' => $account,
];
$this->mailManager
->mail('agreement', $key, $mail, $account
->getPreferredAdminLangcode(), $params);
}
}
public static function create(ContainerInterface $container) {
return new static($container
->get('agreement.handler'), $container
->get('current_route_match'), $container
->get('language_manager'), $container
->get('current_user'), $container
->get('messenger'), $container
->get('plugin.manager.mail'));
}
}