'Link internal content' with 'Skip already imported entities' processor

Created on 19 August 2024, 4 months ago
Updated 27 August 2024, 4 months ago

Problem/Motivation

I encountered an issue while sharing menu link entities. On client and server side, I am using the "UUID for link (link field only)" on the link field of the menu link entity via the JSON API Extras module. On the client side, I am utilizing the 'Link internal content' processor along with the 'Skip already imported entities' option.

The issue arises when I pull a menu link entity that references a node entity previously pulled. In this scenario, the URI is not correctly transformed, resulting in the menu link being created with an empty URI. This leads to a fatal error when the menu link is displayed, with the message:

Route "" does not exist

I was able to resolve the issue in the \Drupal\entity_share_client\Plugin\EntityShareClient\Processor\LinkInternalContentImporter::processLink function. Below is the original function:

  /**
   * Attempts to import UUID-enhanced link content.
   *
   * @param \Drupal\entity_share_client\RuntimeImportContext $runtime_import_context
   *   The import context.
   * @param string $uri
   *   URI should be in the format entity:[entity_type]/[bundle_name]/[UUID].
   * @param string $import_url
   *   The import URL prepared by the entity_share_uuid_link enhancer plugin.
   *
   * @return string
   *   Link to the imported content in the form entity:[entity_type]/[Id].
   */
  protected function processLink(RuntimeImportContext $runtime_import_context, string $uri, string $import_url) {
    // Check if it is a link to an entity.
    preg_match("/entity:(.*)\/(.*)\/(.*)/", $uri, $parsed_uri);
    // If the link is not in UUID enhanced format, just return the original URI.
    if (empty($parsed_uri)) {
      return $uri;
    }

    $entity_type = $parsed_uri[1];
    $entity_uuid = $parsed_uri[3];

    // In the case of links, if the linked entity is already
    // present on the website, there is nothing to do as the
    // UuidLinkEnhancer::doTransform() method will convert the URI format back
    // to Drupal expected format.
    if (
      $this->currentRecursionDepth != $this->configuration['max_recursion_depth'] &&
      !$runtime_import_context->isEntityMarkedForImport($entity_uuid)
    ) {
      $runtime_import_context->addEntityMarkedForImport($entity_uuid);
      $referenced_entities_ids = $this->importUrl($runtime_import_context, $import_url);
      if (!empty($referenced_entities_ids) && isset($referenced_entities_ids[$entity_uuid])) {
        return 'entity:' . $entity_type . '/' . $referenced_entities_ids[$entity_uuid];
      }
    }
    else {
      return $uri;
    }
  }

As noted in the comment, "In the case of links, if the linked entity is already present on the website, there is nothing to do as the UuidLinkEnhancer::doTransform() method will convert the URI format back to Drupal's expected format." However, this conversion never occurs if $referenced_entities_ids is empty, causing the function to fail to return any $uri. This can happen when the referenced node entity was skipped due to the 'Skip already imported entities' processor.

In an earlier version of this function, such as in version 8.x-3.0-rc2, the function would return a URI in this scenario. You can view this version here: https://git.drupalcode.org/project/entity_share/-/blob/8.x-3.0-rc2/modul...

Proposed resolution

Keep returning the $uri.

I provided a patch to fix the issue.

🐛 Bug report
Status

Active

Version

3.0

Component

Code

Created by

🇩🇪Germany ayrmax

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

Comments & Activities

Production build 0.71.5 2024