utilikit-1.0.0/src/Service/UtilikitCacheManager.php

src/Service/UtilikitCacheManager.php
<?php

declare(strict_types=1);

namespace Drupal\utilikit\Service;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Theme\Registry;
use Drupal\Core\Asset\AssetCollectionOptimizerInterface;

/**
 * Manages cache operations for Utilikit utility classes and CSS.
 *
 * This service provides comprehensive cache management including render cache,
 * page cache, asset optimization caches, and Utilikit-specific cache tags.
 * It supports different clearing strategies and provides cache statistics
 * for monitoring and debugging purposes.
 */
class UtilikitCacheManager implements UtilikitCacheManagerInterface {

  /**
   * The render cache backend service.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected CacheBackendInterface $renderCache;

  /**
   * The cache tags invalidator service.
   *
   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
   */
  protected CacheTagsInvalidatorInterface $cacheTagsInvalidator;

  /**
   * The state service for persistent data storage.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected StateInterface $state;

  /**
   * The theme registry service.
   *
   * @var \Drupal\Core\Theme\Registry
   */
  protected Registry $themeRegistry;

  /**
   * The CSS asset collection optimizer service.
   *
   * @var \Drupal\Core\Asset\AssetCollectionOptimizerInterface
   */
  protected AssetCollectionOptimizerInterface $cssOptimizer;

  /**
   * The JS asset collection optimizer service.
   *
   * @var \Drupal\Core\Asset\AssetCollectionOptimizerInterface
   */
  protected AssetCollectionOptimizerInterface $jsOptimizer;

  /**
   * The page cache backend service (optional).
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface|null
   */
  protected ?CacheBackendInterface $pageCache;

  /**
   * The dynamic page cache backend service (optional).
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface|null
   */
  protected ?CacheBackendInterface $dynamicPageCache;

  /**
   * Constructs a new UtilikitCacheManager object.
   *
   * @param \Drupal\Core\Cache\CacheBackendInterface $renderCache
   *   The render cache backend service.
   * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cacheTagsInvalidator
   *   The cache tags invalidator service.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service for persistent data storage.
   * @param \Drupal\Core\Theme\Registry $themeRegistry
   *   The theme registry service.
   * @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $cssOptimizer
   *   The CSS asset collection optimizer service.
   * @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $jsOptimizer
   *   The JS asset collection optimizer service.
   * @param \Drupal\Core\Cache\CacheBackendInterface|null $pageCache
   *   The page cache backend service (optional).
   * @param \Drupal\Core\Cache\CacheBackendInterface|null $dynamicPageCache
   *   The dynamic page cache backend service (optional).
   */
  public function __construct(
    CacheBackendInterface $renderCache,
    CacheTagsInvalidatorInterface $cacheTagsInvalidator,
    StateInterface $state,
    Registry $themeRegistry,
    AssetCollectionOptimizerInterface $cssOptimizer,
    AssetCollectionOptimizerInterface $jsOptimizer,
    ?CacheBackendInterface $pageCache = NULL,
    ?CacheBackendInterface $dynamicPageCache = NULL,
  ) {
    $this->renderCache = $renderCache;
    $this->cacheTagsInvalidator = $cacheTagsInvalidator;
    $this->state = $state;
    $this->themeRegistry = $themeRegistry;
    $this->cssOptimizer = $cssOptimizer;
    $this->jsOptimizer = $jsOptimizer;
    $this->pageCache = $pageCache;
    $this->dynamicPageCache = $dynamicPageCache;
  }

  /**
   * Clears all caches and resets the Utilikit system.
   *
   * Performs a comprehensive cache clear including render cache, page caches,
   * asset optimization caches, theme registry, and all Utilikit-specific
   * cache tags. Also triggers a full Drupal cache flush.
   */
  public function clearAllCaches(): void {
    $this->clearRenderCache();
    $this->clearPageCaches();
    $this->clearAssetCaches();
    $this->updateCssTimestamp();
    $this->invalidateUtilikitTags();
    $this->themeRegistry->reset();
    drupal_flush_all_caches();
  }

  /**
   * Clears CSS-related caches without full system flush.
   *
   * Targets caches specifically related to CSS processing and Utilikit
   * functionality while preserving other system caches for better
   * performance during CSS updates.
   */
  public function clearCssCaches(): void {
    $this->clearRenderCache();
    $this->clearAssetCaches();
    $this->updateCssTimestamp();
    $this->invalidateUtilikitTags([
      UtilikitConstants::CACHE_TAG_CSS,
      UtilikitConstants::CACHE_TAG_INLINE_MODE,
      UtilikitConstants::CACHE_TAG_STATIC_MODE,
      UtilikitConstants::CACHE_TAG_HEAD_MODE,
    ]);
  }

  /**
   * Clears tracked Utilikit data from state storage.
   *
   * Removes generated CSS content and known classes from the state API,
   * effectively resetting Utilikit to a clean state without affecting
   * other cache layers.
   */
  public function clearTrackedData(): void {
    $this->state->deleteMultiple([
      UtilikitConstants::STATE_GENERATED_CSS,
      UtilikitConstants::STATE_KNOWN_CLASSES,
    ]);
  }

