From 68ff0721ce486502fe717d7aaf2cef6be76b892f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Mon, 2 Feb 2026 18:44:44 +0100 Subject: [PATCH] Merged functionality from UpdateAvailableManager and UpdateChecker --- src/Command/UpdateCommand.php | 4 +- src/Controller/HomepageController.php | 4 +- src/Controller/ToolsController.php | 4 +- src/Controller/UpdateManagerController.php | 2 +- ...eManager.php => UpdateAvailableFacade.php} | 46 ++++--------------- src/Services/System/UpdateChecker.php | 27 ++++++----- src/Twig/UpdateExtension.php | 4 +- 7 files changed, 34 insertions(+), 57 deletions(-) rename src/Services/System/{UpdateAvailableManager.php => UpdateAvailableFacade.php} (67%) diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php index 64fa2bad..ca6c8399 100644 --- a/src/Command/UpdateCommand.php +++ b/src/Command/UpdateCommand.php @@ -166,7 +166,7 @@ HELP $includePrerelease = $input->getOption('include-prerelease'); if (!$targetVersion) { - $latest = $this->updateChecker->getLatestRelease($includePrerelease); + $latest = $this->updateChecker->getLatestVersion($includePrerelease); if (!$latest) { $io->error('Could not determine the latest version. Please specify a version manually.'); return Command::FAILURE; @@ -175,7 +175,7 @@ HELP } // Validate target version - if (!$this->updateChecker->isNewerVersion($targetVersion)) { + if (!$this->updateChecker->isNewerVersionThanCurrent($targetVersion)) { $io->warning(sprintf( 'Version %s is not newer than the current version %s.', $targetVersion, diff --git a/src/Controller/HomepageController.php b/src/Controller/HomepageController.php index 6192c249..6f863a3c 100644 --- a/src/Controller/HomepageController.php +++ b/src/Controller/HomepageController.php @@ -26,7 +26,7 @@ use App\DataTables\LogDataTable; use App\Entity\Parts\Part; use App\Services\System\BannerHelper; use App\Services\System\GitVersionInfoProvider; -use App\Services\System\UpdateAvailableManager; +use App\Services\System\UpdateAvailableFacade; use Doctrine\ORM\EntityManagerInterface; use Omines\DataTablesBundle\DataTableFactory; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -44,7 +44,7 @@ class HomepageController extends AbstractController #[Route(path: '/', name: 'homepage')] public function homepage(Request $request, GitVersionInfoProvider $versionInfo, EntityManagerInterface $entityManager, - UpdateAvailableManager $updateAvailableManager): Response + UpdateAvailableFacade $updateAvailableManager): Response { $this->denyAccessUnlessGranted('HAS_ACCESS_PERMISSIONS'); diff --git a/src/Controller/ToolsController.php b/src/Controller/ToolsController.php index f1ed888c..76dffb4d 100644 --- a/src/Controller/ToolsController.php +++ b/src/Controller/ToolsController.php @@ -28,7 +28,7 @@ use App\Services\Attachments\BuiltinAttachmentsFinder; use App\Services\Doctrine\DBInfoHelper; use App\Services\Doctrine\NatsortDebugHelper; use App\Services\System\GitVersionInfoProvider; -use App\Services\System\UpdateAvailableManager; +use App\Services\System\UpdateAvailableFacade; use App\Settings\AppSettings; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -48,7 +48,7 @@ class ToolsController extends AbstractController #[Route(path: '/server_infos', name: 'tools_server_infos')] public function systemInfos(GitVersionInfoProvider $versionInfo, DBInfoHelper $DBInfoHelper, NatsortDebugHelper $natsortDebugHelper, - AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager, + AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableFacade $updateAvailableManager, AppSettings $settings): Response { $this->denyAccessUnlessGranted('@system.server_infos'); diff --git a/src/Controller/UpdateManagerController.php b/src/Controller/UpdateManagerController.php index 08f7c77f..d88cab5d 100644 --- a/src/Controller/UpdateManagerController.php +++ b/src/Controller/UpdateManagerController.php @@ -226,7 +226,7 @@ class UpdateManagerController extends AbstractController if (!$targetVersion) { // Get latest version if not specified - $latest = $this->updateChecker->getLatestRelease(); + $latest = $this->updateChecker->getLatestVersion(); if (!$latest) { $this->addFlash('error', 'Could not determine target version.'); return $this->redirectToRoute('admin_update_manager'); diff --git a/src/Services/System/UpdateAvailableManager.php b/src/Services/System/UpdateAvailableFacade.php similarity index 67% rename from src/Services/System/UpdateAvailableManager.php rename to src/Services/System/UpdateAvailableFacade.php index 82cfb84e..2a00321c 100644 --- a/src/Services/System/UpdateAvailableManager.php +++ b/src/Services/System/UpdateAvailableFacade.php @@ -35,17 +35,18 @@ use Version\Version; /** * This class checks if a new version of Part-DB is available. */ -class UpdateAvailableManager +class UpdateAvailableFacade { private const API_URL = 'https://api.github.com/repos/Part-DB/Part-DB-server/releases/latest'; private const CACHE_KEY = 'uam_latest_version'; private const CACHE_TTL = 60 * 60 * 24 * 2; // 2 day - public function __construct(private readonly HttpClientInterface $httpClient, - private readonly CacheInterface $updateCache, private readonly VersionManagerInterface $versionManager, - private readonly PrivacySettings $privacySettings, private readonly LoggerInterface $logger, - #[Autowire(param: 'kernel.debug')] private readonly bool $is_dev_mode) + public function __construct( + private readonly CacheInterface $updateCache, + private readonly PrivacySettings $privacySettings, + private readonly UpdateChecker $updateChecker, + ) { } @@ -89,9 +90,7 @@ class UpdateAvailableManager } $latestVersion = $this->getLatestVersion(); - $currentVersion = $this->versionManager->getVersion(); - - return $latestVersion->isGreaterThan($currentVersion); + return $this->updateChecker->isNewerVersionThanCurrent($latestVersion); } /** @@ -111,34 +110,7 @@ class UpdateAvailableManager return $this->updateCache->get(self::CACHE_KEY, function (ItemInterface $item) { $item->expiresAfter(self::CACHE_TTL); - try { - $response = $this->httpClient->request('GET', self::API_URL); - $result = $response->toArray(); - $tag_name = $result['tag_name']; - - // Remove the leading 'v' from the tag name - $version = substr($tag_name, 1); - - return [ - 'version' => $version, - 'url' => $result['html_url'], - ]; - } catch (\Exception $e) { - //When we are in dev mode, throw the exception, otherwise just silently log it - if ($this->is_dev_mode) { - throw $e; - } - - //In the case of an error, try it again after half of the cache time - $item->expiresAfter(self::CACHE_TTL / 2); - - $this->logger->error('Checking for updates failed: ' . $e->getMessage()); - - return [ - 'version' => '0.0.1', - 'url' => 'update-checking-error' - ]; - } + return $this->updateChecker->getLatestVersion(); }); } -} \ No newline at end of file +} diff --git a/src/Services/System/UpdateChecker.php b/src/Services/System/UpdateChecker.php index b7a90296..e388d51f 100644 --- a/src/Services/System/UpdateChecker.php +++ b/src/Services/System/UpdateChecker.php @@ -75,7 +75,7 @@ class UpdateChecker * Get Git repository information. * @return array{branch: ?string, commit: ?string, has_local_changes: bool, commits_behind: int, is_git_install: bool} */ - public function getGitInfo(): array + private function getGitInfo(): array { $info = [ 'branch' => null, @@ -113,7 +113,7 @@ class UpdateChecker return 0; } - $cacheKey = self::CACHE_KEY_COMMITS . '_' . md5($branch); + $cacheKey = self::CACHE_KEY_COMMITS . '_' . hash('xxh3', $branch); return $this->updateCache->get($cacheKey, function (ItemInterface $item) use ($branch) { $item->expiresAfter(self::CACHE_TTL); @@ -135,9 +135,9 @@ class UpdateChecker */ public function refreshVersionInfo(): void { - $gitInfo = $this->getGitInfo(); - if ($gitInfo['branch']) { - $this->updateCache->delete(self::CACHE_KEY_COMMITS . '_' . md5($gitInfo['branch'])); + $gitBranch = $this->gitVersionInfoProvider->getBranchName(); + if ($gitBranch) { + $this->updateCache->delete(self::CACHE_KEY_COMMITS . '_' . hash('xxh3', $gitBranch)); } $this->updateCache->delete(self::CACHE_KEY_RELEASES); } @@ -150,7 +150,10 @@ class UpdateChecker public function getAvailableReleases(int $limit = 10): array { if (!$this->privacySettings->checkForUpdates) { - return []; + return [ //If we don't want to check for updates, we can return dummy data + 'version' => '0.0.1', + 'url' => 'update-checking-disabled' + ]; } return $this->updateCache->get(self::CACHE_KEY_RELEASES, function (ItemInterface $item) use ($limit) { @@ -212,7 +215,7 @@ class UpdateChecker * Get the latest stable release. * @return array{version: string, tag: string, name: string, url: string, published_at: string, body: string, prerelease: bool, assets: array}|null */ - public function getLatestRelease(bool $includePrerelease = false): ?array + public function getLatestVersion(bool $includePrerelease = false): ?array { $releases = $this->getAvailableReleases(); @@ -236,11 +239,13 @@ class UpdateChecker /** * Check if a specific version is newer than current. */ - public function isNewerVersion(string $version): bool + public function isNewerVersionThanCurrent(Version|string $version): bool { + if ($version instanceof Version) { + return $version->isGreaterThan($this->getCurrentVersion()); + } try { - $targetVersion = Version::fromString(ltrim($version, 'v')); - return $targetVersion->isGreaterThan($this->getCurrentVersion()); + return Version::fromString(ltrim($version, 'v'))->isGreaterThan($this->getCurrentVersion()); } catch (\Exception) { return false; } @@ -254,7 +259,7 @@ class UpdateChecker public function getUpdateStatus(): array { $current = $this->getCurrentVersion(); - $latest = $this->getLatestRelease(); + $latest = $this->getLatestVersion(); $gitInfo = $this->getGitInfo(); $installInfo = $this->installationTypeDetector->getInstallationInfo(); diff --git a/src/Twig/UpdateExtension.php b/src/Twig/UpdateExtension.php index 10264d12..ee3bb16c 100644 --- a/src/Twig/UpdateExtension.php +++ b/src/Twig/UpdateExtension.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace App\Twig; -use App\Services\System\UpdateAvailableManager; +use App\Services\System\UpdateAvailableFacade; use Symfony\Bundle\SecurityBundle\Security; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; @@ -33,7 +33,7 @@ use Twig\TwigFunction; */ final class UpdateExtension extends AbstractExtension { - public function __construct(private readonly UpdateAvailableManager $updateAvailableManager, + public function __construct(private readonly UpdateAvailableFacade $updateAvailableManager, private readonly Security $security) {