diff --git a/composer.json b/composer.json index b7b97e747172ada7d2215b556435697892489022..784df1a9ad153a48619d386a01b64529405204ed 100644 --- a/composer.json +++ b/composer.json @@ -321,7 +321,8 @@ "MediaLibraryUiBuilder service does not properly allow additional contextual filter arguments @see https://www.drupal.org/i/3401726": "resources/patch/php/drupal/core/3401726.diff", "The submit button is not following any condition while in popup/dialogs @see https://drupal.org/i/3008172": "resources/patch/php/drupal/core/3008172-43.patch", "Added deprecation suppression": "resources/patch/php/drupal/core/3467293.diff", - "Fix handling of unknown file extensions in FileMediaFormatterBase @see https://www.drupal.org/i/3466462": "resources/patch/php/drupal/core/3466462.diff" + "Fix handling of unknown file extensions in FileMediaFormatterBase @see https://www.drupal.org/i/3466462": "resources/patch/php/drupal/core/3466462.diff", + "Allow ChangedItem to skip updating the entity's \"changed\" timestamp when synchronizing @see https://drupal.org/i/2329253": "resources/patch/php/drupal/core/2329253-10.x.patch" }, "drupal/default_content": { "Allow manual imports @see https://www.drupal.org/i/2640734": "resources/patch/php/drupal/default_content/2640734.diff" diff --git a/composer.lock b/composer.lock index 5342d707cb698f53682c3a8437a2ac777fb5f05c..5ac6e46dbf634215531c463a084cb50bbb9d4756 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "611aa7faada4705d01ba368086f6006d", + "content-hash": "9e71bf6ed65358df495a808abe488908", "packages": [ { "name": "asm89/stack-cors", @@ -24917,7 +24917,7 @@ "version": "2.x-dev", "source": { "type": "git", - "url": "https://git.drupalcode.org/project/dtt/", + "url": "https://git.drupalcode.org/project/dtt.git", "reference": "5e3df23c93f4f3e4f34fd7677df10bc06616f4ce" }, "require": { diff --git a/resources/patch/php/drupal/core/2329253-10.x.patch b/resources/patch/php/drupal/core/2329253-10.x.patch new file mode 100644 index 0000000000000000000000000000000000000000..93bfa1a49fb742d9b0a75218e8d19cd4865516ed --- /dev/null +++ b/resources/patch/php/drupal/core/2329253-10.x.patch @@ -0,0 +1,69 @@ +diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php +index 7116809acd..3294ed40c9 100644 +--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php ++++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/ChangedItem.php +@@ -5,6 +5,7 @@ + use Drupal\Core\Field\Attribute\FieldType; + use Drupal\Core\Field\ChangedFieldItemList; + use Drupal\Core\StringTranslation\TranslatableMarkup; ++use Drupal\Core\Entity\SynchronizableInterface; + + /** + * Defines the 'changed' entity field type. +@@ -44,13 +45,15 @@ public function preSave() { + // \Drupal\content_translation\ContentTranslationMetadataWrapperInterface::setChangedTime(). + /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ + $entity = $this->getEntity(); +- /** @var \Drupal\Core\Entity\ContentEntityInterface $original */ +- $original = $entity->original; +- $langcode = $entity->language()->getId(); +- if (!$entity->isNew() && $original && $original->hasTranslation($langcode)) { +- $original_value = $original->getTranslation($langcode)->get($this->getFieldDefinition()->getName())->value; +- if ($this->value == $original_value && $entity->hasTranslationChanges()) { +- $this->value = \Drupal::time()->getRequestTime(); ++ if (!$entity instanceof SynchronizableInterface || !$entity->isSyncing()) { ++ /** @var \Drupal\Core\Entity\ContentEntityInterface $original */ ++ $original = $entity->original; ++ $langcode = $entity->language()->getId(); ++ if (!$entity->isNew() && $original && $original->hasTranslation($langcode)) { ++ $original_value = $original->getTranslation($langcode)->get($this->getFieldDefinition()->getName())->value; ++ if ($this->value == $original_value && $entity->hasTranslationChanges()) { ++ $this->value = \Drupal::time()->getRequestTime(); ++ } + } + } + } +diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php +index 32a49bf0a0..7824248bf5 100644 +--- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php ++++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityChangedTest.php +@@ -472,6 +472,29 @@ public function testRevisionChanged(): void { + + } + ++ /** ++ * Tests the changed functionality when an entity is syncing. ++ */ ++ public function testChangedSyncing(): void { ++ $entity = EntityTestMulChanged::create(); ++ $entity->save(); ++ $changed_time_1 = $entity->getChangedTime(); ++ ++ // Without the syncing flag the changed time will increment when content is ++ // changed. ++ $entity->setName($this->randomString()); ++ $entity->save(); ++ $changed_time_2 = $entity->getChangedTime(); ++ $this->assertTrue($changed_time_2 > $changed_time_1); ++ ++ // With the syncing flag, the changed time will not change. ++ $entity->setName($this->randomString()); ++ $entity->setSyncing(TRUE); ++ $entity->save(); ++ $changed_time_3 = $entity->getChangedTime(); ++ $this->assertEquals($changed_time_2, $changed_time_3); ++ } ++ + /** + * Retrieves the revision translation affected flag value. + * diff --git a/tests/features/update/update-ISAICP-9076.feature b/tests/features/update/update-ISAICP-9076.feature new file mode 100644 index 0000000000000000000000000000000000000000..a940a547007ac0421fc11a976fcacc88683aade7 --- /dev/null +++ b/tests/features/update/update-ISAICP-9076.feature @@ -0,0 +1,9 @@ +@api @group-clone @update:joinup_core_deploy_111300 +Feature: Ensure that releases without version do not break adding new release + + Scenario: Ensure that releases without version do not break adding new release. + Given I am logged in as a facilitator of the "LEOS - Open Source software for editing legislation" solution + And I accept the "Legal notice" agreement + When I go to the homepage of the "LEOS - Open Source software for editing legislation" solution + And I click "Add release" + And I should see the heading "Add Release" diff --git a/web/modules/custom/custom_page/custom_page.module b/web/modules/custom/custom_page/custom_page.module index 272e3a5526d3135d17a8824d0e07e8e2916eb1c3..7c2b986151cefb6239ee7265562165dbd9f176fe 100644 --- a/web/modules/custom/custom_page/custom_page.module +++ b/web/modules/custom/custom_page/custom_page.module @@ -370,15 +370,16 @@ function custom_page_pathauto_alias_alter(&$alias, array $context): void { return; } - $prohibited_prefixes = [ + $prohibited_suffixes = [ '/distribution', '/news', '/discussion', '/document', '/event', '/solution', + '/release', ]; - foreach ($prohibited_prefixes as $prohibited) { + foreach ($prohibited_suffixes as $prohibited) { if (str_ends_with($alias, $prohibited)) { // Append an incrementing numeric suffix, treat it as already taken. $alias = $alias . '-0'; diff --git a/web/modules/custom/joinup_core/joinup_core.deploy.php b/web/modules/custom/joinup_core/joinup_core.deploy.php index 33814e44ab95ca79c3c15804ccb562d8b10d1023..9fe79c90ce575d707ea67c6bf07e6a8e04f6163b 100644 --- a/web/modules/custom/joinup_core/joinup_core.deploy.php +++ b/web/modules/custom/joinup_core/joinup_core.deploy.php @@ -13,3 +13,51 @@ */ declare(strict_types=1); + +use Drupal\joinup_release\Entity\ReleaseInterface; +use Drupal\pathauto\PathautoState; + +/** + * Fix releases without version string and regenerate their path aliases. + */ +function joinup_core_deploy_111300(): string { + $entityTypeManager = \Drupal::entityTypeManager(); + $nodeStorage = \Drupal::entityTypeManager()->getStorage('node'); + $pathAliasStorage = $entityTypeManager->getStorage('path_alias'); + $releaseIdsWithoutVersion = $nodeStorage + ->getQuery() + ->accessCheck(FALSE) + ->condition('type', 'release') + ->notExists('release_number') + ->execute(); + $changedReleaseCount = 0; + + foreach ($nodeStorage->loadMultiple($releaseIdsWithoutVersion) as $release) { + assert($release instanceof ReleaseInterface); + assert($release->get('release_number')->isEmpty()); + // Skip doing anything to releases whose alias does not end with /release - + // so we don't touch releases having aliases ending with /release-0, + // /release-1 etc.: these aliases are harmless. + $pathField = $release->get('path'); + if (!is_string($pathField->alias) || !str_ends_with($pathField->alias, '/release')) { + continue; + } + // Delete the preexisting alias so Redirect module won't create a redirect + // (which causes the same issue what we're solving here). + if ($aliasId = $pathField->pid) { + $pathAliasStorage->load($aliasId)->delete(); + } + $release->skip_notification = TRUE; + $release + ->setSyncing(TRUE) + ->set('release_number', 'no-version') + ->set('path', ['pathauto' => PathautoState::CREATE]) + ->save(); + $changedReleaseCount++; + } + + return sprintf( + "Added 'no-version' to %s releases which lack version number with an alias ending with '/release'; and re-generated their aliases", + $changedReleaseCount, + ); +}