View source
<?php
namespace Drupal\google_tag\Form;
use Drupal\Core\Form\FormStateInterface;
trait ContainerTrait {
protected $container;
protected $prefix;
public function advancedFieldset(FormStateInterface &$form_state) {
$container = $this->container;
$fieldset = [
'#type' => 'details',
'#title' => $this
->t('Advanced'),
'#group' => 'settings',
];
$fieldset['data_layer'] = [
'#type' => 'textfield',
'#title' => $this
->t('Data layer'),
'#description' => $this
->t('The name of the data layer. Default value is "dataLayer". In most cases, use the default.'),
'#default_value' => $container
->get("{$this->prefix}data_layer"),
'#attributes' => [
'placeholder' => [
'dataLayer',
],
],
'#required' => TRUE,
];
$fieldset['include_classes'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Add classes to the data layer'),
'#description' => $this
->t('If checked, then the listed classes will be added to the data layer.'),
'#default_value' => $container
->get("{$this->prefix}include_classes"),
];
$description = $this
->t('The types of tags, triggers, and variables <strong>allowed</strong> on a page. Enter one class per line. For more information, refer to the <a href="https://developers.google.com/tag-manager/devguide#security">developer documentation</a>.');
$fieldset['whitelist_classes'] = [
'#type' => 'textarea',
'#title' => $this
->t('White-listed classes'),
'#description' => $description,
'#default_value' => $container
->get("{$this->prefix}whitelist_classes"),
'#rows' => 5,
'#states' => $this
->statesArray('include_classes'),
];
$fieldset['blacklist_classes'] = [
'#type' => 'textarea',
'#title' => $this
->t('Black-listed classes'),
'#description' => $this
->t('The types of tags, triggers, and variables <strong>forbidden</strong> on a page. Enter one class per line.'),
'#default_value' => $container
->get("{$this->prefix}blacklist_classes"),
'#rows' => 5,
'#states' => $this
->statesArray('include_classes'),
];
$fieldset['include_environment'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Include an environment'),
'#description' => $this
->t('If checked, then the applicable snippets will include the environment items below. Enable <strong>only for development</strong> purposes.'),
'#default_value' => $container
->get("{$this->prefix}include_environment"),
];
$description = $this
->t('The environment ID to use with this website container. To get an environment ID, <a href="https://tagmanager.google.com/#/admin">select Environments</a>, create an environment, then click the "Get Snippet" action. The environment ID and token will be in the snippet.');
$fieldset['environment_id'] = [
'#type' => 'textfield',
'#title' => $this
->t('Environment ID'),
'#description' => $description,
'#default_value' => $container
->get("{$this->prefix}environment_id"),
'#attributes' => [
'placeholder' => [
'env-x',
],
],
'#size' => 10,
'#maxlength' => 7,
'#states' => $this
->statesArray('include_environment'),
];
$fieldset['environment_token'] = [
'#type' => 'textfield',
'#title' => $this
->t('Environment token'),
'#description' => $this
->t('The authentication token for this environment.'),
'#default_value' => $container
->get("{$this->prefix}environment_token"),
'#attributes' => [
'placeholder' => [
'xxxxxxxxxxxxxxxxxxxxxx',
],
],
'#size' => 20,
'#maxlength' => 25,
'#states' => $this
->statesArray('include_environment'),
];
return $fieldset;
}
public function statesArray($variable) {
return [
'required' => [
':input[name="' . $variable . '"]' => [
'checked' => TRUE,
],
],
'invisible' => [
':input[name="' . $variable . '"]' => [
'checked' => FALSE,
],
],
];
}
public function pathFieldset(FormStateInterface &$form_state) {
$fieldset_title = $this
->t('Request path');
$fieldset_description = $this
->t('On this and the following tabs, specify the conditions on which the GTM JavaScript snippet will either be inserted on or omitted from the page response, thereby enabling or disabling tracking and other analytics. All conditions must be satisfied for the snippet to be inserted. The snippet will be omitted if any condition is not met.');
$args = [
'%node' => '/node',
'%user-wildcard' => '/user/*',
'%front' => '<front>',
];
$description = $this
->t('Enter one relative path per line using the "*" character as a wildcard. Example paths are: "%node" for the node page, "%user-wildcard" for each individual user, and "%front" for the front page.', $args);
$rows = 10;
$singular = 'path';
$plural = 'paths';
$adjective = 'listed';
$config = compact([
'fieldset_title',
'fieldset_description',
'singular',
'plural',
'adjective',
'description',
'rows',
]);
return $this
->genericFieldset($config, $form_state);
}
public function roleFieldset(FormStateInterface &$form_state) {
$fieldset_title = $this
->t('User role');
$singular = 'role';
$plural = 'roles';
$options = array_map(function ($role) {
return $role
->label();
}, user_roles());
$config = compact([
'fieldset_title',
'singular',
'plural',
'options',
]);
return $this
->genericFieldset($config, $form_state);
}
public function statusFieldset(FormStateInterface &$form_state) {
$fieldset_title = $this
->t('Response status');
$description = $this
->t('Enter one response status per line. For more information, refer to the <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">list of HTTP status codes</a>.');
$rows = 5;
$singular = 'status';
$plural = 'statuses';
$adjective = 'listed';
$config = compact([
'fieldset_title',
'singular',
'plural',
'adjective',
'description',
'rows',
]);
return $this
->genericFieldset($config, $form_state);
}
public function genericFieldset(array $config, FormStateInterface &$form_state) {
$container = $this->container;
$config += [
'fieldset_description' => '',
'adjective' => 'selected',
];
extract($config);
$toggle = "{$singular}_toggle";
$list = "{$singular}_list";
$args = [
'@adjective' => $adjective,
'@uc_adjective' => ucfirst($adjective),
'@plural' => $plural,
];
$fieldset = [
'#type' => 'details',
'#title' => $fieldset_title,
'#description' => $fieldset_description,
'#group' => 'conditions',
];
$fieldset[$toggle] = [
'#type' => 'radios',
'#title' => $this
->specialT('Insert snippet for specific @plural', $args),
'#options' => [
GOOGLE_TAG_EXCLUDE_LISTED => $this
->specialT('All @plural except the @adjective @plural', $args),
GOOGLE_TAG_INCLUDE_LISTED => $this
->specialT('Only the @adjective @plural', $args),
],
'#default_value' => $container
->get("{$this->prefix}{$toggle}"),
];
if ($adjective == 'selected') {
$fieldset[$list] = [
'#type' => 'checkboxes',
'#title' => $this
->specialT('@uc_adjective @plural', $args),
'#options' => $options,
'#default_value' => $container
->get("{$this->prefix}{$list}"),
];
}
else {
$fieldset[$list] = [
'#type' => 'textarea',
'#title' => $this
->specialT('@uc_adjective @plural', $args),
'#description' => $description,
'#default_value' => $container
->get("{$this->prefix}{$list}"),
'#rows' => $rows,
];
}
return $fieldset;
}
protected function specialT($string, array $args) {
return $this
->t(strtr($string, $args));
}
public function validateFormValues(array &$form, FormStateInterface $form_state) {
$container_id = $form_state
->getValue('container_id');
if (!is_null($container_id)) {
$container_id = trim($container_id);
$container_id = str_replace([
'–',
'—',
'−',
], '-', $container_id);
$form_state
->setValue('container_id', $container_id);
if (!preg_match('/^GTM-\\w{4,}$/', $container_id)) {
$form_state
->setError($form['general']['container_id'], $this
->t('A valid container ID is case sensitive and formatted like GTM-xxxxxx.'));
}
}
$uri = $form_state
->getValue('uri');
if (!is_null($uri) && $form['#form_id'] == 'google_tag_settings') {
$uri = trim($uri);
$form_state
->setValue('uri', $uri);
$directory = $uri;
if (substr($directory, -3) == '://') {
$args = [
'%directory' => $directory,
];
$message = 'The snippet parent uri %directory is invalid. Enter a single trailing slash to specify a plain stream wrapper.';
$form_state
->setError($form['module']['uri'], $this
->t($message, $args));
}
$directory .= substr($directory, -2) == ':/' ? '/' : '';
if (!is_dir($directory) || !_google_tag_is_writable($directory) || !_google_tag_is_executable($directory)) {
$args = [
'%directory' => $directory,
];
$message = 'The snippet parent uri %directory is invalid, possibly due to file system permissions. The directory either does not exist, or is not writable or searchable.';
$form_state
->setError($form['module']['uri'], $this
->t($message, $args));
}
}
$environment_id = trim($form_state
->getValue('environment_id'));
$form_state
->setValue('data_layer', trim($form_state
->getValue('data_layer')));
$form_state
->setValue('path_list', $this
->cleanText($form_state
->getValue('path_list')));
$form_state
->setValue('status_list', $this
->cleanText($form_state
->getValue('status_list')));
$form_state
->setValue('whitelist_classes', $this
->cleanText($form_state
->getValue('whitelist_classes')));
$form_state
->setValue('blacklist_classes', $this
->cleanText($form_state
->getValue('blacklist_classes')));
$environment_id = str_replace([
'–',
'—',
'−',
], '-', $environment_id);
$form_state
->setValue('environment_id', $environment_id);
$form_state
->setValue('role_list', array_filter($form_state
->getValue('role_list')));
if ($form_state
->getValue('include_environment') && !preg_match('/^env-\\d{1,}$/', $environment_id)) {
$form_state
->setError($form['advanced']['environment_id'], $this
->t('A valid environment ID is case sensitive and formatted like env-x.'));
}
}
public function cleanText($text, $format = 'string') {
$text = explode("\n", $text);
$text = array_map('trim', $text);
$text = array_filter($text, 'trim');
if ($format == 'string') {
$text = implode("\n", $text);
}
return $text;
}
}