diff --git a/services/drupal/composer.patches.json b/services/drupal/composer.patches.json index 6cc1083a42..d7ea0f5f46 100644 --- a/services/drupal/composer.patches.json +++ b/services/drupal/composer.patches.json @@ -39,7 +39,8 @@ "Improve consistency of revision terminology labeling in revision UI": "https://www.drupal.org/files/issues/2021-12-03/2899719-D9_2-36.patch", "Allow reverting current revision": "https://www.drupal.org/files/issues/2021-12-10/allow-reverting-current-rev-3252521-D9_2-5.patch", "Prevent reverting latest revision (custom patch so that it plays nicely with our patches for 3252521 and 2899719)": "patches/disallow-reverting-latest-rev-3252540-D9_2-2-custom.patch", - "Use EPA-preferred terminology for revision reversion operation. This patch needs to be applied on top of the patches for 3252521, 2899719, and 3252540": "patches/rename-revision-revert-operation-button.patch" + "Use EPA-preferred terminology for revision reversion operation. This patch needs to be applied on top of the patches for 3252521, 2899719, and 3252540": "patches/rename-revision-revert-operation-button.patch", + "Improve layout builder performance by reducing number of calls to checkRequirements": "patches/drupal-layout-builder-performance-3186116-11.patch" }, "drupal/s3fs": { "Module should initialize default credentials provider instead of instance profile when use_instance_profile is TRUE": "https://www.drupal.org/files/issues/2020-03-24/3122091-2-s3fs-default-provider.patch", diff --git a/services/drupal/patches/drupal-layout-builder-performance-3186116-11.patch b/services/drupal/patches/drupal-layout-builder-performance-3186116-11.patch new file mode 100644 index 0000000000..77037e010a --- /dev/null +++ b/services/drupal/patches/drupal-layout-builder-performance-3186116-11.patch @@ -0,0 +1,85 @@ +diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +index 587fe66b1f9a6ad0ae6d044ef0dbf09856e0e3c4..96fbf9e0d645ef1e53fd0332553adb856e821ef8 100644 +--- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php ++++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +@@ -62,13 +62,33 @@ protected function getContextDefinitions($plugin_definition) { + */ + public function checkRequirements(array $contexts, array $requirements) { + foreach ($requirements as $requirement) { +- if ($requirement->isRequired() && !$this->getMatchingContexts($contexts, $requirement)) { ++ if ($requirement->isRequired() && !$this->isAnyContextMatching($contexts, $requirement)) { + return FALSE; + } + } + return TRUE; + } + ++ /** ++ * Determines if any contexts satisfy the constraints of a given definition. ++ * ++ * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts ++ * An array of contexts. ++ * @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface $definition ++ * The definition to satisfy. ++ * ++ * @return bool ++ * TRUE if any of the contexts satisfy the constraints, FALSE otherwise. ++ */ ++ private function isAnyContextMatching(array $contexts, ContextDefinitionInterface $definition): bool { ++ foreach ($contexts as $context) { ++ if ($definition->isSatisfiedBy($context)) { ++ return TRUE; ++ } ++ } ++ return FALSE; ++ } ++ + /** + * {@inheritdoc} + */ +diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +index 075cd51d92f6be29e47308b6da15faf8b5dd142d..66c7ffa13033d66b62e078b198833793e9747bc9 100644 +--- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php ++++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +@@ -19,7 +19,9 @@ + use Drupal\Core\DependencyInjection\ContainerBuilder; + use Drupal\Core\Extension\ModuleHandlerInterface; + use Drupal\Core\Plugin\Context\ContextDefinition; ++use Drupal\Core\Plugin\Context\ContextDefinitionInterface; + use Drupal\Core\Plugin\Context\ContextHandler; ++use Drupal\Core\Plugin\Context\ContextInterface; + use Drupal\Core\Plugin\ContextAwarePluginInterface; + use Drupal\Core\TypedData\TypedDataManager; + use Drupal\Core\Validation\ConstraintManager; +@@ -124,6 +126,31 @@ public function providerTestCheckRequirements() { + return $data; + } + ++ /** ++ * @covers ::checkRequirements ++ */ ++ public function testCheckRequirementsEarlyReturn() { ++ // Set up three contexts. ++ $context1 = $this->prophesize(ContextInterface::class); ++ $context2 = $this->prophesize(ContextInterface::class); ++ $context3 = $this->prophesize(ContextInterface::class); ++ $contexts[] = $context1->reveal(); ++ $contexts[] = $context2->reveal(); ++ $contexts[] = $context3->reveal(); ++ ++ $requirement = $this->prophesize(ContextDefinitionInterface::class); ++ $requirement->isRequired()->willReturn(TRUE); ++ ++ // Set the second context to satisfy the requirement. The third context ++ // should not be checked. ++ $requirement->isSatisfiedBy($context1)->willReturn(FALSE); ++ $requirement->isSatisfiedBy($context2)->willReturn(TRUE); ++ $requirement->isSatisfiedBy($context3)->shouldNotBeCalled(); ++ ++ $requirements[] = $requirement->reveal(); ++ $this->contextHandler->checkRequirements($contexts, $requirements); ++ } ++ + /** + * @covers ::getMatchingContexts + *