diff --git a/patches/Definevoidreturntype2.patch b/patches/Definevoidreturntype2.patch new file mode 100644 index 00000000..124f015e --- /dev/null +++ b/patches/Definevoidreturntype2.patch @@ -0,0 +1,92 @@ +diff --git a/src/ExistingSiteBase.php b/src/ExistingSiteBase.php +index b21be6c..476b796 100644 +--- a/src/ExistingSiteBase.php ++++ b/src/ExistingSiteBase.php +@@ -50,7 +50,7 @@ abstract class ExistingSiteBase extends TestCase implements LoggerInterface + */ + protected $baseUrl; + +- protected function setUp() ++ protected function setUp(): void + { + parent::setUp(); + $this->setupMinkSession(); +@@ -60,7 +60,7 @@ abstract class ExistingSiteBase extends TestCase implements LoggerInterface + /** + * @throws \Drupal\Core\Entity\EntityStorageException + */ +- public function tearDown() ++ public function tearDown(): void + { + parent::tearDown(); + $this->tearDownDrupal(); +diff --git a/tests/Entity/MediaCreationTraitTest.php b/tests/Entity/MediaCreationTraitTest.php +index 1700d67..39213a2 100644 +--- a/tests/Entity/MediaCreationTraitTest.php ++++ b/tests/Entity/MediaCreationTraitTest.php +@@ -11,7 +11,7 @@ use weitzman\DrupalTestTraits\ExistingSiteBase; + class MediaCreationTraitTest extends ExistingSiteBase + { + use MediaCreationTrait; +- protected function setUp() ++ protected function setUp(): void + { + parent::setUp(); + $status = \Drupal::service('module_installer') +@@ -33,7 +33,7 @@ class MediaCreationTraitTest extends ExistingSiteBase + $this->assertEquals($media->id(), $this->cleanupEntities[1]->id()); + } + +- public function tearDown() ++ public function tearDown(): void + { + // Delete all the media content before uninstalling the module. + $this->cleanupEntities[0]->delete(); +diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php +index 05428e1..d5e62fe 100644 +--- a/tests/ExampleTest.php ++++ b/tests/ExampleTest.php +@@ -13,7 +13,7 @@ use weitzman\DrupalTestTraits\ExistingSiteBase; + class ExampleTest extends ExistingSiteBase + { + +- protected function setUp() ++ protected function setUp(): void + { + parent::setUp(); + +diff --git a/tests/Mail/MailCollectorTraitTest.php b/tests/Mail/MailCollectorTraitTest.php +index 6f5e753..865e0cc 100644 +--- a/tests/Mail/MailCollectorTraitTest.php ++++ b/tests/Mail/MailCollectorTraitTest.php +@@ -18,7 +18,7 @@ class MailCollectorTraitTest extends ExistingSiteBase + /** + * {@inheritdoc} + */ +- protected function setUp() ++ protected function setUp(): void + { + parent::setUp(); + $this->startMailCollection(); +@@ -27,7 +27,7 @@ class MailCollectorTraitTest extends ExistingSiteBase + /** + * {@inheritdoc} + */ +- public function tearDown() ++ public function tearDown(): void + { + $this->restoreMailSettings(); + parent::tearDown(); +diff --git a/tests/ScreenShotTraitTest.php b/tests/ScreenShotTraitTest.php +index 22a7ae8..c1f9278 100644 +--- a/tests/ScreenShotTraitTest.php ++++ b/tests/ScreenShotTraitTest.php +@@ -25,7 +25,7 @@ class ScreenShotTraitTest extends ExistingSiteWebDriverTestBase + /** + * {@inheritdoc} + */ +- protected function setUp() ++ protected function setUp(): void + { + parent::setUp(); + diff --git a/patches/core-2546212-168-entity-display-translation-11.4.7.patch b/patches/core-2546212-168-entity-display-translation-11.4.7.patch new file mode 100644 index 00000000..fb5343f1 --- /dev/null +++ b/patches/core-2546212-168-entity-display-translation-11.4.7.patch @@ -0,0 +1,289 @@ +diff --git a/core/modules/config_translation/src/ConfigTranslation/EntityDisplayMapper.php b/core/modules/config_translation/src/ConfigTranslation/EntityDisplayMapper.php +new file mode 100644 +index 00000000..98d75c45 +--- /dev/null ++++ b/core/modules/config_translation/src/ConfigTranslation/EntityDisplayMapper.php +@@ -0,0 +1,112 @@ ++entityTypeManager ++ ->getDefinition($this->pluginDefinition['base_entity_type']); ++ $bundle_parameter_key = $base_entity_info ++ ->getBundleEntityType() ?: 'bundle'; ++ ++ $parameters = []; ++ $parameters[$bundle_parameter_key] = $this->entity->getTargetBundle(); ++ $parameters[$this->pluginDefinition['display_context'] . '_mode_name'] = $this->entity->getMode(); ++ ++ return $parameters; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getOverviewRouteName() { ++ return "entity.{$this->entityType}.config_translation_overview.{$this->pluginDefinition['base_entity_type']}"; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getTitle() { ++ $base_entity_info = $this->entityTypeManager ++ ->getDefinition($this->pluginDefinition['base_entity_type']); ++ $bundle = $base_entity_info->getLabel(); ++ if ($bundle_type = $base_entity_info->getBundleEntityType()) { ++ $bundle = $this->entityTypeManager ++ ->getStorage($bundle_type) ++ ->load($this->entity->getTargetBundle()) ++ ->label(); ++ } ++ ++ $mode = $this->entityTypeManager ++ ->getStorage("entity_{$this->pluginDefinition['display_context']}_mode") ++ ->load($this->pluginDefinition['base_entity_type'] . '.' . $this->entity->getMode()); ++ $mode = $mode ? $mode->label() : $this->t('Default'); ++ ++ if ($this->entityType == 'entity_view_display') { ++ return $this->t('@bundle @mode display', [ ++ '@bundle' => $bundle, ++ '@mode' => $mode, ++ ]); ++ } ++ elseif ($this->entityType == 'entity_form_display') { ++ return $this->t('@bundle @mode form display', [ ++ '@bundle' => $bundle, ++ '@mode' => $mode, ++ ]); ++ } ++ parent::getTypeLabel(); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getTypeLabel() { ++ $base_entity_info = $this->entityTypeManager ++ ->getDefinition($this->pluginDefinition['base_entity_type']); ++ ++ if ($this->entityType == 'entity_view_display') { ++ return $this->t('@label view display', [ ++ '@label' => $base_entity_info->getLabel(), ++ ]); ++ } ++ elseif ($this->entityType == 'entity_form_display') { ++ return $this->t('@label form display', [ ++ '@label' => $base_entity_info->getLabel(), ++ ]); ++ } ++ parent::getTypeLabel(); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function populateFromRouteMatch(RouteMatchInterface $route_match) { ++ $bundle_entity_type = $this->entityTypeManager ++ ->getDefinition($this->pluginDefinition['base_entity_type']) ++ ->getBundleEntityType(); ++ $bundle = $route_match->getParameter($bundle_entity_type ?: 'bundle') ?: $this->pluginDefinition['base_entity_type']; ++ $mode = $route_match->getParameter($this->pluginDefinition['display_context'] . '_mode_name') ?: 'default'; ++ ++ $entity = $this->entityTypeManager ++ ->getStorage($this->entityType) ++ ->load("{$this->pluginDefinition['base_entity_type']}.{$bundle}.{$mode}"); ++ ++ if ($entity) { ++ $route_match->getParameters()->set($this->entityType, $entity); ++ ++ $this->setEntity($entity); ++ parent::populateFromRouteMatch($route_match); ++ } ++ } ++ ++} +diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationEntityDisplayListBuilder.php b/core/modules/config_translation/src/Controller/ConfigTranslationEntityDisplayListBuilder.php +new file mode 100644 +index 00000000..b24e46f2 +--- /dev/null ++++ b/core/modules/config_translation/src/Controller/ConfigTranslationEntityDisplayListBuilder.php +@@ -0,0 +1,117 @@ ++displayContext = preg_replace('/^entity_(.+)_display$/', '\1', $this->entityType->id()); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function load() { ++ // It is not possible to use the standard load method, because this needs ++ // all display entities only for the given baseEntityType. ++ $ids = \Drupal::entityQuery($this->entityType->id()) ++ ->condition('id', $this->baseEntityType . '.', 'STARTS_WITH') ++ ->execute(); ++ return $this->storage->loadMultiple($ids); ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getFilterLabels() { ++ $info = parent::getFilterLabels(); ++ $bundle = $this->baseEntityInfo->getBundleLabel() ?: $this->t('Bundle'); ++ $bundle = mb_strtolower($bundle); ++ $info['placeholder'] = $this->t('Enter mode or @bundle', [ ++ '@bundle' => $bundle, ++ ]); ++ $info['description'] = $this->t('Enter a part of the mode or @bundle to filter by.', [ ++ '@bundle' => $bundle, ++ ]); ++ return $info; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildRow(EntityInterface $entity) { ++ $row = parent::buildRow($entity); ++ $row['label']['data'] = $entity->getMode() == 'default' ? $this->t('Default') : $this->entityTypeManager ++ ->getStorage('entity_' . $this->displayContext . '_mode') ++ ->load($entity->getTargetEntityTypeId() . '.' . $entity->getMode()) ++ ->label(); ++ return $row; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function buildHeader() { ++ $header = parent::buildHeader(); ++ $header['label'] = $this->entityType->getLabel(); ++ return $header; ++ } ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function getOperations(EntityInterface $entity) { ++ // Entity displays have no canonical no direct edit-form links so we ++ // hard-code the route to the translation operation. ++ // @todo Use config-translation-overview link template like field_ui does. ++ $route_parameters = [ ++ $this->displayContext . '_mode_name' => $entity->getMode(), ++ ]; ++ ++ $bundle_type = $this->entityTypeManager ++ ->getDefinition($entity->getTargetEntityTypeId()) ++ ->getBundleEntityType(); ++ if ($bundle_type) { ++ $route_parameters[$bundle_type] = $entity->getTargetBundle(); ++ } ++ ++ $operations['translate'] = [ ++ 'title' => $this->t('Translate'), ++ 'url' => $this->ensureDestination(Url::fromRoute("entity.{$this->entityType->id()}.config_translation_overview.{$entity->getTargetEntityTypeId()}", $route_parameters)), ++ ]; ++ ++ return $operations; ++ } ++ ++} +diff --git a/core/modules/config_translation/src/Hook/ConfigTranslationHooks.php b/core/modules/config_translation/src/Hook/ConfigTranslationHooks.php +index 21daa8b7..bca9d4eb 100644 +--- a/core/modules/config_translation/src/Hook/ConfigTranslationHooks.php ++++ b/core/modules/config_translation/src/Hook/ConfigTranslationHooks.php +@@ -8,6 +8,9 @@ + use Drupal\Core\Config\Entity\ConfigEntityInterface; + use Drupal\Core\Url; + use Drupal\Core\Routing\RouteMatchInterface; ++use Drupal\Core\Entity\Display\EntityDisplayInterface; ++use Drupal\config_translation\ConfigTranslation\EntityDisplayMapper; ++use Drupal\config_translation\Controller\ConfigTranslationEntityDisplayListBuilder; + use Drupal\Core\Hook\Attribute\Hook; + + /** +@@ -119,6 +122,10 @@ public function entityTypeAlter(array &$entity_types) : void { + // \Drupal\field\Entity\FieldConfig::linkTemplates(). + $entity_type->setLinkTemplate('config-translation-overview', $entity_type->getLinkTemplate('edit-form') . '/translate'); + } ++ elseif ($entity_type->entityClassImplements(EntityDisplayInterface::class)) { ++ $class = ConfigTranslationEntityDisplayListBuilder::class; ++ // @todo Link template is not used but should be set so other logic can apply. ++ } + else { + $class = 'Drupal\config_translation\Controller\ConfigTranslationEntityListBuilder'; + } +@@ -150,6 +157,22 @@ public function configTranslationInfo(&$info): void { + 'base_entity_type' => $entity_type_id, + 'weight' => 10, + ]; ++ $info[$entity_type_id . '_form_display'] = [ ++ 'base_route_name' => "entity.entity_form_display.{$entity_type_id}.form_mode", ++ 'entity_type' => 'entity_form_display', ++ 'class' => EntityDisplayMapper::class, ++ 'base_entity_type' => $entity_type_id, ++ 'display_context' => 'form', ++ 'weight' => 10, ++ ]; ++ $info[$entity_type_id . '_view_display'] = [ ++ 'base_route_name' => "entity.entity_view_display.{$entity_type_id}.view_mode", ++ 'entity_type' => 'entity_view_display', ++ 'class' => EntityDisplayMapper::class, ++ 'base_entity_type' => $entity_type_id, ++ 'display_context' => 'view', ++ 'weight' => 10, ++ ]; + } + } + } diff --git a/patches/core-3198715-configimporter-checkop-null-11.4.7.patch b/patches/core-3198715-configimporter-checkop-null-11.4.7.patch new file mode 100644 index 00000000..3ae6b9cb --- /dev/null +++ b/patches/core-3198715-configimporter-checkop-null-11.4.7.patch @@ -0,0 +1,17 @@ +diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php +index 1b590d3..6b5cead 100644 +--- a/core/lib/Drupal/Core/Config/ConfigImporter.php ++++ b/core/lib/Drupal/Core/Config/ConfigImporter.php +@@ -981,8 +981,10 @@ protected function checkOp($collection, $op, $name) { + $entity_storage = $this->configManager->getEntityTypeManager()->getStorage($entity_type_id); + $entity_type = $this->configManager->getEntityTypeManager()->getDefinition($entity_type_id); + $entity = $entity_storage->load($entity_storage->getIDFromConfigName($name, $entity_type->getConfigPrefix())); +- $entity->delete(); +- $this->logError($this->t('Deleted and replaced configuration entity "@name"', ['@name' => $name])); ++ if ($entity) { ++ $entity->delete(); ++ $this->logError($this->t('Deleted and replaced configuration entity "@name"', ['@name' => $name])); ++ } + } + else { + $this->storageComparer->getTargetStorage($collection)->delete($name);