sitewide_alerts-1.0.0/src/SiteAlertService.php

src/SiteAlertService.php
<?php

namespace Drupal\sitewide_alerts;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheFactoryInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Routing\AdminContext;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\State\State;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\taxonomy\Entity\Term;

/**
 * Site Alert Service.
 *
 * @package Drupal\sitewide_alerts
 */
class SiteAlertService implements TrustedCallbackInterface {

  use MessengerTrait;
  use StringTranslationTrait;

  /**
   * The cache backend.
   */
  private CacheBackendInterface $cache;

  /**
   * The config.
   */
  private ImmutableConfig $config;

  /**
   * The time.
   */
  private TimeInterface $time;

  /**
   * The entity type manager.
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * The state.
   */
  protected State $state;

  /**
   * The admin context.
   */
  protected AdminContext $adminContext;

  /**
   * The database.
   */
  protected Connection $database;

  /**
   * The module handler.
   */
  protected ModuleHandler $moduleHandler;

  /**
   * SiteAlertService constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config
   *   The config.
   * @param \Drupal\Core\Cache\CacheFactoryInterface $cache
   *   The cache factory.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\State\State $state
   *   The state.
   * @param \Drupal\Core\Routing\AdminContext $admin_context
   *   The admin context.
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   * @param \Drupal\Core\Extension\ModuleHandler $module_handler
   *   The module handler.
   */
  public function __construct(
    ConfigFactoryInterface $config,
    CacheFactoryInterface $cache,
    TimeInterface $time,
    EntityTypeManagerInterface $entity_type_manager,
    State $state,
    AdminContext $admin_context,
    Connection $database,
    ModuleHandler $module_handler
  ) {
    $this->cache = $cache->get('sitewide_alerts');
    $this->config = $config->get('sitewide_alerts.settings');
    $this->time = $time;
    $this->entityTypeManager = $entity_type_manager;
    $this->state = $state;
    $this->adminContext = $admin_context;
    $this->database = $database;
    $this->moduleHandler = $module_handler;
  }

  /**
   * Get the config.
   *
   * @return \Drupal\Core\Config\ImmutableConfig
   *   Returns the config.
   */
  public function getConfig(): ImmutableConfig {
    return $this->config;
  }

  /**
   * Get the state config.
   *
   * @param array $state_keys
   *   Array of state keys to fetch.
   *
   * @return array
   *   The array of state config values.
   */
  public function getStateConfig(array $state_keys = []): array {
    return $this->state->getMultiple($state_keys);
  }

  /**
   * Set state configuration data.
   *
   * @param array $data
   *   The array of state config.
   */
  public function setStateConfig(array $data): void {
    $this->state->setMultiple($data);
  }

  /**
   * Get module handler.
   *
   * @return \Drupal\Core\Extension\ModuleHandler
   *   Returns the module handler.
   */
  public function getModuleHandler(): ModuleHandler {
    return $this->moduleHandler;
  }

  /**
   * Get entity type manager.
   *
   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
   *   Returns the entity type manager.
   */
  public function getEntityTypeManager(): EntityTypeManagerInterface {
    return $this->entityTypeManager;
  }

