You are here

final class SwaggerUiLibraryDiscovery in Swagger UI Field Formatter 8.3

Same name in this branch
  1. 8.3 src/Service/SwaggerUiLibraryDiscovery.php \Drupal\swagger_ui_formatter\Service\SwaggerUiLibraryDiscovery
  2. 8.3 tests/modules/swagger_ui_formatter_test/src/Service/SwaggerUiLibraryDiscovery.php \Drupal\swagger_ui_formatter_test\Service\SwaggerUiLibraryDiscovery

Default Swagger UI library discovery service implementation.

The main purpose of this service is to allow themes and modules to modify the Swagger UI library directory path. The default theme can do this by implementing the hook_swagger_ui_library_directory_alter() hook. Modules can override the directory path by decorating the service.

Hierarchy

Expanded class hierarchy of SwaggerUiLibraryDiscovery

See also

https://www.drupal.org/docs/drupal-apis/services-and-dependency-injectio...

2 files declare their use of SwaggerUiLibraryDiscovery
SwaggerUiLibraryDiscoveryTest.php in tests/src/Unit/SwaggerUiLibraryDiscoveryTest.php
swagger_ui_formatter.install in ./swagger_ui_formatter.install
1 string reference to 'SwaggerUiLibraryDiscovery'
swagger_ui_formatter.services.yml in ./swagger_ui_formatter.services.yml
swagger_ui_formatter.services.yml
1 service uses SwaggerUiLibraryDiscovery
swagger_ui_formatter.swagger_ui_library_discovery in ./swagger_ui_formatter.services.yml
Drupal\swagger_ui_formatter\Service\SwaggerUiLibraryDiscovery

File

src/Service/SwaggerUiLibraryDiscovery.php, line 27

Namespace

Drupal\swagger_ui_formatter\Service
View source
final class SwaggerUiLibraryDiscovery implements SwaggerUiLibraryDiscoveryInterface, ContainerInjectionInterface, CacheableDependencyInterface {

  /**
   * Swagger UI library path related cache ID.
   */
  private const LIBRARY_PATH_CID = 'swagger_ui_formatter:library_path';

  /**
   * The minimum supported Swagger UI library version.
   */
  public const MIN_SUPPORTED_LIBRARY_VERSION = '3.32.2';

  /**
   * The default cache bin.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  private $cache;

  /**
   * The theme handler service.
   *
   * @var \Drupal\Core\Extension\ThemeHandlerInterface
   */
  private $themeHandler;

  /**
   * The theme manager service.
   *
   * @var \Drupal\Core\Theme\ThemeManagerInterface
   */
  private $themeManager;

  /**
   * The theme initialization service.
   *
   * @var \Drupal\Core\Theme\ThemeInitializationInterface
   */
  private $themeInitialization;

