refreshless-8.x-1.x-dev/modules/refreshless_turbo/src/Hooks/PageAttachments.php

modules/refreshless_turbo/src/Hooks/PageAttachments.php
<?php

declare(strict_types=1);

namespace Drupal\refreshless_turbo\Hooks;

use Drupal\Core\Asset\AssetQueryStringInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Session\PermissionsHashGeneratorInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\hux\Attribute\Hook;
use Drupal\refreshless\Service\RefreshlessKillSwitchInterface;
use Drupal\refreshless\Service\RequestWrapperFactoryInterface;

/**
 * Page attachments hook implementations.
 */
class PageAttachments {

  /**
   * Hook constructor; saves dependencies.
   *
   * @param \Drupal\Core\Asset\AssetQueryStringInterface $assetQueryString
   *   The Drupal asset query string service.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The Drupal configuration object factory service.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   The current user account proxy service.
   *
   * @param \Drupal\refreshless\Service\RequestWrapperFactoryInterface $requestWrapperFactory
   *   The RefreshLess request wrapper factory.
   *
   * @param \Drupal\refreshless_turbo\Service\RefreshlessKillSwitchInterface $killSwitch
   *   The RefreshLess kill switch service.
   *
   * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
   *   The Drupal theme manager.
   *
   * @param \Drupal\Core\Session\PermissionsHashGeneratorInterface $permissionsHashGenerator
   *   The permissions hash generator service.
   */
  public function __construct(
    protected readonly AssetQueryStringInterface  $assetQueryString,
    protected readonly ConfigFactoryInterface     $configFactory,
    protected readonly AccountProxyInterface      $currentUser,
    protected readonly RequestWrapperFactoryInterface $requestWrapperFactory,
    protected readonly RefreshlessKillSwitchInterface $killSwitch,
    protected readonly ThemeManagerInterface              $themeManager,
    protected readonly PermissionsHashGeneratorInterface  $permissionsHashGenerator,
  ) {}

  #[Hook('page_attachments')]
  /**
   * Attaches RefreshLess to the page.
   *
   * @see \hook_page_attachments()
   */
  public function attachLibraries(array &$attachments): void {

    // Vary based on whether Turbo is enabled for a request. Note that this must
    // be applied regardless of whether or not Turbo is enabled.
    (CacheableMetadata::createFromRenderArray($attachments))->addCacheContexts([
      'refreshless_enabled',
    ])->applyTo($attachments);

    // Only attach if the kill switch was not triggered.
    if ($this->killSwitch->triggered()) {
      return;
    }

    $attachments['#attached']['library'][] = 'refreshless_turbo/refreshless';

  }

