google_tag-8.x-1.x-dev/src/Form/TagContainerForm.php
src/Form/TagContainerForm.php
<?php
namespace Drupal\google_tag\Form;
use Drupal\Component\Utility\Html;
use Drupal\Core\Condition\ConditionManager;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Url;
use Drupal\google_tag\Entity\TagContainer;
use Drupal\google_tag\GoogleTagEventManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the Google tag container settings form.
*
* @property \Drupal\google_tag\Entity\TagContainer $entity
*/
class TagContainerForm extends EntityForm {
// @todo move this into something pluggable.
use GoogleTagManagerSettingsTrait;
/**
* The condition plugin manager.
*
* @var \Drupal\Core\Condition\ConditionManager
*/
protected ConditionManager $conditionManager;
/**
* Context repository.
*
* @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
*/
protected ContextRepositoryInterface $contextRepository;
/**
* Google Tag Events Plugin Manager.
*
* @var \Drupal\google_tag\GoogleTagEventManager
*/
protected GoogleTagEventManager $tagEventManager;
/**
* The language manager service.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected LanguageManagerInterface $languageManager;
/**
* Constructs a ContainerForm object.
*
* @param \Drupal\Core\Condition\ConditionManager $condition_manager
* The ConditionManager for building the insertion conditions.
* @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
* Context repository.
* @param \Drupal\google_tag\GoogleTagEventManager $tag_event_manager
* Tag event manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* Language manager.
*/
public function __construct(ConditionManager $condition_manager, ContextRepositoryInterface $context_repository, GoogleTagEventManager $tag_event_manager, LanguageManagerInterface $language_manager) {
$this->conditionManager = $condition_manager;
$this->contextRepository = $context_repository;
$this->tagEventManager = $tag_event_manager;
$this->languageManager = $language_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new self(
$container->get('plugin.manager.condition'),
$container->get('context.repository'),
$container->get('plugin.manager.google_tag_event'),
$container->get('language_manager')
);
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);
// Store the gathered contexts in the form state for other objects to use
// during form building.
$form_state->setTemporaryValue('gathered_contexts', $this->contextRepository->getAvailableContexts());
$accounts_wrapper_id = Html::getUniqueId('accounts-add-more-wrapper');
$form['accounts_wrapper'] = [
'#type' => 'fieldset',
'#title' => $this->t('Google Tag ID(s)'),
'#prefix' => '<div id="' . $accounts_wrapper_id . '">',
'#description' => $this->t('This ID is unique to each site you want to track separately, and is in the form of UA-xxxxx-yy, G-xxxxxxxx, AW-xxxxxxxxx, or DC-xxxxxxxx. To get a Web Property ID, <a href=":analytics">register your site with Google Analytics</a>, or if you already have registered your site, go to your Google Analytics Settings page to see the ID next to every site profile. <a href=":webpropertyid">Find more information in the documentation</a>.', [
':analytics' => 'https://marketingplatform.google.com/about/analytics/',
':webpropertyid' => Url::fromUri('https://developers.google.com/analytics/resources/concepts/gaConceptsAccounts', ['fragment' => 'webProperty'])->toString(),
]),
'#suffix' => '</div>',
];
// Filter order (tabledrag).
$form['accounts_wrapper']['accounts'] = [
'#input' => FALSE,
'#tree' => TRUE,
'#type' => 'table',
'#tabledrag' => [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => 'account-order-weight',
],
],
];
$accounts = $form_state->getValue('accounts', []);
if ($accounts === []) {
$entity_accounts = $this->entity->get('tag_container_ids');
foreach ($entity_accounts as $index => $account) {
$accounts[$index]['value'] = $account;
$accounts[$index]['weight'] = $index;
}
// Default fallback.
if (count($accounts) === 0) {
$accounts[] = ['value' => '', 'weight' => 0];
}
}
foreach ($accounts as $index => $account) {
$form['accounts_wrapper']['accounts'][$index]['#attributes']['class'][] = 'draggable';
$form['accounts_wrapper']['accounts'][$index]['#weight'] = $account['weight'];
$form['accounts_wrapper']['accounts'][$index]['value'] = [
'#default_value' => (string) ($account['value'] ?? ''),
'#maxlength' => 20,
'#required' => (count($accounts) === 1),
'#size' => 20,
'#type' => 'textfield',
'#pattern' => TagContainer::GOOGLE_TAG_MATCH,
'#ajax' => [
'callback' => [self::class, 'storeGtagAccountsCallback'],
'disable-refocus' => TRUE,
'event' => 'change',
'wrapper' => 'advanced-settings-wrapper',
],
'#attributes' => [
'data-disable-refocus' => 'true',
],
];
$form['accounts_wrapper']['accounts'][$index]['weight'] = [
'#type' => 'weight',
'#title' => $this->t('Weight for @title', ['@title' => (string) ($account['value'] ?? '')]),
'#title_display' => 'invisible',
'#delta' => 50,
'#default_value' => $index,
'#parents' => ['accounts', $index, 'weight'],
'#attributes' => ['class' => ['account-order-weight']],
];
// If there is more than one id, add the remove button.
if (count($accounts) > 1) {
$form['accounts_wrapper']['accounts'][$index]['remove'] = [
'#type' => 'submit',
'#value' => $this->t('Remove'),
'#name' => 'remove_gtag_id_' . $index,
'#parameter_index' => $index,
'#limit_validation_errors' => [
['accounts'],
],
'#submit' => [
[self::class, 'removeGtagCallback'],
],
'#ajax' => [
'callback' => [self::class, 'gtagFormCallback'],
'wrapper' => $form['#id'],
],
];
}
}
$id_prefix = implode('-', ['accounts_wrapper', 'accounts']);
// Add blank account.
$form['accounts_wrapper']['add_gtag_id'] = [
'#type' => 'submit',
'#value' => $this->t('Add another ID'),
'#name' => str_replace('-', '_', $id_prefix) . '_add_gtag_id',
'#submit' => [
[self::class, 'addGtagCallback'],
],
'#ajax' => [
'callback' => [self::class, 'ajaxRefreshAccounts'],
'wrapper' => $accounts_wrapper_id,
'effect' => 'fade',
],
];
$dimensions_metrics_wrapper_id = Html::getUniqueId('metrics-dimensions-add-more-wrapper');
$form['dimensions_metrics_wrapper'] = [
'#type' => 'fieldset',
'#title' => $this->t('Custom dimensions and metrics'),
'#prefix' => '<div id="' . $dimensions_metrics_wrapper_id . '">',
'#suffix' => '</div>',
];
$form['dimensions_metrics_wrapper']['dimensions_metrics'] = [
'#input' => FALSE,
'#tree' => TRUE,
'#type' => 'table',
'#header' => [
['data' => $this->t('Type')],
['data' => $this->t('Name')],
['data' => $this->t('Value')],
['data' => $this->t('Remove')],
],
'#empty' => $this->t('No custom dimensions or metrics added.'),
'#rows' => [],
];
$token_exists = $this->moduleHandler->moduleExists('token');
$dimensions_metrics = $form_state->getValue('dimensions_metrics', $this->entity->getDimensionsAndMetrics());
foreach ($dimensions_metrics as $index => $item) {
$form['dimensions_metrics_wrapper']['dimensions_metrics'][$index]['type'] = [
'#type' => 'select',
'#title' => $this->t('Type for parameter #@index', ['@index' => $index]),
'#title_display' => 'invisible',
'#options' => [
'dimension' => $this->t('Dimension'),
'metric' => $this->t('Metric'),
],
'#default_value' => $item['type'],
'#disabled' => TRUE,
];
$form['dimensions_metrics_wrapper']['dimensions_metrics'][$index]['name'] = [
'#type' => 'textfield',
'#title' => $this->t('Name for parameter #@index', ['@index' => $index]),
'#title_display' => 'invisible',
'#maxlength' => 255,
'#default_value' => $item['name'],
];
$form['dimensions_metrics_wrapper']['dimensions_metrics'][$index]['value'] = [
'#type' => 'textfield',
'#title' => $this->t('Value for parameter #@index', ['@index' => $index]),
'#title_display' => 'invisible',
'#maxlength' => 255,
'#default_value' => $item['value'],
];
if ($token_exists) {
$form['dimensions_metrics_wrapper']['dimensions_metrics'][$index]['value']['#element_validate'] = [
'token_element_validate',
];
}
$form['dimensions_metrics_wrapper']['dimensions_metrics'][$index]['remove'] = [
'#type' => 'submit',
'#value' => $this->t('Remove'),
'#name' => 'remove_parameter' . $index,
'#parameter_index' => $index,
'#limit_validation_errors' => [
['dimensions_metrics'],
],
'#submit' => [
[self::class, 'removeDimensionMetric'],
],
'#ajax' => [
'callback' => [self::class, 'ajaxRefreshMetricsDimensions'],
'wrapper' => $dimensions_metrics_wrapper_id,
],
];
}
$form['dimensions_metrics_wrapper']['new_dimensions_metrics'] = [
'#type' => 'container',
'#attributes' => [
'class' => ['container-inline'],
],
'new_metric_dimension_type' => [
'#type' => 'select',
'#options' => [
'dimension' => $this->t('Dimension'),
'metric' => $this->t('Metric'),
],
'#title' => $this->t('New parameter type'),
'#title_display' => 'invisible',
'#empty_option' => t('- Select -'),
'#empty_value' => '',
],
'new_metric_dimension_submit' => [
'#type' => 'submit',
'#value' => $this->t('Add new parameter'),
'#submit' => [
[self::class, 'addNewDimensionMetric'],
],
'#ajax' => [
'callback' => [self::class, 'ajaxRefreshMetricsDimensions'],
'wrapper' => $dimensions_metrics_wrapper_id,
],
],
];
if ($token_exists) {
$form['dimensions_metrics_wrapper']['token_tree'] = [
'#theme' => 'token_tree_link',
'#token_types' => ['node'],
];
}
$form['events_settings'] = $this->getEventSettings([], $form_state);
$form['conditions'] = $this->conditionsForm([], $form_state);
$form['advanced_settings'] = $this->getAdvancedSettings([], $form_state, $accounts);
$form['status'] = [
'#type' => 'checkbox',
'#title' => 'Enabled',
'#default_value' => $this->entity->status(),
'#description' => 'Check this checkbox to enable Tag Container.',
];
return $form;
}
/**
* Builds form elements for event plugin configuration.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The augmented form array with the insertion condition elements.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
protected function getEventSettings(array $form, FormStateInterface $form_state) {
$form['#tree'] = TRUE;
$form['events_tabs'] = [
'#type' => 'vertical_tabs',
'#title' => $this->t('Events'),
'#description' => $this->t('Events which will be sent to GA.'),
'#description_display' => 'before',
'#parents' => ['events_tabs'],
];
$events = $this->entity->get('events');
$event_definitions = $this->tagEventManager->getDefinitions();
foreach ($event_definitions as $event_id => $definition) {
$event_config = $events[$event_id] ?? [];
$event_plugin = $this->tagEventManager->createInstance($event_id, $event_config);
$form[$event_id] = [
'#type' => 'details',
'#title' => $definition['label'],
'#group' => 'events_tabs',
];
$form[$event_id]['enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable event :label', [':label' => $definition['label']]),
'#default_value' => isset($events[$event_id]) || $this->entity->isNew(),
'#parameter_index' => $event_id,
];
if ($event_plugin instanceof PluginFormInterface) {
$form_state->set(['events', $event_id], $event_plugin);
$form[$event_id]['event_form'] = $event_plugin->buildConfigurationForm([], $form_state);
$form[$event_id]['event_form']['#type'] = 'fieldset';
$selector = 'events_settings[' . $event_id . '][enabled]';
$states = [
'visible' => [
':input[name="' . $selector . '"]' => ['checked' => TRUE],
],
];
$form[$event_id]['event_form']['#states'] = $states;
}
}
return $form;
}
/**
* Builds the form elements for the insertion conditions.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The augmented form array with the insertion condition elements.
*/
protected function conditionsForm(array $form, FormStateInterface $form_state): array {
$form['#tree'] = TRUE;
$form['condition_tabs'] = [
'#type' => 'vertical_tabs',
'#title' => $this->t('Conditions'),
'#description' => $this->t('Conditions in which the tag will be processed on a request.'),
'#description_display' => 'before',
'#parents' => ['condition_tabs'],
];
/** @var array<string, array<string, mixed>> $conditions */
$conditions = $this->entity->get('conditions');
$definitions = $this->conditionManager->getFilteredDefinitions(
'google_tag',
$form_state->getTemporaryValue('gathered_contexts')
);
foreach (array_keys($definitions) as $condition_id) {
// Don't display the current theme condition.
if ($condition_id === 'current_theme') {
continue;
}
// Don't display the language condition until we have multiple languages.
if ($condition_id === 'language' && !$this->languageManager->isMultilingual()) {
continue;
}
/** @var \Drupal\Core\Condition\ConditionInterface $condition */
$condition = $this->conditionManager->createInstance($condition_id, $conditions[$condition_id] ?? []);
$form_state->set(['conditions', $condition_id], $condition);
$condition_form = $condition->buildConfigurationForm([], $form_state);
$condition_form['#type'] = 'details';
$condition_form['#title'] = $condition->getPluginDefinition()['label'];
$condition_form['#group'] = 'condition_tabs';
$form[$condition_id] = $condition_form;
}
return $form;
}
/**
* Builds form elements for advanced settings configuration.
*
* Currently, only Google Tag Manager has advanced settings. However, this
* form could be used to add Google Tag / GA / etc options as well.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $accounts
* A keyed array containing the all the gtag accounts for the container.
*
* @return array
* The augmented form array with the insertion condition elements.
*/
protected function getAdvancedSettings(array $form, FormStateInterface $form_state, array $accounts) {
// Advanced Settings. These are specific settings per ID.
$advanced_settings = [
'#type' => 'fieldset',
'#title' => $this->t('Advanced settings'),
'#description' => $this->t('The settings affecting the snippet contents for this container.'),
'#attributes' => ['class' => ['google-tag']],
'#prefix' => '<div id="advanced-settings-wrapper">',
'#suffix' => '</div>',
'#open' => FALSE,
'#tree' => TRUE,
];
// Allow disabling of consent options when using non Ads tags.
$advanced_settings['consent_mode'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enforce Privacy Consent Policy'),
'#description' => $this->t("In certain countries and for certain tags (Ads), user consent is required before sending any data. Please review this <a href='https://www.google.com/about/company/user-consent-policy-help/'>Google FAQ</a> before disabling."),
'#default_value' => !empty($this->entity->get('advanced_settings')['consent_mode']),
];
// Only show Advanced GTM settings if one of the IDs belong to GTM.
$gtm_ids = array_slice(
array_filter(
$accounts,
static fn ($id) => preg_match(TagContainer::GOOGLE_TAG_MANAGER_MATCH, $id['value'])
),
0);
// Add processing / ajax input and append it to the form.
foreach ($gtm_ids as $gtm_id) {
$advanced_settings_data = $this->entity->getGtmSettings($gtm_id['value']);
$advanced_settings['gtm'][$gtm_id['value']] = $this->gtmAdvancedFieldset($advanced_settings_data, $gtm_id['value']);
}
return $advanced_settings;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$this->validateGtmFormValues($form, $form_state);
$this->validateConditionsForm($form, $form_state);
$this->buildEntity($form, $form_state);
$this->validateEventsForm($form, $form_state);
}
/**
* Form validation handler for the event plugins.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
protected function validateEventsForm(array $form, FormStateInterface $form_state) {
$events = $form_state->getValue('events_settings');
$events = array_filter($events, static function (array $event) {
return (int) $event['enabled'] === 1;
});
foreach (array_keys($events) as $event_id) {
/** @var \Drupal\Core\Plugin\PluginFormInterface $configurable_event */
if ($configurable_event = $form_state->get(['events', $event_id])) {
$configurable_event->validateConfigurationForm($form['events_settings'][$event_id]['event_form'], SubformState::createForSubform($form['events_settings'][$event_id]['event_form'], $form, $form_state));
}
}
}
/**
* Form submission handler for the event plugins.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
protected function submitEventsForm(array $form, FormStateInterface $form_state) {
$events = $form_state->getValue('events_settings');
$events = array_filter($events, static function (array $event) {
return (int) $event['enabled'] === 1;
});
$event_data = [];
foreach (array_keys($events) as $event_id) {
if ($event_plugin = $form_state->get(['events', $event_id])) {
$event_plugin->submitConfigurationForm($form['events_settings'][$event_id]['event_form'], SubformState::createForSubform($form['events_settings'][$event_id]['event_form'], $form, $form_state));
}
else {
/** @var \Drupal\google_tag\Plugin\GoogleTag\Event\GoogleTagEventInterface $event_plugin */
$event_plugin = $this->tagEventManager->createInstance($event_id);
}
$event_data[$event_id] = $event_plugin->getConfiguration();
}
$this->entity->set('events', $event_data);
}
/**
* Form validation handler for the insertion conditions.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
protected function validateConditionsForm(array $form, FormStateInterface $form_state) {
// Validate visibility condition settings.
foreach ($form_state->getValue('conditions') as $condition_id => $values) {
// All condition plugins use 'negate' as a Boolean in their schema.
// However, certain form elements may return it as 0/1. Cast here to
// ensure the data is in the expected type.
if (array_key_exists('negate', $values)) {
$form_state->setValue(['conditions', $condition_id, 'negate'], (bool) $values['negate']);
}
/** @var \Drupal\Core\Condition\ConditionInterface $condition */
$condition = $form_state->get(['conditions', $condition_id]);
$condition->validateConfigurationForm($form['conditions'][$condition_id], SubformState::createForSubform($form['conditions'][$condition_id], $form, $form_state));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$default_id = '';
// No need to fetch again from entity,
// ids should already be available in form state values now.
$tag_container_ids = [];
foreach ($form_state->getValue('accounts') as $account) {
if (!$default_id) {
$default_id = $account['value'];
}
$tag_container_ids[$account['weight']] = $account['value'];
}
// Need to save tags without weights otherwise it doesn't show up on UI.
$this->entity->set('tag_container_ids', array_values($tag_container_ids));
if ($this->entity->id() === NULL) {
// Set the ID and Label based on the first Google Tag.
$config_id = uniqid($default_id . '.', TRUE);
$this->entity->setOriginalId($config_id);
$this->entity->set('id', $config_id);
$this->entity->set('label', $default_id);
}
$this->submitConditionsForm($form, $form_state);
$this->submitEventsForm($form, $form_state);
// Save config entity a first time so that the conditions form can be
// properly filtered.
// @see https://www.drupal.org/project/google_tag/issues/3345719#comment-15009415
// @see BlockForm::submitForm()
// The fix on https://www.drupal.org/project/google_tag/issues/3357105
// may not be necessary, but as BlockForm::submitForm() is still
// doing we are leaving it for now.
$this->entity->save();
$this->messenger()->addStatus($this->t('The configuration options have been saved.'));
// Redirect to collection page.
$form_state->setRedirect('entity.google_tag_container.single_form');
}
/**
* {@inheritDoc}
*/
public function save(array $form, FormStateInterface $form_state) {
$result = parent::save($form, $form_state);
// Store the resulting entity ID in the global Google tag settings.
$config = $this->configFactory()->getEditable('google_tag.settings');
$config->set('default_google_tag_entity', $this->entity->id())->save();
return $result;
}
/**
* Form submission handler for the insertion conditions.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
protected function submitConditionsForm(array $form, FormStateInterface $form_state) {
foreach ($form_state->getValue('conditions') as $condition_id => $values) {
/** @var \Drupal\Core\Condition\ConditionInterface $condition */
$condition = $form_state->get(['conditions', $condition_id]);
$condition->submitConfigurationForm($form['conditions'][$condition_id], SubformState::createForSubform($form['conditions'][$condition_id], $form, $form_state));
$configuration = $condition->getConfiguration();
// Due to strict type checking, cast negation to a boolean.
$configuration['negate'] = (bool) (array_key_exists('negate', $configuration) ? $configuration['negate'] : FALSE);
// Update the insertion conditions on the container.
$this->entity->getInsertionConditions()->addInstanceId($condition_id, $configuration);
}
}
/**
* Callback for both ajax account buttons.
*
* Selects and returns the fieldset with the names in it.
*/
public static function gtagFormCallback(array &$form, FormStateInterface $form_state) {
return $form;
}
/**
* Submit handler for the "remove one" button.
*
* Decrements the max counter and causes a form rebuild.
*/
public static function removeGtagCallback(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$index = $triggering_element['#parameter_index'];
$accounts = $form_state->getValue('accounts', []);
unset($accounts[$index]);
$form_state->setValue('accounts', $accounts);
$form_state->setRebuild();
}
/**
* Submit handler for the "add-one-more" button.
*
* Increments the max counter and causes a rebuild.
*/
public static function addGtagCallback(array &$form, FormStateInterface $form_state) {
$accounts = $form_state->getValue('accounts', []);
$accounts[] = [
'value' => '',
'weight' => count($accounts),
];
$form_state->setValue('accounts', $accounts);
$form_state->setRebuild();
}
/**
* Submit handler for the "add-one-more" button.
*
* Increments the max counter and causes a rebuild.
*/
public static function storeGtagAccountsCallback(array &$form, FormStateInterface $form_state) {
// Update Advanced Settings Form.
return $form['advanced_settings'];
}
/**
* Ajax handler for removing dimension metric.
*
* @param array $form
* Form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*/
public static function removeDimensionMetric(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
$index = $triggering_element['#parameter_index'];
$dimensions_metrics = $form_state->getValue('dimensions_metrics', []);
unset($dimensions_metrics[$index]);
$form_state->setValue('dimensions_metrics', $dimensions_metrics);
$form_state->setRebuild();
}
/**
* Ajax handler for adding dimension metric.
*
* @param array $form
* Form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*/
public static function addNewDimensionMetric(array $form, FormStateInterface $form_state) {
$dimensions_metrics = $form_state->getValue('dimensions_metrics', []);
$dimensions_metrics[] = [
'type' => $form_state->getValue('new_metric_dimension_type'),
'name' => '',
'value' => '',
];
$form_state->setValue('dimensions_metrics', $dimensions_metrics);
$form_state->setRebuild();
}
/**
* Ajax handler for refreshing the form metrics wrapper after metrics change.
*
* @param array $form
* Form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*
* @return mixed
* Metrics wrapper.
*/
public static function ajaxRefreshMetricsDimensions(array $form, FormStateInterface $form_state) {
return $form['dimensions_metrics_wrapper'];
}
/**
* Callback for add more gtag accounts.
*
* @param array $form
* Form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state.
*
* @return mixed
* Accounts wrapper.
*/
public static function ajaxRefreshAccounts(array $form, FormStateInterface $form_state) {
return $form['accounts_wrapper'];
}
}
