Verified Commit b3e943e9 authored by Dave Long's avatar Dave Long
Browse files

Issue #3358336 by kim.pepper, rpayanm, andypost, longwave, smustgrave, Wim...

Issue #3358336 by kim.pepper, rpayanm, andypost, longwave, smustgrave, Wim Leers, catch: Deprecate _drupal_flush_css_js() and create a new AssetQueryString cache service
parent 69333763
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -292,6 +292,12 @@ services:
      - { name: cache.bin, default_backend: cache.backend.chainedfast }
    factory: ['@cache_factory', 'get']
    arguments: [discovery]
  Drupal\Core\Asset\AssetQueryStringInterface: '@asset.query_string'
  asset.query_string:
    class: Drupal\Core\Asset\AssetQueryString
    arguments:
      - '@state'
      - '@datetime.time'
  cache_router_rebuild_subscriber:
    class: Drupal\Core\EventSubscriber\CacheRouterRebuildSubscriber
  page_cache_request_policy:
@@ -1580,7 +1586,7 @@ services:
  Drupal\Core\Session\MetadataBag: '@session_manager.metadata_bag'
  asset.css.collection_renderer:
    class: Drupal\Core\Asset\CssCollectionRenderer
    arguments: [ '@state', '@file_url_generator' ]
    arguments: [ '@asset.query_string', '@file_url_generator' ]
  asset.css.collection_optimizer:
    class: Drupal\Core\Asset\CssCollectionOptimizerLazy
    arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@theme.manager', '@library.dependency_resolver', '@request_stack', '@file_system', '@config.factory', '@file_url_generator', '@datetime.time', '@language_manager']
@@ -1594,7 +1600,7 @@ services:
    arguments: ['@file_system']
  asset.js.collection_renderer:
    class: Drupal\Core\Asset\JsCollectionRenderer
    arguments: [ '@state', '@file_url_generator' ]
    arguments: [ '@asset.query_string','@file_url_generator' ]
  asset.js.collection_optimizer:
    class: Drupal\Core\Asset\JsCollectionOptimizerLazy
    arguments: [ '@asset.js.collection_grouper', '@asset.js.optimizer', '@theme.manager', '@library.dependency_resolver', '@request_stack', '@file_system', '@config.factory', '@file_url_generator', '@datetime.time', '@language_manager']
+8 −3
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ function drupal_flush_all_caches($kernel = NULL) {
  // Flush asset file caches.
  \Drupal::service('asset.css.collection_optimizer')->deleteAll();
  \Drupal::service('asset.js.collection_optimizer')->deleteAll();
  _drupal_flush_css_js();
  \Drupal::service('asset.query_string')->reset();

  // Reset all static caches.
  drupal_static_reset();
@@ -531,10 +531,15 @@ function drupal_flush_all_caches($kernel = NULL) {
 *
 * Changing the dummy query string appended to CSS and JavaScript files forces
 * all browsers to reload fresh files.
 *
 * @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
 *   Use \Drupal\Core\Asset\AssetQueryStringInterface::reset() instead.
 *
 * @see https://www.drupal.org/node/3358337
 */
function _drupal_flush_css_js() {
  // The timestamp is converted to base 36 in order to make it more compact.
  Drupal::state()->set('system.css_js_query_string', base_convert(\Drupal::time()->getRequestTime(), 10, 36));
  @trigger_error('_drupal_flush_css_js is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use \Drupal\Core\Asset\AssetQueryStringInterface::reset() instead. See https://www.drupal.org/node/3358337', E_USER_DEPRECATED);
  \Drupal::service('asset.query_string')->reset();
}

/**
+51 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Asset;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\State\StateInterface;

/**
 * Stores a cache busting query string service for asset URLs.
 *
 * The string changes on every update or full cache flush, forcing browsers to
 * load a new copy of the files, as the URL changed.
 */
class AssetQueryString implements AssetQueryStringInterface {

  /**
   * The key used for state.
   */
  const STATE_KEY = 'asset.css_js_query_string';

  /**
   * Creates a new AssetQueryString instance.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   State service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   System time service.
   */
  public function __construct(
    protected StateInterface $state,
    protected TimeInterface $time
  ) {}

  /**
   * {@inheritdoc}
   */
  public function reset(): void {
    // The timestamp is converted to base 36 in order to make it more compact.
    $this->state->set(self::STATE_KEY, base_convert(strval($this->time->getRequestTime()), 10, 36));
  }

  /**
   * {@inheritdoc}
   */
  public function get(): string {
    return $this->state->get(self::STATE_KEY, '0');
  }

}
+25 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Core\Asset;

/**
 * Provides a cache busting query string service for asset URLs.
 */
interface AssetQueryStringInterface {

  /**
   * Resets the cache query string added to all CSS and JavaScript URLs.
   *
   * Changing the cache query string appended to CSS and JavaScript URLs forces
   * all browsers to fetch fresh files.
   */
  public function reset(): void;

  /**
   * Gets the query string value.
   */
  public function get(): string;

}
+20 −8
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@

namespace Drupal\Core\Asset;

use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\State\StateInterface;

@@ -10,12 +11,19 @@
 */
class CssCollectionRenderer implements AssetCollectionRendererInterface {

  use DeprecatedServicePropertyTrait;

  /**
   * {@inheritdoc}
   */
  protected array $deprecatedProperties = ['state' => 'state'];

  /**
   * The state key/value store.
   * The asset query string.
   *
   * @var \Drupal\Core\State\StateInterface
   * @var \Drupal\Core\Asset\AssetQueryStringInterface
   */
  protected $state;
  protected AssetQueryStringInterface $assetQueryString;

  /**
   * The file URL generator.
@@ -27,13 +35,17 @@ class CssCollectionRenderer implements AssetCollectionRendererInterface {
  /**
   * Constructs a CssCollectionRenderer.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state key/value store.
   * @param \Drupal\Core\Asset\AssetQueryStringInterface|\Drupal\Core\State\StateInterface $asset_query_string
   *   The asset query string.
   * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator
   *   The file URL generator.
   */
  public function __construct(StateInterface $state, FileUrlGeneratorInterface $file_url_generator) {
    $this->state = $state;
  public function __construct(AssetQueryStringInterface|StateInterface $asset_query_string, FileUrlGeneratorInterface $file_url_generator) {
    if ($asset_query_string instanceof StateInterface) {
      @trigger_error('Calling ' . __METHOD__ . '() with an $asset_query_string argument as \Drupal\Core\State\StateInterface instead of \Drupal\Core\Asset\AssetQueryStringInterface is deprecated in drupal:10.2.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3358337', E_USER_DEPRECATED);
      $asset_query_string = \Drupal::service('asset.query_string');
    }
    $this->assetQueryString = $asset_query_string;
    $this->fileUrlGenerator = $file_url_generator;
  }

@@ -47,7 +59,7 @@ public function render(array $css_assets) {
    // browser-caching. The string changes on every update or full cache
    // flush, forcing browsers to load a new copy of the files, as the
    // URL changed.
    $query_string = $this->state->get('system.css_js_query_string', '0');
    $query_string = $this->assetQueryString->get();

    // Defaults for LINK and STYLE elements.
    $link_element_defaults = [
Loading