  #[Hook('page_attachments')]
  /**
   * Attaches <meta> elements for Turbo.
   *
   * @see \hook_page_attachments()
   *
   * @todo Split this into several methods, grouped by purpose:
   *   1. Theme <meta> element.
   *   2. Asset <meta> elements.
   *   3. turbo-cache-control <meta> element.
   */
  public function attachMetaElements(array &$attachments): void {

    // Vary based on whether Turbo is enabled for a request. Note that this must
    // be applied regardless of whether or not Turbo is enabled.
    (CacheableMetadata::createFromRenderArray($attachments))->addCacheContexts([
      'refreshless_enabled',
    ])->applyTo($attachments);

    // Don't attach any of our <meta> elements if the kill switch was triggered.
    if ($this->killSwitch->triggered()) {
      return;
    }

    /** @var \Drupal\Core\Config\ImmutableConfig */
    $performanceConfig = $this->configFactory->get('system.performance');

    /** @var \Drupal\Core\Config\ImmutableConfig */
    $themeConfig = $this->configFactory->get('system.theme');

    // Important note: don't add cache metadata to the items in
    // $attachments['#attached']['html_head'] because Drupal doesn't seem to
    // bubble that up to the page and thus the response, meaning that none of
    // the cache metadata will take effect.
    /** @var \Drupal\Core\Cache\RefinableCacheableDependencyInterface Cache metadata object containing existing metadata found in $attachments, if any. */
    $cacheMetadata = CacheableMetadata::createFromRenderArray($attachments);

    // This outputs the machine name of the current theme along with the
    // data-turbo-track="reload" attribute which causes Turbo to automagically
    // do a full page load rather than a fetch when this element changes on
    // navigating to a new page.
    //
    // @see https://turbo.hotwired.dev/reference/attributes
    $attachments['#attached']['html_head'][] = [[
      '#type'       => 'html_tag',
      '#tag'        => 'meta',
      '#attributes' => [
        'name'              => 'refreshless-turbo-theme',
        'content'           => $this->themeManager->getActiveTheme()->getName(),
        'data-turbo-track'  => 'reload',
      ],
    ], 'refreshless_turbo_theme'];

    // Add the cache metadata for the system theme configuration.
    $cacheMetadata->addCacheableDependency($themeConfig);

    foreach (['css', 'js'] as $type) {

      $attachments['#attached']['html_head'][] = [[
        '#type'       => 'html_tag',
        '#tag'        => 'meta',
        '#attributes' => [
          'name'    => 'refreshless-turbo-' . $type . '-aggregation',
          'content' => $performanceConfig->get($type . '.preprocess') ?
            'enabled' : 'disabled',
          'data-turbo-track'  => 'reload',
        ],
      ], 'refreshless_turbo_' . $type . '_aggregation'];

    }

    // Add the cache metadata for the performance configuration.
    $cacheMetadata->addCacheableDependency($performanceConfig);

    $attachments['#attached']['html_head'][] = [[
      '#type'       => 'html_tag',
      '#tag'        => 'meta',
      '#attributes' => [
        'name'              => 'refreshless-turbo-asset-query-string',
        'content'           => $this->assetQueryString->get(),
        'data-turbo-track'  => 'reload',
      ],
    ], 'refreshless_turbo_asset_query_string'];

    // This gets invalidated and rebuilt when the 'library_info' cache tag is
    // invalidated. Note that there doesn't seem to be a more specific cache
    // tag at the time of writing for the asset query string.
    //
    // @see \Drupal\Core\Asset\AssetResolver::getCssAssets()
    //   Caches with the 'library_info' tag.
    //
    // @see \Drupal\Core\Asset\AssetResolver::getJsAssets()
    //   Caches with the 'library_info' tag.
    //
    // @see \Drupal\Core\Asset\AssetQueryString::reset()
    //   Gets reset here but does not invalidate a cache tag or other
    //   mechanism.
    //
    // @see https://www.drupal.org/project/drupal/issues/3258064
    //   Core issue to add cache tags for state values.
    $cacheMetadata->addCacheTags(['library_info']);

    // Varies based on whether this is a RefreshLess request or not.
    $cacheMetadata->addCacheContexts(['refreshless_request']);

    $requestWrapper = $this->requestWrapperFactory->fromRequest();

    // Indicates that this response was the result of a Turbo request.
    $attachments['#attached']['html_head'][] = [[
      '#type'       => 'html_tag',
      '#tag'        => 'meta',
      '#attributes' => [
        'name'        => 'refreshless-turbo-response',
        'content'     => match ($requestWrapper->isRefreshless()) {
          true  => 'true',
          false => 'false',
        },
        // Instruct Turbo to remove this if a response does not contain it. This
        // prevents situations where two instances of this element can be
        // present, one with content="true" and one with content="false",
        // resulting in false positives.
        'data-turbo-track' => 'dynamic',
      ],
    ], 'refreshless_turbo_response'];

    $attachments['#attached']['html_head'][] = [[
      '#type'       => 'html_tag',
      '#tag'        => 'meta',
      '#attributes' => [
        'name'              => 'refreshless-turbo-permissions-hash',
        'content'           => $this->permissionsHashGenerator->generate(
          $this->currentUser->getAccount(),
        ),
        'data-turbo-track'  => 'reload',
      ],
    ], 'refreshless_turbo_permissions_hash'];

    // Merge in the permissions hash cache metadata.
    $cacheMetadata = $cacheMetadata->merge(
      $this->permissionsHashGenerator->getCacheableMetadata(
        $this->currentUser->getAccount(),
      ),
    );

    // Apply all the accumulated cache metadata back to $attachments right at
    // the end.
    $cacheMetadata->applyTo($attachments);

  }

}

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

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