diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 86d4a5356..793e74d2b 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -195,7 +195,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface } if ($eventDispatcher) { - $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], $package); + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], 'package', $package); $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); } diff --git a/src/Composer/Plugin/PluginInterface.php b/src/Composer/Plugin/PluginInterface.php index f18799e7b..305a784bc 100644 --- a/src/Composer/Plugin/PluginInterface.php +++ b/src/Composer/Plugin/PluginInterface.php @@ -32,7 +32,7 @@ interface PluginInterface * * @var string */ - const PLUGIN_API_VERSION = '2.0.0'; + const PLUGIN_API_VERSION = '2.1.0'; /** * Apply plugin modifications to Composer diff --git a/src/Composer/Plugin/PostFileDownloadEvent.php b/src/Composer/Plugin/PostFileDownloadEvent.php index 370f58cd4..665bce128 100644 --- a/src/Composer/Plugin/PostFileDownloadEvent.php +++ b/src/Composer/Plugin/PostFileDownloadEvent.php @@ -38,32 +38,47 @@ class PostFileDownloadEvent extends Event private $url; /** - * @var \Composer\Package\PackageInterface + * @var mixed */ - private $package; + private $context; + + /** + * @var string + */ + private $type; /** * Constructor. * * @param string $name The event name - * @param string $fileName The file name + * @param string|null $fileName The file name * @param string|null $checksum The checksum * @param string $url The processed url - * @param PackageInterface $package The package. + * @param string $type The type (package or metadata). + * @param mixed $context Additional context for the download. */ - public function __construct($name, $fileName, $checksum, $url, PackageInterface $package) + public function __construct($name, $fileName, $checksum, $url, $type, $context = null) { + if ($context === null && $type instanceof PackageInterface) { + $context = $type; + $type = 'package'; + trigger_error('PostFileDownloadEvent::__construct should receive a $type=package and the package object in $context since Composer 2.1.', E_USER_DEPRECATED); + } + parent::__construct($name); $this->fileName = $fileName; $this->checksum = $checksum; $this->url = $url; - $this->package = $package; + $this->context = $context; + $this->type = $type; } /** * Retrieves the target file name location. * - * @return string + * If this download is of type metadata, null is returned. + * + * @return string|null */ public function getFileName() { @@ -90,13 +105,42 @@ class PostFileDownloadEvent extends Event return $this->url; } + /** + * Returns the context of this download, if any. + * + * If this download is of type package, the package object is returned. If + * this download is of type metadata, an array{response: Response, repository: RepositoryInterface} is returned. + * + * @return mixed + */ + public function getContext() + { + return $this->context; + } + /** * Get the package. * - * @return \Composer\Package\PackageInterface The package. + * If this download is of type metadata, null is returned. + * + * @return \Composer\Package\PackageInterface|null The package. + * @deprecated Use getContext instead */ public function getPackage() { - return $this->package; + trigger_error('PostFileDownloadEvent::getPackage is deprecated since Composer 2.1, use getContext instead.', E_USER_DEPRECATED); + $context = $this->getContext(); + + return $context instanceof PackageInterface ? $context : null; + } + + /** + * Returns the type of this download (package, metadata). + * + * @return string + */ + public function getType() + { + return $this->type; } } diff --git a/src/Composer/Plugin/PreFileDownloadEvent.php b/src/Composer/Plugin/PreFileDownloadEvent.php index b741d4646..4372bedd6 100644 --- a/src/Composer/Plugin/PreFileDownloadEvent.php +++ b/src/Composer/Plugin/PreFileDownloadEvent.php @@ -127,6 +127,7 @@ class PreFileDownloadEvent extends Event * Returns the context of this download, if any. * * If this download is of type package, the package object is returned. + * If the type is metadata, an array{repository: RepositoryInterface} is returned. * * @return mixed */ diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 308972309..569d4a110 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -24,6 +24,7 @@ use Composer\Json\JsonFile; use Composer\Cache; use Composer\Config; use Composer\IO\IOInterface; +use Composer\Plugin\PostFileDownloadEvent; use Composer\Semver\CompilingMatcher; use Composer\Util\HttpDownloader; use Composer\Util\Loop; @@ -1088,7 +1089,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito while ($retries--) { try { if ($this->eventDispatcher) { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this)); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1113,6 +1114,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.'); } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', array('response' => $response, 'repository' => $this)); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1175,7 +1181,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito while ($retries--) { try { if ($this->eventDispatcher) { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this)); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1191,6 +1197,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($this->eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', array('response' => $response, 'repository' => $this)); + $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($this->io, $this->url, $data); @@ -1244,7 +1255,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $httpDownloader = $this->httpDownloader; if ($this->eventDispatcher) { - $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata'); + $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this)); $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent); $filename = $preFileDownloadEvent->getProcessedUrl(); } @@ -1261,9 +1272,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito $url = $this->url; $cache = $this->cache; $degradedMode = &$this->degradedMode; + $eventDispatcher = $this->eventDispatcher; $repo = $this; - $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $repo) { + $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher, $repo) { // package not found is acceptable for a v2 protocol repository if ($response->getStatusCode() === 404) { $repo->packagesNotFoundCache[$filename] = true; @@ -1278,6 +1290,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito return true; } + if ($eventDispatcher) { + $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $url, 'metadata', array('response' => $response, 'repository' => $repo)); + $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent); + } + $data = $response->decodeJson(); HttpDownloader::outputWarnings($io, $url, $data); diff --git a/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json index aa44b5a3d..c2a347a51 100644 --- a/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json +++ b/tests/Composer/Test/Plugin/Fixtures/plugin-v8/composer.json @@ -9,6 +9,6 @@ ] }, "require": { - "composer-plugin-api": "2.0.0" + "composer-plugin-api": "^2.0.0" } }