  /**
   * Determine if site alerts are enabled or not.
   *
   * @return bool
   *   Returns TRUE if enabled, FALSE otherwise.
   */
  public function isEnabled(): bool {
    $config = $this->getConfig();
    if ($config->get('active')) {
      return TRUE;
    }
    else {
      return FALSE;
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks(): array {
    return [
      'preRenderDefaultLink',
      'preRenderSiteAlert',
      'preRenderSiteAlertType',
    ];
  }

  /**
   * Get/pre-render default alerts link.
   *
   * @param string $language
   *   The current language code.
   *
   * @return array
   *   Returns the render array.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityMalformedException
   */
  public function preRenderDefaultLink(string $language = 'en'): array {
    $build = [];
    $alerts_page_nid = $this->getConfig()->get('default_alerts_page');
    if (!empty($alerts_page_nid)) {
      /** @var \Drupal\node\Entity\Node $node */
      $node = $this->entityTypeManager->getStorage('node')->load($alerts_page_nid);
      if ($node->isTranslatable() && $node->hasTranslation($language)) {
        $node = $node->getTranslation($language);
      }
      if ($node) {
        $build = [
          '#type' => 'link',
          '#title' => $this->t('Learn more'),
          '#url' => $node->toUrl(),
          '#attributes' => [
            'class' => [
              'c-site-alert-default-link',
            ],
          ],
          '#prefix' => '<div class="field field-site-alert-default-link field__item">',
          '#suffix' => '</div>',
        ];
        // Setup cache meta data.
        $cacheableMetadata = new CacheableMetadata();
        $cacheableMetadata->addCacheableDependency($node);
        $cacheableMetadata->applyTo($build);
      }
    }
    return $build;
  }

  /**
   * Get site alert entity by id.
   *
   * @param int $id
   *   The site alert entity id.
   *
   * @return \Drupal\Core\Entity\EntityInterface|null
   *   Returns the site alert entity.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getSiteAlert(int $id): ?EntityInterface {
    return $this->entityTypeManager->getStorage('site_alert')->load($id);
  }

  /**
   * Get site alert types.
   *
   * @param string $language
   *   The current language code.
   *
   * @return array
   *   Returns an array of site alert types.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getSiteAlertTypes(string $language = 'en'): array {
    $site_alert_types = [];

    // Get the term storage.
    $entity_storage = $this->entityTypeManager->getStorage('taxonomy_term');

    // Query the terms sorted by weight.
    $query_result = $entity_storage->getQuery()
      ->accessCheck()
      ->condition('vid', 'site_alert_types')
      ->sort('weight', 'ASC')
      ->execute();

    // Load the terms.
    $terms = $entity_storage->loadMultiple($query_result);

    /** @var \Drupal\taxonomy\Entity\Term $term */
    foreach ($terms as $term) {
      if ($term->isTranslatable()) {
        if ($term->hasTranslation($language)) {
          $term = $term->getTranslation($language);
        }
      }
      $site_alert_types[$term->id()] = $term;
    }

    return $site_alert_types;
  }

  /**
   * Get site alerts in order by weight and language.
   *
   * @param string $language
   *   The current language code.
   *
   * @return array
   *   The array of site alert entities.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getSiteAlerts(string $language = 'en'): array {
    // Get site alerts ordered by weight field.
    $query = $this->database->select('site_alert', 's');
    $query->addField('s', 'id');
    $query->addField('s', 'revision_id');
    $query->addJoin('inner', 'site_alert_field_data', 'sf', 'sf.id = s.id AND sf.revision_id = s.revision_id');

    // Filter by language code if set.
    if (!empty($language)) {
      $query->condition('sf.langcode', $language, '=');
    }

    // Only want published site alerts.
    $query->condition('sf.status', 1, '=');

    // Order by weight.
    $query->orderBy('sf.weight', 'ASC');

    // Allow for altering of query.
    $this->moduleHandler->invokeAll('sitewide_alerts_alter_query', [&$query]);

    // Get results.
    $result = $query->execute();

    // Get site alert ids.
    $ids = [];
    while ($row = $result->fetchObject()) {
      $ids[$row->revision_id] = $row->id;
    }

    // Load up site alert entities by ids.
    $site_alerts = [];
    $entities = $this->entityTypeManager->getStorage('site_alert')->loadMultiple($ids);

    /**
     * @var \Drupal\sitewide_alerts\Entity\SiteAlert $site_alert
     */
    foreach ($entities as $id => $site_alert) {
      // Check to see if entity is translatable.
      if ($site_alert->isTranslatable()) {
        // Check to see if entity has translation.
        if ($site_alert->hasTranslation($language)) {
          // Has translation, so we return it.
          $site_alerts[$id] = $site_alert->getTranslation($language);
        }
      }
      else {
        // Not translatable, so we just return it.
        $site_alerts[$id] = $site_alert;
      }
    }

    // Allow for altering site alerts.
    $this->moduleHandler->invokeAll('sitewide_alerts_alter_alerts', [&$site_alerts]);

    return $site_alerts;
  }

