Problem/Motivation
When this code is executed on a file entity:
$entity->url('canonical')
The url that is returned is an absolute url, on all other entities in Drupal, the url that is returned is a relative url.
This code is in EntityReferenceFieldItemNormalizer::normalize() which produces a mixed response like this:
{
"uid": [
{
"target_id": "0",
"url": "/user/0"
}
],
"field_thumbnail": [
{
"target_id": "1362526",
"alt": null,
"title": null,
"width": null,
"height": null,
"url": "https://example.com/sites/default/files/video/thumbnail/2016/03/22/mco4_gp_0.jpg"
}
]
}
This means that File entities do not match other entity types and produces an inconsistent API. :(
Proposed resolution
I know that with some stream wrappers you cannot have a relative path, but you should be able to always have a relative path with the public
and private
stream wrapper(s).
The solution should be to modify the stream wrappers to return a relative url. However, since this might be a breaking change, we should simply parse what is returned from the stream wrapper, if the result has the same domain as the current domain of the request, then we can just return the relative path (like all other entities), rather than the absolute url.
Remaining tasks
- Write Patch
User interface changes
None.
API changes
File entities will now be consistent with all other entities and return a relative url (when possible).
Data model changes
None.
Comments
Comment #2
BerdirThe url() override in the file entity class should be dropped.
It's deprecated and the whole rest integration only works because we call a deprecated method.Once we switch that to toUrl(), it will fail.
If we want to have the URL available, we should instead have a special normalizer for files. See also #1927648: Allow creation of file entities from binary data via REST requests.
Only problem is, existing code might now rely on this method, especially in twig templates. So maybe we do have to keep it, and update rest to do things differently instead.
Comment #3
alexpottFunny enough the absolute path is really likely to cause issues in the templates. It certainly did for a recent C3 client. For example, if the user is logged in and under https the render cache can get polluted with https links.
Comment #4
alexpottAlso somewhat amusingly...
returns...
Drupal\Core\Entity\Exception\UndefinedLinkTemplateException with message 'No link template 'canonical' found for the 'file' entity type'
Comment #5
alexpottJust created #2710069: File entity $entity->toUrl('canonical') is broken to handle #4
Comment #10
Wim LeersI'm tempted to mark this as a duplicate of #2402533: Provide File::createFileUrl() as a replacement for the deprecated File:url() implementation.
Comment #11
Wim Leers#2710069: File entity $entity->toUrl('canonical') is broken was marked a duplicate of #2402533: Provide File::createFileUrl() as a replacement for the deprecated File:url() implementation.
Comment #17
BerdirI'm just going to close this.
url() is gone and toUrl() now has a consistent result in Drupal 9 (meaning, an exception, because it has no canonical link template in core), there is a separate method to the the relative or absolute file URL, createFileUrl().