diff --git a/package_manager/src/Event/PostRequireEvent.php b/package_manager/src/Event/PostRequireEvent.php index c35076f5cf905eee0a28921f5013ddf33b764a51..b35f7918749a3c764b8ff9270fd0283769612dd8 100644 --- a/package_manager/src/Event/PostRequireEvent.php +++ b/package_manager/src/Event/PostRequireEvent.php @@ -6,4 +6,7 @@ namespace Drupal\package_manager\Event; * Event fired after packages are updated to the staging area. */ class PostRequireEvent extends StageEvent { + + use RequireEventTrait; + } diff --git a/package_manager/src/Event/PreRequireEvent.php b/package_manager/src/Event/PreRequireEvent.php index bcb9bfc6337e449fd180a9a8cc027acc0cb500fe..ff74da6ad1e93123de2c125970c41dfe3b8ffaad 100644 --- a/package_manager/src/Event/PreRequireEvent.php +++ b/package_manager/src/Event/PreRequireEvent.php @@ -6,4 +6,7 @@ namespace Drupal\package_manager\Event; * Event fired before packages are updated to the staging area. */ class PreRequireEvent extends PreOperationStageEvent { + + use RequireEventTrait; + } diff --git a/package_manager/src/Event/RequireEventTrait.php b/package_manager/src/Event/RequireEventTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..50a4d54b9f333371a8271856698d1dff75899c3d --- /dev/null +++ b/package_manager/src/Event/RequireEventTrait.php @@ -0,0 +1,89 @@ +<?php + +namespace Drupal\package_manager\Event; + +use Drupal\package_manager\Stage; + +/** + * Common methods for pre- and post-require events. + * + * @internal + * This is an internal part of Automatic Updates and should only be used by + * \Drupal\package_manager\Event\PreRequireEvent and + * \Drupal\package_manager\Event\PostRequireEvent. + */ +trait RequireEventTrait { + + /** + * The runtime packages, in the form 'vendor/name:constraint'. + * + * @var string[] + */ + private $runtimePackages; + + /** + * The dev packages to be required, in the form 'vendor/name:constraint'. + * + * @var string[] + */ + private $devPackages; + + /** + * Constructs the object. + * + * @param \Drupal\package_manager\Stage $stage + * The stage. + * @param string[] $runtime_packages + * The runtime (i.e., non-dev) packages to be required, in the form + * 'vendor/name:constrant'. + * @param string[] $dev_packages + * The dev packages to be required, in the form 'vendor/name:constrant'. + */ + public function __construct(Stage $stage, array $runtime_packages, array $dev_packages = []) { + $this->runtimePackages = $runtime_packages; + $this->devPackages = $dev_packages; + parent::__construct($stage); + } + + /** + * Gets the runtime (i.e., non-dev) packages. + * + * @return string[] + * An array of packages where the values are version constraints and keys + * are package names in the form 'vendor/name'. + */ + public function getRuntimePackages(): array { + return $this->getKeyedPackages($this->runtimePackages); + } + + /** + * Gets the dev packages. + * + * @return string[] + * An array of packages where the values are version constraints and keys + * are package names in the form 'vendor/name'. + */ + public function getDevPackages(): array { + return $this->getKeyedPackages($this->devPackages); + } + + /** + * Gets packages as a keyed array. + * + * @param string[] $packages + * The packages, in the form 'vendor/name:version'. + * + * @return string[] + * An array of packages where the values are version constraints and keys + * are package names in the form 'vendor/name'. + */ + private function getKeyedPackages(array $packages): array { + $keyed_packages = []; + foreach ($packages as $package) { + [$name, $constraint] = explode(':', $package); + $keyed_packages[$name] = $constraint; + } + return $keyed_packages; + } + +} diff --git a/package_manager/src/Stage.php b/package_manager/src/Stage.php index b2dcac50f79e9f10f3aba18e65d09b2a910a323e..49acc42a4f4d71c4dc6f6bdeb42b333c68ad46ba 100644 --- a/package_manager/src/Stage.php +++ b/package_manager/src/Stage.php @@ -301,7 +301,7 @@ class Stage { public function require(array $runtime, array $dev = []): void { $this->checkOwnership(); - $this->dispatch(new PreRequireEvent($this)); + $this->dispatch(new PreRequireEvent($this, $runtime, $dev)); $dir = $this->getStageDirectory(); // Change the runtime and dev requirements as needed, but don't update @@ -321,7 +321,7 @@ class Stage { $this->stager->stage($command, $dir); } - $this->dispatch(new PostRequireEvent($this)); + $this->dispatch(new PostRequireEvent($this, $runtime, $dev)); } /** diff --git a/package_manager/tests/src/Kernel/StageEventsTest.php b/package_manager/tests/src/Kernel/StageEventsTest.php index 34cd73eef1e9b04323d6622b902d68df18bf209e..16c28129f1ba53a65dc4ef6bda5c4f6ec5642908 100644 --- a/package_manager/tests/src/Kernel/StageEventsTest.php +++ b/package_manager/tests/src/Kernel/StageEventsTest.php @@ -160,4 +160,25 @@ class StageEventsTest extends PackageManagerKernelTestBase implements EventSubsc } } + /** + * Tests that pre- and post-require events have access to the package lists. + */ + public function testPackageListsAvailableToRequireEvents(): void { + $listener = function (object $event): void { + $expected_runtime = ['drupal/core' => '9.8.2']; + $expected_dev = ['drupal/core-dev' => '9.8.2']; + + /** @var \Drupal\package_manager\Event\PreRequireEvent|\Drupal\package_manager\Event\PostRequireEvent $event */ + $this->assertSame($expected_runtime, $event->getRuntimePackages()); + $this->assertSame($expected_dev, $event->getDevPackages()); + }; + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher */ + $event_dispatcher = $this->container->get('event_dispatcher'); + $event_dispatcher->addListener(PreRequireEvent::class, $listener); + $event_dispatcher->addListener(PostRequireEvent::class, $listener); + + $this->stage->create(); + $this->stage->require(['drupal/core:9.8.2'], ['drupal/core-dev:9.8.2']); + } + }