  /**
   * Get site alert bar and return render array.
   *
   * @param string $language
   *   The current language.
   *
   * @return array
   *   Returns the render array.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getSiteAlertBar(string $language = 'en'): array {
    $build = [];

    // Check to see if site alerts is enabled.
    if ($this->isEnabled()) {

      $config = $this->getConfig();

      // Not admin route.
      if (!$this->adminContext->isAdminRoute()) {

        // Set and get default view mode.
        $view_mode = 'default';
        if (!empty($config->get('default_view_mode'))) {
          $view_mode = $config->get('default_view_mode');
        }

        $build = [
          '#theme' => 'site_alerts',
          '#view_mode' => $view_mode,
        ];

        // Store alert keys.
        $alert_keys = [];

        // Get site alerts.
        $build['#alerts'] = [];
        $site_alerts = $this->getSiteAlerts($language);
        /** @var \Drupal\sitewide_alerts\SiteAlertInterface $site_alert */
        foreach ($site_alerts as $site_alert) {
          $build['#alerts'][] = $this->preRenderSiteAlert($site_alert, $view_mode, $language);
          $alert_keys[] = $site_alert->id() . '-' . $site_alert->language()->getId();
        }

        // Attach drupal settings.
        $build['#attached'] = [
          'drupalSettings' => [
            'sitewide_alerts' => [
              'dismissedKeys' => $alert_keys,
              'previewMode' => FALSE,
              'cookieExpiration' => $this->getSiteAlertExpiration(),
            ],
          ],
        ];

        // Setup cache meta data.
        $cacheableMetadata = new CacheableMetadata();
        $cacheableMetadata->addCacheableDependency($config);
        /** @var \Drupal\sitewide_alerts\SiteAlertInterface $site_alert */
        foreach ($site_alerts as $site_alert) {
          $cacheableMetadata->addCacheableDependency($site_alert);
        }
        $cacheableMetadata->addCacheTags(['sitewide_alerts']);
        $cacheableMetadata->applyTo($build);
      }
    }

    return $build;
  }

  /**
   * Get site alert render array.
   *
   * @param \Drupal\sitewide_alerts\SiteAlertInterface $site_alert
   *   The site alert entity.
   * @param string $view_mode
   *   The view mode to render the site alert in.
   * @param string $language
   *   The current language.
   *
   * @return array
   *   Returns the render array for site alert.
   */
  public function preRenderSiteAlert(SiteAlertInterface $site_alert, string $view_mode = 'default', string $language = 'en'): array {
    $view_builder = $this->entityTypeManager->getViewBuilder('site_alert');
    return $view_builder->view($site_alert, $view_mode, $language);
  }

  /**
   * Get site alert type render array.
   *
   * @param \Drupal\taxonomy\Entity\Term $site_alert_type
   *   The site alert entity.
   * @param string $view_mode
   *   The view mode to render the site alert in.
   * @param string $language
   *   The current language.
   *
   * @return array
   *   Returns the render array for site alert type.
   */
  public function preRenderSiteAlertType(Term $site_alert_type, string $view_mode = 'default', string $language = 'en'): array {
    $view_builder = $this->entityTypeManager->getViewBuilder('taxonomy_term');
    return $view_builder->view($site_alert_type, $view_mode, $language);
  }

  /**
   * Get site alert expiration.
   *
   * @return int|string
   *   Returns the expiration value for site alert.
   */
  public function getSiteAlertExpiration(): int|string {
    $config = $this->getConfig();

    // Set up cookie expiration value for jQuery cookie function.
    switch ($config->get('expiration')) {
      case 'year':
        $expiration = 365;
        break;

      case 'month':
        $expiration = 30;
        break;

      case 'week':
        $expiration = 7;
        break;

      case 'day':
        $expiration = 1;
        break;

      default:
        $expiration = 'default';
    }

    return $expiration;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc