diff --git a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php index 32e88224cc..76dddc20e8 100644 --- a/core/modules/path/src/Plugin/Field/FieldType/PathItem.php +++ b/core/modules/path/src/Plugin/Field/FieldType/PathItem.php @@ -51,28 +51,33 @@ public function preSave() { * {@inheritdoc} */ public function postSave($update) { + /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */ + $alias_storage = \Drupal::service('path.alias_storage'); + // Only process a non-empty alias. $entity = $this->getEntity(); + $canonical = '/' . $entity->toUrl()->getInternalPath(); if ($entity->getEntityType()->isRevisionable() && !$entity->isDefaultRevision()) { $source = '/' . $entity->toUrl('revision')->getInternalPath(); } else { - $source = '/' . $entity->toUrl()->getInternalPath(); + $source = $canonical; } if ($this->alias && (!$update || $source != $this->source)) { - if ($path = \Drupal::service('path.alias_storage')->save($source, $this->alias, $this->getLangcode())) { - $this->pid = $path['pid']; + $default_alias = $alias_storage->load(['source' => $canonical]); + if ($default_alias['alias'] != $this->alias && $path = $alias_storage->save($source, $this->alias, $this->getLangcode())) { + $this->pid = $path['pid']; } } else { // Delete old alias if user erased it. if (!$this->alias) { - \Drupal::service('path.alias_storage')->delete(['source' => $source]); + $alias_storage->delete(['source' => $source]); } // Only save a non-empty alias. elseif ($source) { - \Drupal::service('path.alias_storage')->save($source, $this->alias, $this->getLangcode(), $this->pid); + $alias_storage->save($source, $this->alias, $this->getLangcode(), $this->pid); } } } diff --git a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php index a6805c5b91..8f5bcb79d7 100644 --- a/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php +++ b/core/modules/path/src/Plugin/Field/FieldWidget/PathWidget.php @@ -28,16 +28,17 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $entity = $items->getEntity(); $path = []; if (!$entity->isNew()) { - if ($entity->getEntityType()->isRevisionable() && !$entity->isDefaultRevision()) { - $conditions = ['source' => '/' . $entity->toUrl('revision')->getInternalPath()]; + if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) { + $conditions = ['langcode' => $items->getLangcode()]; } - else { - $conditions = ['source' => '/' . $entity->toUrl()->getInternalPath()]; + if ($entity->getEntityType()->isRevisionable() && !$entity->isDefaultRevision()) { + $conditions['source'] = '/' . $entity->toUrl('revision')->getInternalPath(); + $path = \Drupal::service('path.alias_storage')->load($conditions); } - if ($items->getLangcode() != LanguageInterface::LANGCODE_NOT_SPECIFIED) { - $conditions['langcode'] = $items->getLangcode(); + if ($path === FALSE) { + $conditions['source'] = '/' . $entity->toUrl()->getInternalPath(); + $path = \Drupal::service('path.alias_storage')->load($conditions); } - $path = \Drupal::service('path.alias_storage')->load($conditions); if ($path === FALSE) { $path = []; } diff --git a/core/modules/path/tests/src/Functional/PathContentModerationTest.php b/core/modules/path/tests/src/Functional/PathContentModerationTest.php index 7b2c66057c..b9d9f8305e 100644 --- a/core/modules/path/tests/src/Functional/PathContentModerationTest.php +++ b/core/modules/path/tests/src/Functional/PathContentModerationTest.php @@ -26,9 +26,11 @@ class PathContentModerationTest extends BrowserTestBase { protected function setUp() { parent::setUp(); + // Created a content type. $node_type = NodeType::create(['name' => 'moderated', 'type' => 'moderated']); $node_type->save(); + // Set the content type as moderated. $workflow = Workflow::load('editorial'); $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated'); $workflow->save(); @@ -37,6 +39,7 @@ protected function setUp() { } public function testNodePathAlias() { + // Create some moderated content with a path alias. $this->drupalPostForm('node/add/moderated', [ 'title[0][value]' => 'moderated content', 'path[0][alias]' => '/moderated-content', @@ -46,41 +49,41 @@ public function testNodePathAlias() { $this->drupalGet('/moderated-content'); $this->assertSession()->pageTextContains('moderated content'); + // Add a forward revision with the same alias. $this->drupalPostForm('node/' . $node->id() . '/edit', [ 'title[0][value]' => 'forward revision', - 'path[0][alias]' => '/forward-revision', + 'path[0][alias]' => '/moderated-content', ], t('Save and Create New Draft')); - $this->drupalGet('/forward-revision'); - $this->assertSession()->pageTextNotContains('moderated content'); - $this->assertSession()->pageTextContains('forward revision'); + // Check the alias still shows the default content. $this->drupalGet('/moderated-content'); $this->assertSession()->pageTextNotContains('forward revision'); $this->assertSession()->pageTextContains('moderated content'); + // Add a third revision, updating alias. $this->drupalPostForm('node/' . $node->id() . '/edit', [ 'title[0][value]' => 'revision three', 'path[0][alias]' => '/revision-three', ], t('Save and Create New Draft')); + // Check both aliases return what we'd expect. $this->drupalGet('/revision-three'); $this->assertSession()->pageTextNotContains('moderated content'); $this->assertSession()->pageTextNotContains('forward revision'); $this->assertSession()->pageTextContains('revision three'); - $this->drupalGet('/forward-revision'); - $this->assertSession()->pageTextNotContains('moderated content'); - $this->assertSession()->pageTextContains('forward revision'); - $this->assertSession()->pageTextNotContains('revision three'); $this->drupalGet('/moderated-content'); $this->assertSession()->pageTextNotContains('forward revision'); $this->assertSession()->pageTextContains('moderated content'); $this->assertSession()->pageTextNotContains('revision three'); + // Add another forward revision with no alias. $this->drupalPostForm('node/' . $node->id() . '/edit', [ 'title[0][value]' => 'revision four', 'path[0][alias]' => '', ], t('Save and Create New Draft')); + // The first two aliases should still work, and the revision with no alias + // should work on the revision path. $this->drupalGet('/node/1/revisions/4/view'); $this->assertSession()->pageTextNotContains('moderated content'); $this->assertSession()->pageTextNotContains('forward revision'); @@ -91,11 +94,6 @@ public function testNodePathAlias() { $this->assertSession()->pageTextNotContains('forward revision'); $this->assertSession()->pageTextContains('revision three'); $this->assertSession()->pageTextNotContains('revision four'); - $this->drupalGet('/forward-revision'); - $this->assertSession()->pageTextNotContains('moderated content'); - $this->assertSession()->pageTextContains('forward revision'); - $this->assertSession()->pageTextNotContains('revision three'); - $this->assertSession()->pageTextNotContains('revision four'); $this->drupalGet('/moderated-content'); $this->assertSession()->pageTextNotContains('forward revision'); $this->assertSession()->pageTextContains('moderated content');