Unverified Commit b2160caa authored by alexpott's avatar alexpott

Issue #2402533 by YesCT, Berdir, tamasd, tjwelde, Wim Leers, vijaycs85,...

Issue #2402533 by YesCT, Berdir, tamasd, tjwelde, Wim Leers, vijaycs85, alexpott, slashrsm, Leon Kessler, chr.fritsch, borisson_: Provide File::createFileUrl() as a replacement for the deprecated File:url() implementation
parent 46f02154
......@@ -206,11 +206,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
// attributes and set data-entity-type to 'file'.
$fid = $form_state->getValue(['fid', 0]);
if (!empty($fid)) {
/** @var \Drupal\file\FileInterface $file */
$file = $this->fileStorage->load($fid);
$file_url = file_create_url($file->getFileUri());
// Transform absolute image URLs to relative image URLs: prevent problems
// on multisite set-ups and prevent mixed content errors.
$file_url = file_url_transform_relative($file_url);
$file_url = $file->createFileUrl();
$form_state->setValue(['attributes', 'src'], $file_url);
$form_state->setValue(['attributes', 'data-entity-uuid'], $file->uuid());
$form_state->setValue(['attributes', 'data-entity-type'], 'file');
......
......@@ -5,6 +5,7 @@
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\file\FileInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -76,8 +77,8 @@ public function process($text, $langcode) {
// URL. This ensures the URL works even after the file location changes.
if ($node->hasAttribute('src')) {
$file = $this->entityManager->loadEntityByUuid('file', $uuid);
if ($file) {
$node->setAttribute('src', file_url_transform_relative(file_create_url($file->getFileUri())));
if ($file instanceof FileInterface) {
$node->setAttribute('src', $file->createFileUrl());
}
}
......@@ -86,7 +87,7 @@ public function process($text, $langcode) {
$processed_uuids[$uuid] = TRUE;
$file = $this->entityManager->loadEntityByUuid('file', $uuid);
if ($file) {
if ($file instanceof FileInterface) {
$result->addCacheTags($file->getCacheTags());
}
}
......
......@@ -1171,7 +1171,7 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta
// tokens are also often used in e-mails, it's better to keep absolute
// file URLs. The 'url.site' cache context is associated to ensure the
// correct absolute URL is used in case of a multisite setup.
$replacements[$original] = file_create_url($file->getFileUri());
$replacements[$original] = $file->createFileUrl(FALSE);
$bubbleable_metadata->addCacheContexts(['url.site']);
break;
......@@ -1431,7 +1431,7 @@ function template_preprocess_file_link(&$variables) {
// to ensure different file URLs are generated for different sites in a
// multisite setup, including HTTP and HTTPS versions of the same site.
// Fix in https://www.drupal.org/node/2646744.
$url = file_create_url($file_entity->getFileUri());
$url = $file_entity->createFileUrl(FALSE);
$variables['#cache']['contexts'][] = 'url.site';
$mime_type = $file->getMimeType();
......
......@@ -74,13 +74,25 @@ public function setFileUri($uri) {
$this->get('uri')->value = $uri;
}
/**
* {@inheritdoc}
*/
public function createFileUrl($relative = TRUE) {
$url = file_create_url($this->getFileUri());
if ($relative && $url) {
$url = file_url_transform_relative($url);
}
return $url;
}
/**
* {@inheritdoc}
*
* @see file_url_transform_relative()
*/
public function url($rel = 'canonical', $options = []) {
return file_create_url($this->getFileUri());
@trigger_error('File entities returning the URL to the physical file in File::url() is deprecated, use $file->createFileUrl() instead. See https://www.drupal.org/node/3019830', E_USER_DEPRECATED);
return $this->createFileUrl(FALSE);
}
/**
......
......@@ -50,6 +50,20 @@ public function getFileUri();
*/
public function setFileUri($uri);
/**
* Creates a file URL for the URI of this file.
*
* @param bool $relative
* (optional) Whether the URL should be root-relative, defaults to TRUE.
*
* @return string
* A string containing a URL that may be used to access the file.
*
* @see file_create_url()
* @see file_url_transform_relative()
*/
public function createFileUrl($relative = TRUE);
/**
* Returns the MIME type of the file.
*
......
......@@ -196,7 +196,7 @@ protected function getSourceFiles(EntityReferenceFieldItemListInterface $items,
if (static::mimeTypeApplies($file->getMimeType())) {
$source_attributes = new Attribute();
$source_attributes
->setAttribute('src', file_url_transform_relative(file_create_url($file->getFileUri())))
->setAttribute('src', $file->createFileUrl())
->setAttribute('type', $file->getMimeType());
if ($this->getSetting('multiple_file_display_type') === 'tags') {
$source_files[] = [
......
......@@ -25,13 +25,14 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
// Add the first file as an enclosure to the RSS item. RSS allows only one
// enclosure per item. See: http://wikipedia.org/wiki/RSS_enclosure
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
/** @var \Drupal\file\FileInterface $file */
$entity->rss_elements[] = [
'key' => 'enclosure',
'attributes' => [
// In RSS feeds, it is necessary to use absolute URLs. The 'url.site'
// cache context is already associated with RSS feed responses, so it
// does not need to be specified here.
'url' => file_create_url($file->getFileUri()),
'url' => $file->createFileUrl(FALSE),
'length' => $file->getSize(),
'type' => $file->getMimeType(),
],
......
......@@ -3,6 +3,7 @@
namespace Drupal\file\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\file\FileInterface;
/**
* Plugin implementation of the 'file_url_plain' formatter.
......@@ -24,8 +25,9 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
assert($file instanceof FileInterface);
$elements[$delta] = [
'#markup' => file_url_transform_relative(file_create_url($file->getFileUri())),
'#markup' => $file->createFileUrl(),
'#cache' => [
'tags' => $file->getCacheTags(),
],
......
......@@ -92,7 +92,7 @@ public function testSingleValuedWidget() {
$this->assertFileExists($node_file, 'New file saved to disk on node creation.');
// Ensure the file can be downloaded.
$this->drupalGet(file_create_url($node_file->getFileUri()));
$this->drupalGet($node_file->createFileUrl());
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
// Ensure the edit page has a remove button instead of an upload button.
......@@ -322,7 +322,7 @@ public function testPrivateFileSetting() {
$this->assertFileExists($node_file, 'New file saved to disk on node creation.');
// Ensure the private file is available to the user who uploaded it.
$this->drupalGet(file_create_url($node_file->getFileUri()));
$this->drupalGet($node_file->createFileUrl());
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
// Ensure we can't change 'uri_scheme' field settings while there are some
......@@ -388,14 +388,14 @@ public function testPrivateFileComment() {
$comment_file = $comment->{'field_' . $name}->entity;
$this->assertFileExists($comment_file, 'New file saved to disk on node creation.');
// Test authenticated file download.
$url = file_create_url($comment_file->getFileUri());
$url = $comment_file->createFileUrl();
$this->assertNotEqual($url, NULL, 'Confirmed that the URL is valid');
$this->drupalGet(file_create_url($comment_file->getFileUri()));
$this->drupalGet($url);
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
// Test anonymous file download.
$this->drupalLogout();
$this->drupalGet(file_create_url($comment_file->getFileUri()));
$this->drupalGet($url);
$this->assertResponse(403, 'Confirmed that access is denied for the file without the needed permission.');
// Unpublishes node.
......@@ -405,7 +405,7 @@ public function testPrivateFileComment() {
// Ensures normal user can no longer download the file.
$this->drupalLogin($user);
$this->drupalGet(file_create_url($comment_file->getFileUri()));
$this->drupalGet($url);
$this->assertResponse(403, 'Confirmed that access is denied for the file without the needed permission.');
}
......@@ -575,7 +575,7 @@ protected function doTestTemporaryFileRemovalExploit(UserInterface $victim_user,
$this->assertEqual($attacker_user->id(), $node_file->getOwnerId(), 'New file belongs to the attacker.');
// Ensure the file can be downloaded.
$this->drupalGet(file_create_url($node_file->getFileUri()));
$this->drupalGet($node_file->createFileUrl());
$this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.');
// "Click" the remove button (emulating either a nojs or js submission).
......
......@@ -211,7 +211,7 @@ public function testDescriptionDefaultFileFieldDisplay() {
// Test default formatter.
$this->drupalGet('node/' . $nid);
$this->assertFieldByXPath('//a[@href="' . $node->{$field_name}->entity->url() . '"]', $description);
$this->assertFieldByXPath('//a[@href="' . $node->{$field_name}->entity->createFileUrl(FALSE) . '"]', $description);
// Change formatter to "Table of files".
$display = \Drupal::entityTypeManager()->getStorage('entity_view_display')->load('node.' . $type_name . '.default');
......@@ -221,7 +221,7 @@ public function testDescriptionDefaultFileFieldDisplay() {
])->save();
$this->drupalGet('node/' . $nid);
$this->assertFieldByXPath('//a[@href="' . $node->{$field_name}->entity->url() . '"]', $description);
$this->assertFieldByXPath('//a[@href="' . $node->{$field_name}->entity->createFileUrl(FALSE) . '"]', $description);
}
/**
......
......@@ -46,8 +46,8 @@ public function testRender($tag_count, $formatter_settings) {
$this->drupalGet($entity->toUrl());
$file1_url = file_url_transform_relative(file_create_url($file1->getFileUri()));
$file2_url = file_url_transform_relative(file_create_url($file2->getFileUri()));
$file1_url = $file1->createFileUrl();
$file2_url = $file2->createFileUrl();
$assert_session = $this->assertSession();
$assert_session->elementsCount('css', 'audio[controls="controls"]', $tag_count);
......
......@@ -46,8 +46,8 @@ public function testRender($tag_count, $formatter_settings) {
$this->drupalGet($entity->toUrl());
$file1_url = file_url_transform_relative(file_create_url($file1->getFileUri()));
$file2_url = file_url_transform_relative(file_create_url($file2->getFileUri()));
$file1_url = $file1->createFileUrl();
$file2_url = $file2->createFileUrl();
$assert_session = $this->assertSession();
$assert_session->elementsCount('css', 'video[controls="controls"]', $tag_count);
......
......@@ -99,7 +99,6 @@ public function testFileItem() {
$this->assertEqual($entity->file_test->display, 1);
$this->assertEqual($entity->file_test->description, $description);
$this->assertEqual($entity->file_test->entity->getFileUri(), $this->file->getFileUri());
$this->assertEqual($entity->file_test->entity->url(), $url = file_create_url($this->file->getFileUri()));
$this->assertEqual($entity->file_test->entity->id(), $this->file->id());
$this->assertEqual($entity->file_test->entity->uuid(), $this->file->uuid());
......
<?php
namespace Drupal\Tests\file\Kernel;
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
use Drupal\file\Entity\File;
/**
* Tests file deprecations.
*
* @group file
* @group legacy
*/
class FileLegacyTest extends FieldKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['file'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installConfig(['user']);
$this->installEntitySchema('file');
$this->installSchema('file', ['file_usage']);
}
/**
* Tests that File::url() is deprecated.
*
* @expectedDeprecation File entities returning the URL to the physical file in File::url() is deprecated, use $file->createFileUrl() instead. See https://www.drupal.org/node/3019830
*/
public function testFileUrlDeprecation() {
file_put_contents('public://example.txt', $this->randomMachineName());
$file = File::create([
'uri' => 'public://example.txt',
]);
$file->save();
$this->assertEquals($file->createFileUrl(FALSE), $file->url());
}
}
......@@ -83,7 +83,7 @@ protected function getEntityUri(EntityInterface $entity, array $context = []) {
// back to the old behavior because it relies on said hack, not just to
// generate the value for the 'uri' field of a file (see ::normalize()), but
// also for the HAL normalization's '_links' value.
return file_create_url($entity->getFileUri());
return $entity->createFileUrl(FALSE);
}
}
......@@ -45,7 +45,7 @@ public function testNormalize() {
'uri' => [
[
'value' => $file->getFileUri(),
'url' => file_url_transform_relative(file_create_url($file->getFileUri())),
'url' => $file->createFileUrl(),
],
],
];
......
......@@ -277,7 +277,7 @@ public function testImageFieldSettings() {
$node = $node_storage->load($nid);
$file = $node->{$field_name}->entity;
$url = file_url_transform_relative(file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri())));
$url = file_url_transform_relative(ImageStyle::load('medium')->buildUrl($file->getFileUri()));
$this->assertTrue($this->cssSelect('img[width=40][height=20][class=image-style-medium][src="' . $url . '"]'));
// Add alt/title fields to the image and verify that they are displayed.
......
......@@ -53,7 +53,7 @@ protected function getExpectedNormalizedEntity() {
],
$this->baseUrl . '/rest/relation/media/camelids/field_media_file' => [
[
'href' => $file->url(),
'href' => $file->createFileUrl(FALSE),
'lang' => 'en',
],
],
......@@ -64,7 +64,7 @@ protected function getExpectedNormalizedEntity() {
],
$this->baseUrl . '/rest/relation/media/camelids/thumbnail' => [
[
'href' => $thumbnail->url(),
'href' => $thumbnail->createFileUrl(FALSE),
'lang' => 'en',
],
],
......@@ -80,7 +80,7 @@ protected function getExpectedNormalizedEntity() {
[
'_links' => [
'self' => [
'href' => $file->url(),
'href' => $file->createFileUrl(FALSE),
],
'type' => [
'href' => $this->baseUrl . '/rest/type/file/file',
......@@ -115,7 +115,7 @@ protected function getExpectedNormalizedEntity() {
[
'_links' => [
'self' => [
'href' => $thumbnail->url(),
'href' => $thumbnail->createFileUrl(FALSE),
],
'type' => [
'href' => $this->baseUrl . '/rest/type/file/file',
......
......@@ -176,7 +176,7 @@ protected function getExpectedNormalizedEntity() {
'target_id' => (int) $file->id(),
'target_type' => 'file',
'target_uuid' => $file->uuid(),
'url' => $file->url(),
'url' => $file->createFileUrl(FALSE),
],
],
'thumbnail' => [
......@@ -188,7 +188,7 @@ protected function getExpectedNormalizedEntity() {
'target_type' => 'file',
'target_uuid' => $thumbnail->uuid(),
'title' => NULL,
'url' => $thumbnail->url(),
'url' => $thumbnail->createFileUrl(FALSE),
],
],
'status' => [
......
......@@ -9,6 +9,7 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\file\FileInterface;
use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;
use Drupal\responsive_image\Entity\ResponsiveImageStyle;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -227,9 +228,10 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
}
foreach ($files as $delta => $file) {
assert($file instanceof FileInterface);
// Link the <picture> element to the original file.
if (isset($link_file)) {
$url = file_url_transform_relative(file_create_url($file->getFileUri()));
$url = $file->createFileUrl();
}
// Extract field item attributes for the theme function, and unset them
// from the $item so that the field template does not re-render them.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment