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

8.7.x
Alex Pott 2018-12-14 10:05:18 +00:00
parent 46f02154f8
commit b2160caa3d
No known key found for this signature in database
GPG Key ID: 31905460D4A69276
20 changed files with 115 additions and 37 deletions

View File

@ -206,11 +206,9 @@ class EditorImageDialog extends FormBase {
// 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');

View File

@ -5,6 +5,7 @@ namespace Drupal\editor\Plugin\Filter;
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 @@ class EditorFileReference extends FilterBase implements ContainerFactoryPluginIn
// 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 @@ class EditorFileReference extends FilterBase implements ContainerFactoryPluginIn
$processed_uuids[$uuid] = TRUE;
$file = $this->entityManager->loadEntityByUuid('file', $uuid);
if ($file) {
if ($file instanceof FileInterface) {
$result->addCacheTags($file->getCacheTags());
}
}

View File

@ -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();

View File

@ -74,13 +74,25 @@ class File extends ContentEntityBase implements FileInterface {
$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);
}
/**

View File

@ -50,6 +50,20 @@ interface FileInterface extends ContentEntityInterface, EntityChangedInterface,
*/
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.
*

View File

@ -196,7 +196,7 @@ abstract class FileMediaFormatterBase extends FileFormatterBase implements FileM
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[] = [

View File

@ -25,13 +25,14 @@ class RSSEnclosureFormatter extends FileFormatterBase {
// 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(),
],

View File

@ -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 @@ class UrlPlainFormatter extends FileFormatterBase {
$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(),
],

View File

@ -92,7 +92,7 @@ class FileFieldWidgetTest extends FileFieldTestBase {
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
// 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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
$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).

View File

@ -211,7 +211,7 @@ class FileFieldDisplayTest extends FileFieldTestBase {
// 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 @@ class FileFieldDisplayTest extends FileFieldTestBase {
])->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);
}
/**

View File

@ -46,8 +46,8 @@ class FileAudioFormatterTest extends FileMediaFormatterTestBase {
$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);

View File

@ -46,8 +46,8 @@ class FileVideoFormatterTest extends FileMediaFormatterTestBase {
$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);

View File

@ -99,7 +99,6 @@ class FileItemTest extends FieldKernelTestBase {
$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());

View File

@ -0,0 +1,49 @@
<?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());
}
}

View File

@ -83,7 +83,7 @@ class FileEntityNormalizer extends ContentEntityNormalizer {
// 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);
}
}

View File

@ -45,7 +45,7 @@ class FileNormalizeTest extends NormalizerTestBase {
'uri' => [
[
'value' => $file->getFileUri(),
'url' => file_url_transform_relative(file_create_url($file->getFileUri())),
'url' => $file->createFileUrl(),
],
],
];

View File

@ -277,7 +277,7 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
$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.

View File

@ -53,7 +53,7 @@ class MediaHalJsonAnonTest extends MediaResourceTestBase {
],
$this->baseUrl . '/rest/relation/media/camelids/field_media_file' => [
[
'href' => $file->url(),
'href' => $file->createFileUrl(FALSE),
'lang' => 'en',
],
],
@ -64,7 +64,7 @@ class MediaHalJsonAnonTest extends MediaResourceTestBase {
],
$this->baseUrl . '/rest/relation/media/camelids/thumbnail' => [
[
'href' => $thumbnail->url(),
'href' => $thumbnail->createFileUrl(FALSE),
'lang' => 'en',
],
],
@ -80,7 +80,7 @@ class MediaHalJsonAnonTest extends MediaResourceTestBase {
[
'_links' => [
'self' => [
'href' => $file->url(),
'href' => $file->createFileUrl(FALSE),
],
'type' => [
'href' => $this->baseUrl . '/rest/type/file/file',
@ -115,7 +115,7 @@ class MediaHalJsonAnonTest extends MediaResourceTestBase {
[
'_links' => [
'self' => [
'href' => $thumbnail->url(),
'href' => $thumbnail->createFileUrl(FALSE),
],
'type' => [
'href' => $this->baseUrl . '/rest/type/file/file',

View File

@ -176,7 +176,7 @@ abstract class MediaResourceTestBase extends EntityResourceTestBase {
'target_id' => (int) $file->id(),
'target_type' => 'file',
'target_uuid' => $file->uuid(),
'url' => $file->url(),
'url' => $file->createFileUrl(FALSE),
],
],
'thumbnail' => [
@ -188,7 +188,7 @@ abstract class MediaResourceTestBase extends EntityResourceTestBase {
'target_type' => 'file',
'target_uuid' => $thumbnail->uuid(),
'title' => NULL,
'url' => $thumbnail->url(),
'url' => $thumbnail->createFileUrl(FALSE),
],
],
'status' => [

View File

@ -9,6 +9,7 @@ use Drupal\Core\Field\FieldItemListInterface;
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 @@ class ResponsiveImageFormatter extends ImageFormatterBase implements ContainerFa
}
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.