Version 1
[yaffs-website] / web / modules / contrib / environment_indicator / environment_indicator.module
diff --git a/web/modules/contrib/environment_indicator/environment_indicator.module b/web/modules/contrib/environment_indicator/environment_indicator.module
new file mode 100644 (file)
index 0000000..8c189c6
--- /dev/null
@@ -0,0 +1,338 @@
+<?php
+
+/**
+ * @file
+ * Module implementation file.
+ */
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Url;
+use Drupal\environment_indicator\Entity\EnvironmentIndicator;
+
+/**
+ * Implements hook_help().
+ */
+function environment_indicator_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    case 'environment_indicator.settings':
+      $output = '<p>' . t('The Environment Indicator adds a coloured strip to the site informing you which environment you are currently in (Development, Staging, Production, etc.)') . '</p>';
+      $output .= '<p>' . t('The Environment Indicator\'s visibility depends upon the permissions of the viewer. The <a href="@permissions">access environment indicator</a> permission must be enabled for a user role in order for users of that role to see the indicator.', [
+          '@permissions' => Url::fromRoute('user.admin_permissions', [], ['fragment' => 'module-environment_indicator'])
+            ->toString(),
+        ]) . '</p>';
+      $output .= '<p>'. t('The recommended way to add information about your release is to set the \'environment_indicator.current_release\' state. Use your git hooks to set the state using drush: <code>drush sset environment_indicator.current_release v1.2.44</code>') .'</p>';
+      return $output;
+
+    case 'entity.environment_indicator.collection':
+      $output = '<p>' . t('The environment indicator switcher allows you to create a menu to switch between your environments easily.') . '</p>';
+      $output .= '<p>' . t('You will need to declare all the environments you want to switch. It is advisable that you set your environments in the switcher with the same colors that you use in every environment\'s settings.php.') . '</p>';
+      return $output;
+
+    case 'help.page.environment_indicator':
+      $output = '<p>' . t('The Environment Indicator adds a coloured strip to the site informing you which environment you are currently in (Development, Staging, Production, etc.') . '</p>';
+      $output .= '<p>' . t('The Environment Indicator <a href="@settings">settings page</a> allows you to modify some elements of the indicator\'s behavior and appearance. Since the appearance of the indicator is dependent on your site theme, substantial customisations require modifications to your site\'s theme and CSS files.', ['@settings' => Url::fromRoute('environment_indicator.settings')]) . '</p>';
+      $output .= '<p>' . t('The Environment Indicator\'s visibility depends upon the permissions of the viewer. The <a href="@permissions">access environment indicator</a> permission must be enabled for a user role in order for users of that role to see the indicator.', ['@permissions' => Url::fromRoute('user.admin_permissions', [], ['fragment' => 'module-environment_indicator'])]) . '</p>';
+      $output .= '<p>' . t('Modify the "environment_indicator.indicator" configuration object to control how the environment indicator is presented:') . '</p>';
+      $output .= '<dl>';
+      $output .= '<dt><em>$config[\'environment_indicator.indicator\'][\'bg_color\']</em></dt><dd>' . t('A valid CSS color for the background of the indicator.') . '<br/>$config[\'environment_indicator.indicator\'][\'bg_color\'];<br /></dd></dt>';
+      $output .= '<dt><em>$config[\'environment_indicator.indicator\'][\'fg_color\']</em></dt><dd>' . t('A valid CSS color for the text of the indicator.') . '<br/>$config[\'environment_indicator.indicator\'][\'fg_color\'] = \'#555533\';<br /></dd></dt>';
+      $output .= '<dt><em>$config[\'environment_indicator.indicator\'][\'name\']</em></dt><dd>' . t('The text that will be displayed on the indicator.') . '<br/>$config[\'environment_indicator.indicator\'][\'name\'] = \'Staging\';<br /></dd></dt>';
+      $output .= '</dl>';
+      $output .= '<p>'. t('The recommended way to add information about your release is to set the \'environment_indicator.current_release\' state. Use your git hooks to set the state using drush: <code>drush sset environment_indicator.current_release v1.2.44</code>') .'</p>';
+
+      return $output;
+  }
+
+  return NULL;
+}
+
+/**
+ * Implements hook_page_top().
+ */
+function environment_indicator_page_top(array &$page_top) {
+  if (_environment_indicator_external_integration_is_enabled('toolbar')) {
+    return;
+  }
+  $active_environment = \Drupal::config('environment_indicator.indicator');
+  $page_top['indicator'] = [
+    '#type' => 'environment_indicator',
+    '#title' => $active_environment->get('name'),
+    '#fg_color' => $active_environment->get('fg_color'),
+    '#bg_color' => $active_environment->get('bg_color'),
+    '#description' => \Drupal::state()->get('environment_indicator.current_release'),
+    '#access' => \Drupal::currentUser()
+      ->hasPermission('access environment indicator'),
+    '#attached' => [
+      'library' => ['environment_indicator/drupal.environment_indicator'],
+    ],
+  ];
+
+  // Only add the environment indicator switcher if there are environments to
+  // switch to.
+  if ($items = _environment_indicator_switcher_links()) {
+    $page_top['indicator']['switcher'] = [
+      '#theme' => 'links',
+      '#links' => $items,
+      '#attributes' => [
+        'class' => ['environment-switcher-container'],
+        'style' => 'border-top: 1px solid ' . \Drupal::config('environment_indicator.indicator')
+            ->get('fg_color'),
+      ],
+    ];
+    $page_top['indicator']['#attributes'] = [
+      'style' => 'cursor: pointer',
+      'title' => t('Show the environment switcher.'),
+    ];
+    $page_top['indicator'] += [
+      '#cache' => [
+        'tags' => Cache::mergeTags(['config:environment_indicator.settings'], _environment_indicator_switcher_cache_tags()),
+      ],
+    ];
+  }
+}
+
+/**
+ * Implements hook_theme().
+ */
+function environment_indicator_theme($existing, $type, $theme, $path) {
+  return [
+    'environment_indicator' => [
+      'render element' => 'element',
+    ],
+  ];
+}
+
+/**
+ * Prepares variables for environment indicator element templates.
+ *
+ * Default template: environment-indicator.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #title, #value, #description, #required, #attributes.
+ */
+function template_preprocess_environment_indicator(&$variables) {
+  $element = $variables['element'];
+  $variables['title'] = empty($element['#title']) ? '' : $element['#title'];
+  $variables['fg_color'] = empty($element['#fg_color']) ? '' : $element['#fg_color'];
+  if (!empty($element['#description'])) {
+    $variables['description'] = $element['#description'];
+  }
+  // Ensure #attributes is set.
+  $element += ['#attributes' => []];
+  $attributes = $element['#attributes'];
+  // Make sure to override existing colors.
+  $style = empty($attributes['style']) ? '' : $attributes['style'];
+  $structured_styles = _environment_indicator_parse_style($style);
+  $structured_styles['background-color'] = empty($element['#bg_color']) ? '' : $element['#bg_color'];
+  $structured_styles['color'] = empty($element['#fg_color']) ? '' : $element['#fg_color'];
+  // Now put everything back together as an string.
+  $data = [];
+  foreach ($structured_styles as $css_property => $css_value) {
+    $data[] = sprintf('%s: %s', $css_property, $css_value);
+  }
+  $attributes['style'] = implode('; ', $data);
+  $attributes['id'] = (empty($attributes['id']) ? (empty($attributes['#id']) ? 'environment-indicator' : $attributes['#id']) : $attributes['id']);
+  $variables['attributes'] = $attributes;
+  $variables['switcher'] = isset($element['switcher']) ? $element['switcher'] : '';
+}
+
+/**
+ * Helper function that takes a styles string and parses the individual items.
+ *
+ * @param string $style
+ *   The style string for the HTML element.
+ *
+ * @return array
+ *   An structured array with key value pairs with the CSS properties and their
+ *   values.
+ */
+function _environment_indicator_parse_style($style) {
+  $structured_styles = [];
+  // Get every individual style.
+  $styles = array_filter(explode(';', $style));
+  foreach ($styles as $item) {
+    list($item_name, $item_value) = explode(':', $item);
+    trim($item_name);
+    trim($item_value);
+    $structured_styles[$item_name] = $item_value;
+  }
+  return $structured_styles;
+}
+
+/**
+ * Implements hook_toolbar().
+ */
+function environment_indicator_toolbar() {
+  $active_environment = \Drupal::config('environment_indicator.indicator');
+  $permission = \Drupal::currentUser()
+    ->hasPermission('access environment indicator');
+  $items['environment_indicator'] = [
+    // Include the toolbar_tab_wrapper to style the link like a toolbar tab.
+    // Exclude the theme wrapper if custom styling is desired.
+    '#type' => 'toolbar_item',
+    '#access' => $permission,
+    '#cache' => [
+      'tags' => Cache::mergeTags(['config:environment_indicator.settings'], _environment_indicator_switcher_cache_tags()),
+    ],
+    '#weight' => 125,
+  ];
+  if (!_environment_indicator_external_integration_is_enabled('toolbar')) {
+    return $items;
+  }
+  $title = $active_environment->get('name');
+  $release_info = \Drupal::state()->get('environment_indicator.current_release');
+  $title = empty($release_info) ? $title : $title . ' (' . $release_info . ')';
+  $items['environment_indicator'] += [
+    'tab' => [
+      '#type' => 'link',
+      '#access' => $permission,
+      '#title' => $title,
+      '#url' => \Drupal\Core\Url::fromRoute('environment_indicator.settings'),
+      '#attributes' => [
+        'title' => t('Environments'),
+        'class' => [
+          'toolbar-icon',
+          'toolbar-item',
+          'toolbar-icon-environment',
+        ],
+      ],
+    ],
+    'tray' => [
+      '#heading' => t('Environment switcher'),
+      '#wrapper_attributes' => [],
+      '#access' => $permission,
+      'configure' => [
+        '#type' => 'link',
+        '#title' => t('Configure'),
+        '#url' => \Drupal\Core\Url::fromRoute('environment_indicator.settings'),
+        '#weight' => 100,
+        '#attributes' => [
+          'title' => t('Environment switcher configuration'),
+          'class' => ['edit-environments'],
+        ],
+      ],
+    ],
+    '#attached' => [
+      'library' => ['environment_indicator/drupal.environment_indicator'],
+      'drupalSettings' => [
+        'environmentIndicator' => [
+          'name' => $active_environment->get('name'),
+          'fgColor' => $active_environment->get('fg_color'),
+          'bgColor' => $active_environment->get('bg_color'),
+          'addFavicon' => \Drupal::config('environment_indicator.settings')
+            ->get('favicon'),
+        ],
+      ],
+    ],
+  ];
+
+  if ($links = _environment_indicator_switcher_toolbar_links()) {
+    $items['environment_indicator']['tray']['links'] = $links;
+  }
+  return $items;
+}
+
+/**
+ * Helper function to get the links for the toolbar.
+ *
+ * @return array
+ *   A renderable array for the toolbar tray.
+ */
+function _environment_indicator_switcher_toolbar_links() {
+  if (!$items = _environment_indicator_switcher_links()) {
+    return [];
+  };
+  $menu = [
+    '#theme' => 'links__toolbar_shortcuts',
+    '#links' => $items,
+    '#attributes' => [
+      'class' => ['toolbar-menu'],
+    ],
+  ];
+  return $menu;
+}
+
+/**
+ * Helper function that generates the environment switcher links.
+ *
+ * @return array
+ *   A renderable array with the links.
+ */
+function _environment_indicator_switcher_links() {
+  if (!$environment_entities = EnvironmentIndicator::loadMultiple()) {
+    return [];
+  }
+  $current = \Drupal\Core\Url::fromRoute('<current>');
+  $current_path = $current->toString();
+  return array_map(function (EnvironmentIndicator $entity) use ($current_path) {
+    return [
+      'attributes' => [
+        'style' => 'color: ' . $entity->getFgColor() . '; background-color: ' . $entity->getBgColor() . ';',
+        'title' => t('Opens the current page in the selected environment.'),
+      ],
+      'title' => t('Open in: @label', ['@label' => $entity->label()]),
+      'url' => \Drupal\Core\Url::fromUri($entity->getUrl() . $current_path),
+      'type' => 'link',
+    ];
+  }, $environment_entities);
+}
+
+/**
+ * Helper function that checks if there is external integration.
+ *
+ * @param string $integration
+ *   Name of the integration: toolbar, admin_menu, ...
+ *
+ * @return bool
+ *   TRUE if integration is enabled. FALSE otherwise.
+ */
+function _environment_indicator_external_integration_is_enabled($integration) {
+  if ($integration == 'toolbar') {
+    $access = \Drupal::moduleHandler()->moduleExists('toolbar');
+    $access = $access && in_array('toolbar', \Drupal::config('environment_indicator.settings')
+        ->get('toolbar_integration'));
+    $access = $access && \Drupal::currentUser()
+        ->hasPermission('access toolbar');
+    return $access;
+  }
+  return FALSE;
+}
+
+/**
+ * Get the cache tags for the environment indicator switcher.
+ *
+ * @return string[]
+ *   The cache tags.
+ */
+function _environment_indicator_switcher_cache_tags() {
+  /* @var EnvironmentIndicator[] $environment_entities */
+  if (!$environment_entities = EnvironmentIndicator::loadMultiple()) {
+    return [];
+  }
+
+  $cache_tags = [];
+  foreach ($environment_entities as $entity) {
+    $cache_tags = Cache::mergeTags($cache_tags, $entity->getCacheTags());
+  }
+
+  return $cache_tags;
+}
+
+/**
+ * Loads an environment indicator in a procedural way.
+ *
+ * @param string $environment_id
+ *   The entity ID.
+ *
+ * @return EntityInterface|null
+ *   The loaded entity or null otherwise.
+ */
+function environment_indicator_load($environment_id) {
+  return \Drupal::entityTypeManager()
+    ->getStorage('environment_indicator')
+    ->load($environment_id);
+}