countdown-8.x-1.8/src/Utility/LibraryPathResolver.php

src/Utility/LibraryPathResolver.php
<?php

declare(strict_types=1);

namespace Drupal\countdown\Utility;

use Drupal\Core\Asset\LibrariesDirectoryFileFinder;
use Drupal\Core\DrupalKernel;
use Drupal\Core\File\FileSystemInterface;
use Psr\Log\LoggerInterface;

/**
 * Resolves library installation paths.
 *
 * This utility unifies library path discovery logic previously duplicated
 * across CountdownLibraryPluginBase and CountdownLibraryDiscovery.
 */
class LibraryPathResolver {

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected FileSystemInterface $fileSystem;

  /**
   * The logger service.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected LoggerInterface $logger;

  /**
   * Whether debug mode is enabled.
   *
   * @var bool
   */
  protected bool $debugMode;

  /**
   * Cached library paths.
   *
   * @var array
   */
  protected array $pathCache = [];

  /**
   * Constructs a LibraryPathResolver.
   *
   * @param \Drupal\Core\File\FileSystemInterface $file_system
   *   The file system service.
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger service.
   * @param bool $debug_mode
   *   Whether debug mode is enabled.
   */
  public function __construct(
    FileSystemInterface $file_system,
    LoggerInterface $logger,
    bool $debug_mode = FALSE,
  ) {
    $this->fileSystem = $file_system;
    $this->logger = $logger;
    $this->debugMode = $debug_mode;
  }

  /**
   * Finds a library installation path.
   *
   * @param string $library_id
   *   The library identifier.
   * @param array $possible_names
   *   Array of possible folder names to search.
   *
   * @return string|null
   *   The library path relative to DRUPAL_ROOT, or NULL if not found.
   */
  public function findLibrary(string $library_id, array $possible_names): ?string {
    // Check cache first.
    $cache_key = $library_id . ':' . implode(',', $possible_names);
    if (isset($this->pathCache[$cache_key])) {
      return $this->pathCache[$cache_key];
    }

    // Always include the library ID itself.
    if (!in_array($library_id, $possible_names)) {
      array_unshift($possible_names, $library_id);
    }

    foreach ($possible_names as $name) {
      $path = $this->searchLibraryPath($name);
      if ($path !== NULL) {
        // Ensure path starts with /.
        $path = '/' . ltrim($path, '/');
        $this->pathCache[$cache_key] = $path;

        if ($this->debugMode) {
          $this->logger->debug('Found library @library at path: @path', [
            '@library' => $library_id,
            '@path' => $path,
          ]);
        }

        return $path;
      }
    }

    $this->pathCache[$cache_key] = NULL;
    return NULL;
  }

  /**
   * Searches for a library by folder name.
   *
   * @param string $library_name
   *   The library folder name to search for.
   *
   * @return string|null
   *   The library path or NULL if not found.
   */
  protected function searchLibraryPath(string $library_name): ?string {
    $request = \Drupal::request();

    if (\Drupal::hasService('kernel')) {
      $site_path = \Drupal::getContainer()->getParameter('site.path');
    }
    else {
      $site_path = DrupalKernel::findSitePath($request);
    }

    $root = DRUPAL_ROOT;
    $profile_extension_list = \Drupal::service('extension.list.profile');
    $install_profile = \Drupal::installProfile();

    $libraries_finder = new LibrariesDirectoryFileFinder(
      $root,
      $site_path,
      $profile_extension_list,
      $install_profile
    );

    $result = $libraries_finder->find($library_name);

    if ($result !== FALSE) {
      if ($this->debugMode) {
        $this->logger->debug('Library @name found at: @path', [
          '@name' => $library_name,
          '@path' => $result,
        ]);
      }
      return $result;
    }

    if ($this->debugMode) {
      $this->logger->debug('Library @name not found in any search path.', [
        '@name' => $library_name,
      ]);
    }

    return NULL;
  }

  /**
   * Validates that a library is installed at the given path.
   *
   * @param string $path
   *   The path to validate (relative to DRUPAL_ROOT).
   * @param array $required_files
   *   Array of required file paths relative to library root.
   * @param array $alternative_paths
   *   Array of alternative path sets.
   *
   * @return bool
   *   TRUE if the library is valid at this path, FALSE otherwise.
   */
  public function validateInstallation(string $path, array $required_files, array $alternative_paths = []): bool {
    $path = ltrim($path, '/');
    $full_path = DRUPAL_ROOT . '/' . $path;

    if (!is_dir($full_path)) {
      if ($this->debugMode) {
        $this->logger->debug('Library directory does not exist: @path', [
          '@path' => $full_path,
        ]);
      }
      return FALSE;
    }

    // If no required files, consider it valid.
    if (empty($required_files)) {
      return TRUE;
    }

    // Check primary required files.
    $all_found = TRUE;
    $missing_files = [];

    foreach ($required_files as $file) {
      $file_path = $full_path . '/' . $file;
      if (!file_exists($file_path)) {
        $all_found = FALSE;
        $missing_files[] = $file;
      }
    }

    if ($all_found) {
      return TRUE;
    }

    // Check alternative paths.
    foreach ($alternative_paths as $alt_set) {
      $alt_found = TRUE;
      foreach ($alt_set as $alt_file) {
        $file_path = $full_path . '/' . $alt_file;
        if (!file_exists($file_path)) {
          $alt_found = FALSE;
          break;
        }
      }
      if ($alt_found) {
        return TRUE;
      }
    }

    if ($this->debugMode) {
      $this->logger->debug('Library validation failed. Missing files: @files', [
        '@files' => implode(', ', $missing_files),
      ]);
    }

    return FALSE;
  }

  /**
   * Clears the internal path cache.
   */
  public function clearCache(): void {
    $this->pathCache = [];
  }

}

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

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