Verified Commit f30d64c5 authored by Andrei Mateescu's avatar Andrei Mateescu
Browse files

fix: #1499532 Respect explicitly set node path alias langcode on save

By: q0rban
By: smustgrave
By: joelpittet
parent 9a3648e3
Loading
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -75,10 +75,11 @@ public function postSave($update) {
    $pid = $this->get('pid')->getValue();
    $langcode = $this->get('langcode')->getValue();

    // If specified, rely on the langcode property for the language, so that the
    // existing language of an alias can be kept. That could for example be
    // unspecified even if the field/entity has a specific langcode.
    $alias_langcode = ($langcode && $pid) ? $langcode : $this->getLangcode();
    // If an explicit alias langcode is provided, use it. This allows code to
    // preserve an existing alias language or set a specific language,
    // including language-neutral, when creating or updating an alias.
    // Otherwise, fall back to the field/entity langcode.
    $alias_langcode = $langcode ?: $this->getLangcode();

    // If we have an alias, we need to create or update a path alias entity.
    if ($alias) {
@@ -109,9 +110,18 @@ public function postSave($update) {
      }
      else {
        $path_alias = $path_alias_storage->load($pid);
        $path_alias_changed = FALSE;

        if ($alias != $path_alias->getAlias()) {
          $path_alias->setAlias($alias);
          $path_alias_changed = TRUE;
        }
        // Persist langcode-only updates when the alias text is unchanged.
        if ($alias_langcode !== $path_alias->language()->getId()) {
          $path_alias->set('langcode', $alias_langcode);
          $path_alias_changed = TRUE;
        }
        if ($path_alias_changed) {
          $path_alias->save();
        }
      }
+4 −1
Original line number Diff line number Diff line
@@ -46,7 +46,10 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
    ];
    $element['langcode'] = [
      '#type' => 'value',
      '#value' => $items[$delta]->langcode,
      // For new aliases, let the save logic fall back to the entity language
      // unless a form alter or other code explicitly provides an alias
      // langcode. Existing aliases keep their stored langcode.
      '#value' => $items[$delta]->pid ? $items[$delta]->langcode : NULL,
    ];

    // If the advanced settings tabs-set is available (normally rendered in the
+31 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

namespace Drupal\Tests\path\Kernel;

use Drupal\Core\Language\LanguageInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\node\Entity\Node;
@@ -74,6 +75,21 @@ public function testPathItem(): void {

    $stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
    $this->assertEquals('/foo', $stored_alias['alias']);
    $this->assertEquals($node->language()->getId(), $stored_alias['langcode']);

    $node_storage->resetCache();
    $loaded_node = $node_storage->load($node->id());
    $loaded_node->get('path')->langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
    $loaded_node->save();

    $stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), LanguageInterface::LANGCODE_NOT_SPECIFIED);
    $this->assertEquals('/foo', $stored_alias['alias']);
    $this->assertEquals(LanguageInterface::LANGCODE_NOT_SPECIFIED, $stored_alias['langcode']);
    $stored_aliases = \Drupal::entityTypeManager()->getStorage('path_alias')->loadByProperties([
      'path' => '/' . $node->toUrl()->getInternalPath(),
      'langcode' => $node->language()->getId(),
    ]);
    $this->assertCount(0, $stored_aliases);

    $node_storage->resetCache();

@@ -112,6 +128,21 @@ public function testPathItem(): void {
    $stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $translation->language()->getId());
    $this->assertEquals('/furchtbar', $stored_alias['alias']);

    $node_with_unspecified_alias = Node::create([
      'title' => 'Testing explicit alias langcode',
      'type' => 'foo',
      'langcode' => 'en',
      'path' => [
        'alias' => '/neutral',
        'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
      ],
    ]);
    $node_with_unspecified_alias->save();

    $stored_alias = $alias_repository->lookupBySystemPath('/' . $node_with_unspecified_alias->toUrl()->getInternalPath(), LanguageInterface::LANGCODE_NOT_SPECIFIED);
    $this->assertEquals('/neutral', $stored_alias['alias']);
    $this->assertEquals(LanguageInterface::LANGCODE_NOT_SPECIFIED, $stored_alias['langcode']);

    $loaded_node->get('path')->alias = '/bar';
    $this->assertFalse($loaded_node->get('path')->isEmpty());
    $this->assertEquals('/bar', $loaded_node->get('path')->alias);