iframe_consent-1.0.x-dev/src/Form/ConsentGroupsForm.php
src/Form/ConsentGroupsForm.php
<?php
namespace Drupal\iframe_consent\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configure iframe_consent Consent groups for this site.
*/
class ConsentGroupsForm extends ConfigFormBase {
/**
* The template for an empty consent group.
*/
protected const EMPTY_CONSENT_GROUP_TEMPLATE = [
'id' => '',
'label' => '',
];
/**
* The iframe consent settings service.
*
* @var \Drupal\iframe_consent\Service\IframeConsentHelper
*/
protected $iframeConsentHelper;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->iframeConsentHelper = $container->get('iframe_consent.helper');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'iframe_consent_consent_groups';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['iframe_consent.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('iframe_consent.settings')->get('consent_groups');
if (is_null($form_state->get('consent_groups'))) {
if (empty($config)) {
$form_state->set('consent_groups', [self::EMPTY_CONSENT_GROUP_TEMPLATE]);
}
else {
$config[] = self::EMPTY_CONSENT_GROUP_TEMPLATE;
$form_state->set('consent_groups', $config);
}
}
// Add this wrapper to the add more feature.
$form['consent_groups'] = [
'#type' => 'fieldset',
'#title' => $this->t('Consent groups list'),
'#tree' => TRUE,
'#prefix' => '<div id="iframe-consent-consent-groups-wrapper">',
'#suffix' => '</div>',
];
if ($form_state->get('consent_groups')) {
foreach ($form_state->get('consent_groups') as $delta => $item) {
$form['consent_groups'][$delta] = $this->consentGroupFieldset($delta, 'consent_groups', $item['id'], $item['label']);
}
}
// Add a button to add more consent groups.
$form['add_more'] = [
'#type' => 'submit',
'#value' => $this->t('Add more'),
'#submit' => ['::addMore'],
'#ajax' => [
'callback' => '::addMoreCallback',
'wrapper' => 'iframe-consent-consent-groups-wrapper',
],
];
return parent::buildForm($form, $form_state);
}
/**
* Builds a consent group fieldset.
*
* @param string $delta
* The delta of the fieldset.
* @param string $parents
* The parents fields of the fieldset.
* @param string $id
* The ID of the consent group.
* @param string $label
* The label of the consent group.
*
* @return array
* A fieldset array.
*/
private function consentGroupFieldset(string $delta, string $parents, string $id = '', string $label = '') {
$id_has_usage = $this->iframeConsentHelper->isGroupsInUse($id);
$id_description = $this->t('The ID of the consent group. It must be unique and cannot contain spaces.');
$id_has_usage_description = $this->t('This ID is already in use and cannot be changed. Edit the domains mapping to remove this "Consent group" from usage to be able to change it.');
$fieldset = [
'#type' => 'fieldset',
'#title' => $this->t('Consent group'),
'id' => [
'#type' => 'textfield',
'#title' => $this->t('ID'),
'#default_value' => $id,
'#description' => $id_has_usage ? $id_has_usage_description : $id_description,
'#disabled' => $id_has_usage,
'#states' => [
'required' => [
[':input[name="' . $parents . '[' . $delta . '][label]"]' => ['filled' => TRUE]],
],
],
],
'label' => [
'#type' => 'textfield',
'#title' => $this->t('Label'),
'#default_value' => $label,
'#states' => [
'required' => [
[':input[name="' . $parents . '[' . $delta . '][id]"]' => ['filled' => TRUE]],
],
],
],
];
return $fieldset;
}
/**
* Submit handler for the "add more" button.
*/
public function addMore(array &$form, FormStateInterface $form_state) {
$consent_groups = $form_state->get('consent_groups') ?? [];
$consent_groups[] = self::EMPTY_CONSENT_GROUP_TEMPLATE;
$form_state->set('consent_groups', $consent_groups);
$form_state->setRebuild();
}
/**
* Ajax callback for the "add more" button.
*/
public function addMoreCallback(array &$form, FormStateInterface $form_state) {
return $form['consent_groups'];
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$consent_groups_values = $form_state->getValue('consent_groups') ?? [];
foreach ($consent_groups_values as $delta => $item) {
if (empty($item['id']) && empty($item['label'])) {
continue;
}
// Check if ID contains spaces.
if (!empty($item['id']) && strpos($item['id'], ' ') !== FALSE) {
$form_state->setErrorByName("consent_groups][$delta][id", $this->t('ID must not contain spaces.'));
}
// Check if ID is unique.
foreach ($consent_groups_values as $other_delta => $other_item) {
if ($delta !== $other_delta && $item['id'] === $other_item['id']) {
$form_state->setErrorByName("consent_groups][$delta][id", $this->t('ID must be unique.'));
}
}
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$consent_groups_values = $form_state->getValue('consent_groups') ?? [];
$consent_groups = [];
// Remove empty values.
foreach ($consent_groups_values as $item) {
if (!empty($item['id']) && !empty($item['label'])) {
$consent_groups[] = $item;
}
}
if (!empty($consent_groups)) {
$this->config('iframe_consent.settings')
->set('consent_groups', $consent_groups)
->save();
}
parent::submitForm($form, $form_state);
// Clear the cache tags.
$this->iframeConsentHelper->clearCacheTags();
}
}
