Problem/Motivation

When using "Data from a field" source with a Link field, i have this error coming from FieldValueSourceBase::resolveInternalUri()
:

The URI 'public://2024-10/generateImage_K6fSfV.jpg' is invalid. You must use a valid URI scheme. Use base: for a path, e.g., to a Drupal file that needs the base path. Do not use this for internal paths controlled by Drupal

It can be fixed by doing something like that at the beginning of the method:

    $stream_wrappers = [
      "public",
      "private",
      "temp",
    ];
    $scheme = parse_url($value, PHP_URL_SCHEME);
    if (in_array($scheme, $stream_wrappers)) {
      $value = $this->fileUrlGenerator->generateAbsoluteString($value);
    }

But, I am wondering..

Do we still need FieldValueSourceBase::resolveInternalUri()?

  protected function resolveInternalUri(FieldItemInterface $item, string $value): string {
    // Most of the time, Uri datatype is met in a "link" field type.
    if ($item->getDataDefinition()->getDataType() === 'field_item:link') {
      $options = (array) $item->get('options')->getValue();
      return Url::fromUri($value, $options)->toString();
    }
    return Url::fromUri($value)->toString();
  }

Maybe the logic is better in UrlPropType::normalize()? We will lose the retrieval of $item->get('options'), but it may worth it.

Also, do we still need FieldValueSourceBase::getEntityReferencedLabel()?

  protected function getEntityReferencedLabel(EntityReference $property, string $lang_code): mixed {
    // Ensure the referenced entity still exists.
    $referencedEntityTypeId = $property->getTargetDefinition()
      ->getEntityTypeId();
    $referencedEntityId = $property->getTargetIdentifier();
    if (!$referencedEntityId) {
      return NULL;
    }
    $entity = $this->entityTypeManager
      ->getStorage($referencedEntityTypeId)
      ->load($referencedEntityId);

    if (!$entity || !is_object($entity)) {
      return NULL;
    }
    // Drupal loads the entity in its default language and should load
    // the translated one if available.
    $value = $entity->label();
    /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    if (($entity instanceof TranslatableInterface)
      && $lang_code
      && $entity->hasTranslation($lang_code)) {
      $translated_entity = $entity->getTranslation($lang_code);
      $value = $translated_entity->label();
    }
    return $value;
  }

Because we have "Data from referenced entity now", so we can ignore the entity field properties, and retrieve the referenced entity label.

If we remove those methods, we may not need:

  protected function extractPropertyValue(FieldItemInterface $item, string $property_name, string $lang_code): mixed {
    $property = $item->get($property_name);
    if ($property instanceof TextProcessed) {
      return $property->getValue();
    }
    if ($property instanceof EntityReference) {
      return $this->getEntityReferencedLabel($property, $lang_code);
    }

    $value = $property->getValue();
    if ($value && ($property instanceof Uri)) {
      // $value is a non-empty string.
      return $this->resolveInternalUri($item, $value);
    }
    return $value;
  }

Because TextProcessed typed data logic looks useless.

Proposed resolution

Let's discuss.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

pdureau created an issue. See original summary.

pdureau’s picture

Assigned: pdureau » just_like_good_vibes
Status: Active » Needs review
pdureau’s picture

Issue summary: View changes
pdureau’s picture

Assigned: just_like_good_vibes » pdureau
Status: Needs review » Needs work

I take it back to add the unit test :)

pdureau’s picture

Assigned: pdureau » just_like_good_vibes
Status: Needs work » Needs review

Test added.

just_like_good_vibes’s picture

Assigned: just_like_good_vibes » pdureau
Status: Needs review » Needs work

i just reviewed the proposition.
URL treatment looks very good, but unfortunately, the modification done on the extracted field values seems to loose things.
could be separate both issues ?
we merge now the work on URLs and we postpone for beta5 the work on field values.

pdureau’s picture

About the two tasks of this issue.

Use a valid URI scheme

We are OK wit that.

Rethink FieldValueSourceBase::extractPropertyValue

In the current proposal, we removed:

  • $property instanceof TextProcessed: it is OK, we can keep it removed.
  • $property instanceof EntityReference:: it is OK, we can keep it removed
  • $property instanceof Uri>: it is OK, we can keep it removed, but we will create a new issue for beta5 with a mechanism working on the field level instead of the field property level.
pdureau’s picture

Assigned: pdureau » Unassigned
Status: Needs work » Fixed

  • pdureau committed 7431f5dd on 2.0.x
    Issue #3483508 by pdureau, just_like_good_vibes: Use a valid URI scheme...
pdureau’s picture

Status: Fixed » Closed (fixed)