config_css-8.x-1.0-alpha1/config_css.module

config_css.module
<?php

/**
 * @file
 * Provides a config entity containing CSS rules and visibility conditions to
 * include the stylesheet on specific pages.
 */

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Component\Plugin\Exception\MissingValueContextException;
use Drupal\config_css\ConditionAccessResolver;
use Drupal\config_css\Entity\ConfigCss;
use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\File\Exception\FileWriteException;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_page_attachments().
 */
function config_css_page_attachments(array &$attachments) {
  $activeTheme = \Drupal::theme()->getActiveTheme();
  $contextHandler = \Drupal::service('context.handler');
  $contextRepository = \Drupal::service('context.repository');

  // Load out all stylesheet entities.
  $stylesheets = \Drupal::entityTypeManager()->getStorage('config_css')->loadMultiple();

  // We always add the config_css list cache tag as any change to a config CSS entity could result
  // in it showing up somewhere.
  $cache = [
    'context' => [],
    'tags' => ['config:config_css_list'],
  ];

  foreach ($stylesheets as $stylesheet) {
    $visible = FALSE;
    $missing_values = FALSE;
    if ($stylesheet->get('theme') == $activeTheme->getName()) {
      $visibilityConditions = $stylesheet->getVisibilityConditions();
      $validConditions = [];
      foreach ($visibilityConditions as $condition) {
        $contexts = $contextRepository->getRuntimeContexts(array_values($condition->getContextMapping()));
        try {
          $contextHandler->applyContextMapping($condition, $contexts);
          if ($condition instanceof CacheableDependencyInterface) {
            $cache['context'] = array_merge($cache['context'], $condition->getCacheContexts());
            $cache['tags'] = array_merge($cache['tags'], $condition->getCacheTags());
          }
          $validConditions[] = $condition;
        }
        catch (MissingValueContextException $e) {
          // If there is no value, don't display.
          $visible = FALSE;
          $missing_values = TRUE;
          break;
        }
        catch (ContextException $e) {
          // No-op, we just skip this condition.
        }
      }

      // If we didn't have any missing values, resolve all the conditions.
      if (!$missing_values) {
        $conditionAccessResolver = new ConditionAccessResolver();
        if ($conditionAccessResolver->resolveConditions($validConditions, 'and')) {
          $visible = TRUE;
        }
      }
    }

    // If the stylesheet is visible, attach it.
    if ($visible) {
      $attachments['#attached']['library'][] = 'config_css/' . $stylesheet->id();
      $cache['tags'] = array_merge($cache['tags'], $stylesheet->getCacheTags(), $stylesheet->getEntityType()->getListCacheTags());
      $cache['context'] = array_merge($cache['context'], $stylesheet->getCacheContexts());
    }
  }

  // Always add cache metadata as any change to a config CSS entity requires invalidating all the headers.
  $attachments['#cache'] = $cache;
}

/**
 * Implements hook_library_info_build().
 *
 * Add a library for each stylesheet entry.
 */
function config_css_library_info_build() {
  $libraries = [];
  $stylesheets = \Drupal::entityTypeManager()->getStorage('config_css')->loadMultiple();
  foreach ($stylesheets as $stylesheet) {
    config_css_write_stylesheet($stylesheet);
    $libraries[$stylesheet->id()] = [
      'css' => [
        'base' => [
          $stylesheet->getStylesheetUrl() => [],
        ],
      ],
    ];
  }
  return $libraries;
}

/**
 * Implements hook_css_alter().
 *
 * Drupal will force the group to CSS_AGGREGATE_DEFAULT in LibraryDiscoveryParser->buildByExtension(), so we have to alter
 * our own CSS to set it.
 */
function config_css_css_alter(&$css, AttachedAssetsInterface $assets) {
  $stylesheets = \Drupal::entityTypeManager()->getStorage('config_css')->loadMultiple();
  foreach ($stylesheets as $stylesheet) {
    $path = ltrim($stylesheet->getStylesheetUrl(), '/');
    if (isset($css[$path])) {
      $css[$path]['group'] = CSS_AGGREGATE_THEME;
      $css[$path]['weight'] = 1000 + $stylesheet->get('weight');
    }
  }
}

/**
 * Implements hook_entity_update().
 */
function config_css_entity_update(EntityInterface $entity) {
  if ($entity instanceof ConfigCss) {
    _drupal_flush_css_js();
    \Drupal::service('cache.css_config_asset_resolver')->invalidateAll();
    \Drupal::service('asset.css.collection_optimizer')->deleteAll();
    \Drupal::service('library.discovery')->clearCachedDefinitions();
  }
}

/**
 * Implements hook_entity_insert().
 */
function config_css_entity_insert(EntityInterface $entity) {
  config_css_entity_update($entity);
}

/**
 * Implements hook_entity_delete().
 */
function config_css_entity_delete(EntityInterface $entity) {
  config_css_entity_update($entity);
}

/**
 * Write the stylesheet contents for a config CSS entity to the filesystem.
 *
 * @param \Drupal\config_css\Entity\ConfigCss $entity
 *   The configuration stylesheet entity to write to the filesystem.
 */
function config_css_write_stylesheet(ConfigCss $entity) {
  $config = \Drupal::config('config_css.settings');
  $path = rtrim($config->get('css_store_path'), '/');
  $fileSystem = \Drupal::service('file_system');
  if ($fileSystem->prepareDirectory($path, FileSystem::CREATE_DIRECTORY | FileSystem::MODIFY_PERMISSIONS)) {
    $fileSystem->saveData($entity->get('stylesheet'), $path . '/' . $entity->id() . '.css', FileSystem::EXISTS_REPLACE);
  }
  else {
    throw new FileWriteException(t('CSS store directory %directory could not be prepared.', ['%directory' => $path]));
  }
}

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

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