processUrl Cannot Find the Correct Entity in Multilingual Site

Created on 14 March 2024, 8 months ago
Updated 18 March 2024, 8 months ago

Problem/Motivation

When attempting to process a node in a different language (e.g., en), entity usage should also check the alias across all the different languages. Otherwise, the processUrl function cannot find the correct node ID. This leads to the entity not being found and the inability to create an entity usage.

Steps to reproduce

1. Save an entity with a different language.
2. Try to process this entity using your current URL.
3. Notice that the entity is not processed because the URL cannot be found (in processUrl).

Proposed resolution

To resolve this issue, we need to check all languages in the processUrl function. Validate by resolving the pathalias per language to find a matching node. Then, return that node to the getUrlIfValidWithoutAccessCheck function.

Remaining tasks

Test if this solution works as intended.

User interface changes

None

API changes

None

Data model changes

None

🐛 Bug report
Status

Active

Version

4.0

Component

Code

Created by

🇳🇱Netherlands Remco Hoeneveld

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Remco Hoeneveld
  • 🇳🇱Netherlands seanB Netherlands

    This is indeed an issue. A little more context. The following calls lead to the issue:
    HtmlLink::parseEntitiesFromText()
    EntityUsageBase::findEntityByUrlString()
    EntityUsageBase::processUrl()
    PathValidator::getUrlIfValidWithoutAccessCheck()
    PathValidator::getUrl()
    PathValidator::getPathAttributes()
    PathProcessorManager::processInbound()
    AliasPathProcessor::processInbound()
    AliasManager::getPathByAlias()

    The AliasPathProcessor::processInbound() doesn't pass a langcode to AliasManager::getPathByAlias(), and for that reason AliasManager::getPathByAlias() uses the current language from the URL. If you link to a page in another language this is an issue, but also if the langcode in the URL is different for other reasons (like working on translations or something).

    The current patch has some issues though.

    1. +++ b/src/EntityUsageBase.php
      @@ -9,11 +9,15 @@ use Drupal\Core\Entity\EntityRepositoryInterface;
      +use Drupal\path_alias\AliasManagerInterface;
      

      We don't have a hard dependency on the path_alias module, and we should not add it just for this bug.

    2. +++ b/src/EntityUsageBase.php
      @@ -363,4 +402,29 @@ abstract class EntityUsageBase extends EntityTrackBase {
      +  protected function processUrlForAllLanguages(string &$url): void {
      +    $languages = $this->languageManager->getLanguages();
      +    $request = Request::create($url);
      +    $resolved_path = $this->pathProcessorManager->processInbound($url, $request);
      +    foreach ($languages as $language) {
      +      $alias = $this->aliasManager->getPathByAlias(
      +        $resolved_path,
      +        $language->getId());
      

      This works around the issue, but duplicates a bunch of code. The real issue is the LanguageNegotiationUrl inbound path processor strips the language prefix from the URL, and the AliasPathProcessor is not able to pass the langcode (when available). It seems there already is a core issue to fix this: #3314941: Language-prefixed alias paths cannot be correctly routed inside a request

    Could you try if #3314941: Language-prefixed alias paths cannot be correctly routed inside a request fixes the issue?

Production build 0.71.5 2024