refreshless-8.x-1.x-dev/src/Value/PageState.php

src/Value/PageState.php
<?php

declare(strict_types=1);

namespace Drupal\refreshless\Value;

use Drupal\Component\Utility\UrlHelper;
use Drupal\refreshless\Value\PageStateInterface;
use function array_intersect_key;
use function implode;
use function is_string;
use function json_decode;
use function sort;
use function sprintf;
use Symfony\Component\HttpFoundation\Request;

/**
 * Default implementation of a RefreshLess page state value object.
 */
class PageState implements PageStateInterface {

  /**
   * Name of the cookie containing the RefreshLess page state.
   */
  protected const COOKIE_NAME = 'refreshless-page-state';

  /**
   * Libraries already on the page, if found in the page state.
   *
   * @var string[]
   */
  protected array $libraries = [];

  /**
   * The Symfony Request object this value object was constructed from, if any.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected readonly Request $request;

  /**
   * A CSRF theme token, if one is found in the page state.
   *
   * @var string
   */
  protected string $themeToken = '';

  /**
   * The theme machine name.
   *
   * @var string
   */
  protected string $theme = '';

  /**
   * Protected constructor; use static contructor methods instead.
   */
  protected function __construct() {}

  /**
   * {@inheritdoc}
   */
  public function getLibraries(): array {
    return $this->libraries;
  }

  /**
   * {@inheritdoc}
   */
  public function setLibraries(array|string $libraries): self {

    if (is_string($libraries)) {

      $libraries = UrlHelper::uncompressQueryParameter($libraries);

      $libraries = explode(',', $libraries);

    }

    $this->libraries = $libraries;

    return $this;

  }

  /**
   * {@inheritdoc}
   */
  public function getThemeToken(): string {
    return $this->themeToken;
  }

  /**
   * {@inheritdoc}
   */
  public function setThemeToken(string $themeToken): self {

    $this->themeToken = $themeToken;

    return $this;

  }

  /**
   * {@inheritdoc}
   */
  public function getTheme(): string {
    return $this->theme;
  }

  /**
   * {@inheritdoc}
   */
  public function setTheme(string $theme): self {

    $this->theme = $theme;

    return $this;

  }

  /**
   * Format the page state into an array suitable for drupalSettings.
   *
   * @return array
   *   An array of page state information containing 'libraries', 'theme', and
   *   'themeToken' keys.
   */
  public function toDrupalSettings(): array {

    $libraries = sort($this->getLibraries());

    return [
      'theme'       => $this->getTheme(),
      'themeToken'  => $this->getThemeToken(),
      'libraries'   => UrlHelper::compressQueryParameter(implode(
        ',', $libraries,
      )),
    ];

  }

  /**
   * Create from a provided drupalSettings array.
   *
   * @param array $settings
   *   A array containing 'libraries', 'theme', and 'themeToken' keys.
   *
   * @return self
   *   A new instance with values set.
   */
  public static function fromDrupalSettings(array $settings): self {

    $instance = (new self())
      ->setTheme($settings['theme'])
      ->setLibraries($settings['libraries']);

    // Theme token is optional and only used when on a different theme from the
    // default theme.
    if (isset($settings['themeToken'])) {
      $instance->setThemeToken($settings['themeToken']);
    }

    return $instance;

  }

  /**
   * {@inheritdoc}
   */
  public static function fromCookieValue(string $value): self {

    $parsed = array_intersect_key(
      json_decode($value, true),
      // Allow list of keys from the cookie value.
      ['libraries' => true, 'theme' => true, 'themeToken' => true]
    );

    // This avoids duplicate code by delegating to this method.
    return self::fromDrupalSettings($parsed);

  }

  /**
   * {@inheritdoc}
   *
   * @throws \ValueError If the cookie is not present in the request.
   */
  public static function fromRequest(Request $request): self {

    if (!$request->cookies->has(self::COOKIE_NAME)) {

      throw new \ValueError(sprintf(
        'The request must contain a "%s" cookie!', self::COOKIE_NAME,
      ));

    }

    return self::fromCookieValue($request->cookies->get(self::COOKIE_NAME));

  }

  /**
   * {@inheritdoc}
   */
  public function getRequest(): Request {
    return $this->request;
  }

  /**
   * {@inheritdoc}
   */
  public static function getCookieName(): string {
    return self::COOKIE_NAME;
  }

}

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

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