  /**
   * Constructs a SwaggerUiLibraryDiscovery instance.
   *
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The default cache bin.
   * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
   *   The theme handler service.
   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
   *   The theme manager service.
   * @param \Drupal\Core\Theme\ThemeInitializationInterface $theme_initialization
   *   The theme initialization service.
   */
  public function __construct(CacheBackendInterface $cache, ThemeHandlerInterface $theme_handler, ThemeManagerInterface $theme_manager, ThemeInitializationInterface $theme_initialization) {
    $this->cache = $cache;
    $this->themeHandler = $theme_handler;
    $this->themeManager = $theme_manager;
    $this->themeInitialization = $theme_initialization;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {

    // Make it work in hook_requirements() from the "install" phase.
    return new static($container
      ->get('cache.default'), $container
      ->get('theme_handler'), $container
      ->get('theme.manager'), $container
      ->get('theme.initialization'));
  }

  /**
   * {@inheritdoc}
   */
  public function libraryDirectory() : string {
    $cache = $this->cache
      ->get(self::LIBRARY_PATH_CID);
    if ($cache) {
      return $cache->data;
    }

    // The default library directory (relative to DRUPAL_ROOT).
    $library_dir = 'libraries/swagger-ui';

    // Allow the default theme to alter the default library directory.
    $default_theme = $this->themeInitialization
      ->getActiveThemeByName($this->themeHandler
      ->getDefault());
    $this->themeInitialization
      ->loadActiveTheme($default_theme);

    // The hook is only invoked for the default theme (and its base themes).
    $this->themeManager
      ->alterForTheme($default_theme, 'swagger_ui_library_directory', $library_dir);

    // Make sure that the directory path is relative (to DRUPAL ROOT).
    $library_dir = ltrim($library_dir, '/');
    $this
      ->validateLibraryDirectory(DRUPAL_ROOT . '/' . $library_dir);

    // Save the library directory to cache so we can save some computation time.
    $this->cache
      ->set(self::LIBRARY_PATH_CID, $library_dir, $this
      ->getCacheMaxAge(), $this
      ->getCacheTags());
    return $library_dir;
  }

  /**
   * {@inheritdoc}
   */
  public function libraryVersion() : string {
    $library_dir = $this
      ->libraryDirectory();
    $package_json_path = DRUPAL_ROOT . '/' . $library_dir . '/package.json';
    $package_json_content = file_get_contents($package_json_path);
    if (!$package_json_content) {
      throw SwaggerUiLibraryDiscoveryException::becauseCannotReadPackageJsonContent($package_json_path);
    }
    $data = Json::decode($package_json_content);
    if (json_last_error() !== JSON_ERROR_NONE) {
      throw SwaggerUiLibraryDiscoveryException::becausePackageJsonCannotBeDecoded($package_json_path, json_last_error_msg());
    }
    if (!isset($data['version'])) {
      throw SwaggerUiLibraryDiscoveryException::becauseUnableToIdentifyLibraryVersion($package_json_path);
    }
    if (version_compare($data['version'], self::MIN_SUPPORTED_LIBRARY_VERSION, '<')) {
      throw SwaggerUiLibraryDiscoveryException::becauseLibraryVersionIsNotSupported($data['version'], self::MIN_SUPPORTED_LIBRARY_VERSION);
    }
    return $data['version'];
  }

  /**
   * Validates a given Swagger UI library directory.
   *
   * @param string $library_dir
   *   The directory path which contains the Swagger UI library.
   *
   * @throws \Drupal\swagger_ui_formatter\Exception\SwaggerUiLibraryDiscoveryException
   */
  private function validateLibraryDirectory(string $library_dir) : void {
    if (!file_exists($library_dir)) {
      throw SwaggerUiLibraryDiscoveryException::becauseLibraryDirectoryIsInvalid($library_dir);
    }
    $files_to_check = [
      'package.json',
      'dist/swagger-ui.css',
      'dist/swagger-ui-bundle.js',
      'dist/swagger-ui-standalone-preset.js',
      'dist/oauth2-redirect.html',
    ];
    foreach ($files_to_check as $file) {
      $file_path = $library_dir . '/' . $file;
      if (!file_exists($file_path)) {
        throw SwaggerUiLibraryDiscoveryException::becauseRequiredLibraryFileIsNotFound($file_path);
      }
    }
  }

  /**
   * Clears internal cache.
   */
  public function reset() : void {
    $this->cache
      ->delete(self::LIBRARY_PATH_CID);
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheContexts() : array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheTags() : array {
    return [
      self::LIBRARY_PATH_CID,
      'config:system.theme',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() : int {
    return CacheBackendInterface::CACHE_PERMANENT;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SwaggerUiLibraryDiscovery::$cache private property The default cache bin.
SwaggerUiLibraryDiscovery::$themeHandler private property The theme handler service.
SwaggerUiLibraryDiscovery::$themeInitialization private property The theme initialization service.
SwaggerUiLibraryDiscovery::$themeManager private property The theme manager service.
SwaggerUiLibraryDiscovery::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create
SwaggerUiLibraryDiscovery::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts
SwaggerUiLibraryDiscovery::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge
SwaggerUiLibraryDiscovery::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags
SwaggerUiLibraryDiscovery::libraryDirectory public function Gets the Swagger UI library directory. Overrides SwaggerUiLibraryDiscoveryInterface::libraryDirectory
SwaggerUiLibraryDiscovery::libraryVersion public function Gets the Swagger UI library version. Overrides SwaggerUiLibraryDiscoveryInterface::libraryVersion
SwaggerUiLibraryDiscovery::LIBRARY_PATH_CID private constant Swagger UI library path related cache ID.
SwaggerUiLibraryDiscovery::MIN_SUPPORTED_LIBRARY_VERSION public constant The minimum supported Swagger UI library version.
SwaggerUiLibraryDiscovery::reset public function Clears internal cache.
SwaggerUiLibraryDiscovery::validateLibraryDirectory private function Validates a given Swagger UI library directory.
SwaggerUiLibraryDiscovery::__construct public function Constructs a SwaggerUiLibraryDiscovery instance.