  /**
   * Clears caches using a specific strategy.
   *
   * Provides different cache clearing strategies based on the use case:
   * - conservative: Minimal cache clearing for minor updates
   * - aggressive: Full cache clearing with optional data preservation
   * - standard: Default CSS-focused cache clearing.
   *
   * @param array $options
   *   Options array with the following keys:
   *   - strategy: Cache clearing strategy ('conservative', 'aggressive',
   *     'standard')
   *   - preserve_static_css: Whether to preserve static CSS data in
   *     aggressive mode (default: FALSE)
   */
  public function clearCachesWithStrategy(array $options = []): void {
    $strategy = $options['strategy'] ?? 'standard';

    switch ($strategy) {
      case 'conservative':
        $this->clearRenderCache();
        $this->updateCssTimestamp();
        break;

      case 'aggressive':
        $this->clearAllCaches();
        if (!($options['preserve_static_css'] ?? FALSE)) {
          $this->clearTrackedData();
        }
        break;

      default:
        $this->clearCssCaches();
        break;
    }
  }

  /**
   * Invalidates Utilikit-specific cache tags.
   *
   * Invalidates cache entries tagged with Utilikit-specific tags to ensure
   * that cached content using Utilikit classes is regenerated with the
   * latest CSS rules and configurations.
   *
   * @param array $tags
   *   Additional cache tags to invalidate beyond the default Utilikit tags.
   */
  public function invalidateUtilikitTags(array $tags = []): void {
    $defaultTags = [
      UtilikitConstants::CACHE_TAG_CONFIG,
      UtilikitConstants::CACHE_TAG_CSS,
      UtilikitConstants::CACHE_TAG_INLINE_MODE,
      UtilikitConstants::CACHE_TAG_STATIC_MODE,
      UtilikitConstants::CACHE_TAG_HEAD_MODE,
      UtilikitConstants::CACHE_TAG_RENDERED,
    ];

    $allTags = array_merge($defaultTags, $tags);
    $this->cacheTagsInvalidator->invalidateTags($allTags);
  }

  /**
   * Updates the CSS timestamp to current time.
   *
   * Records the current timestamp for CSS updates, used for cache busting
   * and tracking when CSS was last modified.
   */
  public function updateCssTimestamp(): void {
    $this->state->set(UtilikitConstants::STATE_CSS_TIMESTAMP, time());
  }

  /**
   * Gets cache statistics for monitoring and debugging.
   *
   * Provides information about the current state of Utilikit caches
   * including counts, sizes, and timestamps for monitoring purposes.
   *
   * @return array
   *   Statistics array containing:
   *   - known_classes_count: Number of tracked utility classes
   *   - generated_css_size: Size of generated CSS in bytes
   *   - last_cleanup: Timestamp of last cleanup operation
   *   - css_timestamp: Timestamp of last CSS update
   */
  public function getCacheStatistics(): array {
    $knownClasses = $this->state->get(UtilikitConstants::STATE_KNOWN_CLASSES, []);
    $generatedCss = $this->state->get(UtilikitConstants::STATE_GENERATED_CSS, '');
    $lastCleanup = $this->state->get(UtilikitConstants::STATE_LAST_CLEANUP, 0);

    return [
      'known_classes_count' => count($knownClasses),
      'generated_css_size' => strlen($generatedCss),
      'last_cleanup' => $lastCleanup,
      'css_timestamp' => $this->state->get(UtilikitConstants::STATE_CSS_TIMESTAMP, 0),
    ];
  }

  /**
   * Gets the availability status of cache services.
   *
   * Reports which cache services are available and properly configured
   * for debugging and monitoring purposes.
   *
   * @return array
   *   Service status array containing boolean values for:
   *   - render_cache: Render cache service availability
   *   - page_cache: Page cache service availability
   *   - dynamic_page_cache: Dynamic page cache service availability
   *   - css_optimizer: CSS optimizer service availability
   *   - js_optimizer: JS optimizer service availability
   */
  public function getCacheServiceStatus(): array {
    return [
      'render_cache' => $this->renderCache !== NULL,
      'page_cache' => $this->pageCache !== NULL,
      'dynamic_page_cache' => $this->dynamicPageCache !== NULL,
      'css_optimizer' => $this->cssOptimizer !== NULL,
      'js_optimizer' => $this->jsOptimizer !== NULL,
    ];
  }

  /**
   * Clears the render cache.
   *
   * Invalidates all render cache entries. Exceptions are caught and handled
   * silently to prevent cache clearing failures from breaking the system.
   */
  private function clearRenderCache(): void {
    try {
      $this->renderCache->invalidateAll();
    }
    catch (\Exception $e) {
      // Continue silently.
    }
  }

  /**
   * Clears page caches (both dynamic and static).
   *
   * Clears both dynamic page cache and static page cache if available.
   * Exceptions are caught and handled silently to prevent cache clearing
   * failures from breaking the system.
   */
  private function clearPageCaches(): void {
    try {
      if ($this->dynamicPageCache) {
        $this->dynamicPageCache->deleteAll();
      }
    }
    catch (\Exception $e) {
      $this->logger->warning('Failed to clear dynamic page cache: @message', [
        '@message' => $e->getMessage(),
      ]);
    }

    try {
      if ($this->pageCache) {
        $this->pageCache->deleteAll();
      }
    }
    catch (\Exception $e) {
      $this->logger->warning('Failed to clear page cache: @message', [
        '@message' => $e->getMessage(),
      ]);
    }
  }

  /**
   * Clears asset optimization caches.
   *
   * Deletes optimized CSS and JS asset caches to ensure fresh asset
   * generation. Exceptions are caught and handled silently to prevent
   * cache clearing failures from breaking the system.
   */
  private function clearAssetCaches(): void {
    try {
      $this->cssOptimizer->deleteAll();
      $this->jsOptimizer->deleteAll();
    }
    catch (\Exception $e) {
      // Continue silently.
    }
  }

}

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

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