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.
Issue fork ui_patterns-3483508
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
Comment #3
pdureau commentedComment #4
pdureau commentedComment #5
pdureau commentedI take it back to add the unit test :)
Comment #6
pdureau commentedTest added.
Comment #7
just_like_good_vibesi 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.
Comment #8
pdureau commentedAbout 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.Comment #9
pdureau commentedComment #11
pdureau commented