composer = $composer; $this->io = $io; $this->disabledDownloaders = $disabledDownloaders; // If --no-cache is passed to Composer, we need a different location to // download patches to. When --no-cache is passed, $composer_cache is // set to /dev/null. $composer_cache = $composer->getConfig()->get('cache-dir'); if (!is_dir($composer_cache)) { $composer_cache = sys_get_temp_dir(); } // If the cache directory doesn't exist, create it. $this->cacheDir = $composer_cache . '/patches'; if (!is_dir($this->cacheDir)) { mkdir($this->cacheDir); } } /** * Download a patch using the available downloaders. * * A downloader will update Patch->localPath if it was able to download the patch. * * @param Patch $patch * The patch to download. */ public function downloadPatch(Patch $patch) { if (isset($patch->sha256)) { $cachedPatch = $this->cacheDir . '/' . $patch->sha256 . '.patch'; if (file_exists($cachedPatch)) { $this->io->write(" - Found cached patch at {$cachedPatch}", IOInterface::VERBOSE); $patch->localPath = $cachedPatch; return; } } foreach ($this->getDownloaders() as $downloader) { $class = "\\" . get_class($downloader); if (in_array($class, $this->disabledDownloaders, true)) { $this->io->write( ' - Skipping downloader ' . $class . '', true, IOInterface::VERBOSE ); continue; } $downloader->download($patch); if (isset($patch->localPath)) { $cachedPatch = $this->cacheDir . '/' . $patch->sha256 . '.patch'; if (rename($patch->localPath, $cachedPatch)) { $patch->localPath = $cachedPatch; } return; } } } /** * Gather a list of all patch downloaders from all enabled Composer plugins. * * @return DownloaderInterface[] * A list of Downloaders that are available. */ protected function getDownloaders(): array { static $downloaders; if (!is_null($downloaders)) { return $downloaders; } $downloaders = []; $plugin_manager = $this->composer->getPluginManager(); $capabilities = $plugin_manager->getPluginCapabilities( DownloaderProvider::class, ['composer' => $this->composer, 'io' => $this->io] ); foreach ($capabilities as $capability) { /** @var DownloaderProvider $capability */ $newDownloaders = $capability->getDownloaders(); foreach ($newDownloaders as $downloader) { if (!$downloader instanceof DownloaderInterface) { throw new UnexpectedValueException( 'Plugin capability ' . get_class($capability) . ' returned an invalid value.' ); } } $downloaders = array_merge($downloaders, $newDownloaders); } $event = new PluginEvent(PluginEvents::POST_DISCOVER_DOWNLOADERS, $downloaders, $this->composer, $this->io); $this->composer->getEventDispatcher()->dispatch(PluginEvents::POST_DISCOVER_DOWNLOADERS, $event); $downloaders = $event->getCapabilities(); return $downloaders; } }