/
githubmirror
/
symfony
Обзор
Документация
Войти
/
githubmirror
/
symfony
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
8.2
src/Symfony/Component/AssetMapper/ImportMap/RemotePackageDownloader.php
173 строки
6 KB
Nicolas Grekas
[AssetMapper] Various fixes and hardenings
18 май 2026, 19:32
18 май 2026, 19:32
e06a7ee
Код
Авторство
О чём код?
<?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\AssetMapper\ImportMap; use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolverInterface; use Symfony\Component\Filesystem\Filesystem; /** * @final */ class RemotePackageDownloader { private array $installed; private readonly Filesystem $filesystem; public function __construct( private readonly RemotePackageStorage $remotePackageStorage, private readonly ImportMapConfigReader $importMapConfigReader, private readonly PackageResolverInterface $packageResolver, ) { $this->filesystem = new Filesystem(); } /** * Downloads all packages. * * @return string[] The downloaded packages */ public function downloadPackages(?callable $progressCallback = null): array { try { $installed = $this->loadInstalled(); } catch (\InvalidArgumentException) { $installed = []; } $entries = $this->importMapConfigReader->getEntries(); $remoteEntriesToDownload = []; $newInstalled = []; foreach ($entries as $entry) { if (!$entry->isRemotePackage()) { continue; } // if the file exists at the correct version, skip it if ( isset($installed[$entry->importName]) && $installed[$entry->importName]['version'] === $entry->version && $this->remotePackageStorage->isDownloaded($entry) && $this->areAllExtraFilesDownloaded($entry, $installed[$entry->importName]['extraFiles']) ) { $newInstalled[$entry->importName] = $installed[$entry->importName]; continue; } $remoteEntriesToDownload[$entry->importName] = $entry; } if (!$remoteEntriesToDownload) { return []; } $contents = $this->packageResolver->downloadPackages($remoteEntriesToDownload, $progressCallback); $downloadedPackages = []; foreach ($remoteEntriesToDownload as $package => $entry) { if (!isset($contents[$package])) { throw new \LogicException(\sprintf('The package "%s" was not downloaded.', $package)); } $this->remotePackageStorage->save($entry, $contents[$package]['content']); foreach ($contents[$package]['extraFiles'] as $extraFilename => $extraFileContents) { $this->remotePackageStorage->saveExtraFile($entry, $extraFilename, $extraFileContents); } $newInstalled[$package] = [ 'version' => $entry->version, 'dependencies' => $contents[$package]['dependencies'] ?? [], 'extraFiles' => array_keys($contents[$package]['extraFiles']), ]; $downloadedPackages[] = $package; unset($contents[$package]); } if ($contents) { throw new \LogicException(\sprintf('The following packages were unexpectedly downloaded: "%s".', implode('", "', array_keys($contents)))); } $this->saveInstalled($newInstalled); return $downloadedPackages; } /** * @return string[] */ public function getDependencies(string $importName): array { $installed = $this->loadInstalled(); if (!isset($installed[$importName])) { throw new \InvalidArgumentException(\sprintf('The "%s" vendor asset is missing. Run "php bin/console importmap:install".', $importName)); } return $installed[$importName]['dependencies']; } public function getVendorDir(): string { return $this->remotePackageStorage->getStorageDir(); } /** * @return array<string, array{path: string, version: string, dependencies: array<string, string>, extraFiles: array<string, string>}> */ private function loadInstalled(): array { if (isset($this->installed)) { return $this->installed; } $installedPath = $this->remotePackageStorage->getStorageDir().'/installed.php'; $installed = is_file($installedPath) ? \Closure::bind(static fn () => include $installedPath, null, null)() : []; if (!\is_array($installed)) { throw new \LogicException(\sprintf('The "%s" file must return an array, got "%s".', $installedPath, get_debug_type($installed))); } foreach ($installed as $package => $data) { if (!isset($data['version'])) { throw new \InvalidArgumentException(\sprintf('The package "%s" is missing its version.', $package)); } if (!isset($data['dependencies'])) { throw new \LogicException(\sprintf('The package "%s" is missing its dependencies.', $package)); } if (!isset($data['extraFiles'])) { $installed[$package]['extraFiles'] = []; } } return $this->installed = $installed; } private function saveInstalled(array $installed): void { $this->installed = $installed; $this->filesystem->dumpFile( $this->remotePackageStorage->getStorageDir().'/installed.php', '<?php return '.var_export($installed, true).';', ); } private function areAllExtraFilesDownloaded(ImportMapEntry $entry, array $extraFilenames): bool { foreach ($extraFilenames as $extraFilename) { if (!$this->remotePackageStorage->isExtraFileDownloaded($entry, $extraFilename)) { return false; } } return true; } }