rosetta_translation-1.0.0-alpha1/src/Service/RosettaVersionManager.php

src/Service/RosettaVersionManager.php
<?php

declare(strict_types=1);

namespace Drupal\rosetta_translation\Service;

use Drupal\Core\Cache\CacheBackendInterface;
use GuzzleHttp\ClientInterface;
use Psr\Log\LoggerInterface;

/**
 * Fetches and provides Rosetta release tags from GitHub.
 */
final class RosettaVersionManager {

  private const CACHE_ID = 'rosetta_translation:github_tags';
  private const CACHE_TTL = 3600; // 1 hour.

  public function __construct(
    private readonly ClientInterface $httpClient,
    private readonly CacheBackendInterface $cache,
    private readonly LoggerInterface $logger,
  ) {}

  /**
   * Return releases (tags) sorted desc by semantic version if possible.
   *
   * @return string[]
   *   List of tag names, newest first.
   */
  public function getTags(): array {
    if ($cache = $this->cache->get(self::CACHE_ID)) {
      return is_array($cache->data) ? $cache->data : [];
    }
    try {
      $response = $this->httpClient->request('GET', 'https://api.github.com/repos/au5ton/rosetta/tags', [
        'headers' => [
          'Accept' => 'application/vnd.github+json',
          'User-Agent' => 'rosetta-translation-module',
        ],
        'timeout' => 5,
      ]);
      $data = json_decode((string) $response->getBody(), TRUE) ?: [];
      $tags = array_values(array_filter(array_map(static fn ($i) => $i['name'] ?? NULL, $data)));
      // Sort semver-desc if possible.
      usort($tags, static function (string $a, string $b): int {
        $normalize = static fn (string $v) => array_map('intval', explode('.', ltrim($v, 'v')));
        $aa = $normalize($a);
        $bb = $normalize($b);
        for ($i = 0; $i < 3; $i++) {
          $ai = $aa[$i] ?? 0; $bi = $bb[$i] ?? 0;
          if ($ai === $bi) { continue; }
          return $bi <=> $ai;
        }
        return 0;
      });
      $this->cache->set(self::CACHE_ID, $tags, time() + self::CACHE_TTL);
      return $tags;
    }
    catch (\Throwable $e) {
      $this->logger->warning('Failed fetching Rosetta tags: @message', ['@message' => $e->getMessage()]);
      return [];
    }
  }

  /**
   * Resolve a configured version to a concrete tag.
   */
  public function resolveVersion(string $configured): ?string {
    $configured = trim($configured);
    if ($configured === '' || strtolower($configured) === 'latest') {
      $tags = $this->getTags();
      return $tags[0] ?? NULL;
    }
    return $configured;
  }

  /**
   * Build a raw GitHub content URL for the dist file at a given tag.
   */
  public function buildDistUrl(string $tag): string {
    // Prefer jsDelivr GitHub CDN to ensure proper JS content-type and caching.
    $tag = ltrim($tag, 'v');
    return "https://cdn.jsdelivr.net/gh/au5ton/rosetta@{$tag}/dist/index.js";
  }
}

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

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