Update to Drupal 8.0.3. For more information, see https://www.drupal.org/drupal-8.0.3-release-notes

This commit is contained in:
Pantheon Automation 2016-02-03 14:56:31 -08:00 committed by Greg Anderson
parent 10f9f7fbde
commit 9db4fae9a7
202 changed files with 3806 additions and 760 deletions

View file

@ -977,7 +977,12 @@ function file_tokens($type, $tokens, array $data, array $options, BubbleableMeta
break;
case 'url':
// Ideally, this would use file_url_transform_relative(), but because
// 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());
$bubbleable_metadata->addCacheContexts(['url.site']);
break;
// These tokens are default variations on the chained tokens handled below.
@ -1228,7 +1233,13 @@ function template_preprocess_file_link(&$variables) {
$options = array();
$file_entity = ($file instanceof File) ? $file : File::load($file->fid);
// @todo Wrap in file_url_transform_relative(). This is currently
// impossible. As a work-around, we currently add the 'url.site' cache context
// 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());
$variables['#cache']['contexts'][] = 'url.site';
$mime_type = $file->getMimeType();
// Set options as per anchor format described at

View file

@ -70,6 +70,8 @@ class File extends ContentEntityBase implements FileInterface {
/**
* {@inheritdoc}
*
* @see file_url_transform_relative()
*/
public function url($rel = 'canonical', $options = array()) {
return file_create_url($this->getFileUri());

View file

@ -52,6 +52,8 @@ abstract class BaseFieldFileFormatterBase extends FormatterBase {
$url = NULL;
// Add support to link to the entity itself.
if ($this->getSetting('link_to_file')) {
// @todo Wrap in file_url_transform_relative(). This is currently
// impossible. See below.
$url = file_create_url($items->getEntity()->uri->value);
}
@ -63,6 +65,16 @@ abstract class BaseFieldFileFormatterBase extends FormatterBase {
'#type' => 'link',
'#title' => $view_value,
'#url' => Url::fromUri($url),
// @todo Remove the 'url.site' cache context by using a relative file
// URL (file_url_transform_relative()). This is currently impossible
// because #type => link requires a Url object, and Url objects do not
// support relative URLs: they require fully qualified URLs. Fix in
// https://www.drupal.org/node/2646744.
'#cache' => [
'contexts' => [
'url.site',
],
],
];
}
else {

View file

@ -55,6 +55,9 @@ class FileUriFormatter extends BaseFieldFileFormatterBase {
protected function viewValue(FieldItemInterface $item) {
$value = $item->value;
if ($this->getSetting('file_download_path')) {
// @todo Wrap in file_url_transform_relative(). This is currently
// impossible. See BaseFieldFileFormatterBase::viewElements(). Fix in
// https://www.drupal.org/node/2646744.
$value = file_create_url($value);
}
return $value;

View file

@ -33,6 +33,9 @@ class RSSEnclosureFormatter extends FileFormatterBase {
$entity->rss_elements[] = array(
'key' => 'enclosure',
'attributes' => array(
// 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()),
'length' => $file->getSize(),
'type' => $file->getMimeType(),

View file

@ -30,7 +30,7 @@ class UrlPlainFormatter extends FileFormatterBase {
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
$elements[$delta] = array(
'#markup' => file_create_url($file->getFileUri()),
'#markup' => file_url_transform_relative(file_create_url($file->getFileUri())),
'#cache' => array(
'tags' => $file->getCacheTags(),
),

View file

@ -56,9 +56,11 @@ class FileFieldItemList extends EntityReferenceFieldItemList {
$original_ids = array();
$langcode = $this->getLangcode();
$original = $entity->original;
$original_items = $original->hasTranslation($langcode) ? $original->getTranslation($langcode)->{$field_name} : $original->{$field_name};
foreach ($original_items as $item) {
$original_ids[] = $item->target_id;
if ($original->hasTranslation($langcode)) {
$original_items = $original->getTranslation($langcode)->{$field_name};
foreach ($original_items as $item) {
$original_ids[] = $item->target_id;
}
}
// Decrement file usage by 1 for files that were removed from the field.

View file

@ -186,7 +186,6 @@ class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface {
$elements['#description'] = $description;
$elements['#field_name'] = $field_name;
$elements['#language'] = $items->getLangcode();
$elements['#display_field'] = (bool) $this->getFieldSetting('display_field');
// The field settings include defaults for the field type. However, this
// widget is a base class for other widgets (e.g., ImageWidget) that may
// act on field types without these expected settings.

View file

@ -2,10 +2,10 @@
/**
* @file
* Contains \Drupal\file\Plugin\migrate\cckfield\FileField.
* Contains \Drupal\file\Plugin\migrate\cckfield\d6\FileField.
*/
namespace Drupal\file\Plugin\migrate\cckfield;
namespace Drupal\file\Plugin\migrate\cckfield\d6;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate\Row;

View file

@ -0,0 +1,67 @@
<?php
/**
* @file
* Contains \Drupal\file\Plugin\migrate\cckfield\d7\FileField.
*/
namespace Drupal\file\Plugin\migrate\cckfield\d7;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
/**
* @MigrateCckField(
* id = "file",
* )
*/
class FileField extends CckFieldPluginBase {
/**
* {@inheritdoc}
*/
public function getFieldWidgetMap() {
return [
'filefield_widget' => 'file_generic',
];
}
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {
return [
'default' => 'file_default',
'url_plain' => 'file_url_plain',
'path_plain' => 'file_url_plain',
'image_plain' => 'image',
'image_nodelink' => 'image',
'image_imagelink' => 'image',
];
}
/**
* {@inheritdoc}
*/
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {
$process = [
'plugin' => 'iterator',
'source' => $field_name,
'process' => [
'target_id' => 'fid',
'display' => 'display',
'description' => 'description',
],
];
$migration->mergeProcessOfProperty($field_name, $process);
}
/**
* {@inheritdoc}
*/
public function getFieldType(Row $row) {
return $row->getSourceProperty('widget_type') == 'imagefield_widget' ? 'image' : 'file';
}
}

View file

@ -0,0 +1,45 @@
<?php
/**
* @file
* Contains \Drupal\file\Plugin\migrate\cckfield\d7\ImageField.
*/
namespace Drupal\file\Plugin\migrate\cckfield\d7;
use Drupal\migrate\Entity\MigrationInterface;
use Drupal\migrate_drupal\Plugin\migrate\cckfield\CckFieldPluginBase;
/**
* @MigrateCckField(
* id = "image"
* )
*/
class ImageField extends CckFieldPluginBase {
/**
* {@inheritdoc}
*/
public function getFieldFormatterMap() {
return array();
}
/**
* {@inheritdoc}
*/
public function processCckFieldValues(MigrationInterface $migration, $field_name, $data) {
$process = [
'plugin' => 'iterator',
'source' => $field_name,
'process' => [
'target_id' => 'fid',
'alt' => 'alt',
'title' => 'title',
'width' => 'width',
'height' => 'height',
],
];
$migration->mergeProcessOfProperty($field_name, $process);
}
}

View file

@ -69,6 +69,12 @@ class File extends FieldPluginBase {
protected function renderLink($data, ResultRow $values) {
if (!empty($this->options['link_to_file']) && $data !== NULL && $data !== '') {
$this->options['alter']['make_link'] = TRUE;
// @todo Wrap in file_url_transform_relative(). This is currently
// impossible. As a work-around, we could add the 'url.site' cache context
// to ensure different file URLs are generated for different sites in a
// multisite setup, including HTTP and HTTPS versions of the same site.
// But unfortunately it's impossible to bubble a cache context here.
// Fix in https://www.drupal.org/node/2646744.
$this->options['alter']['path'] = file_create_url($this->getValue($values, 'uri'));
}

View file

@ -0,0 +1,208 @@
<?php
/**
* @file
* Contains \Drupal\file\Tests\FileOnTranslatedEntityTest.
*/
namespace Drupal\file\Tests;
use Drupal\file\Entity\File;
use Drupal\node\Entity\Node;
/**
* Uploads files to translated nodes.
*
* @group file
*/
class FileOnTranslatedEntityTest extends FileFieldTestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('language', 'content_translation');
/**
* The name of the file field used in the test.
*
* @var string
*/
protected $fieldName;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create the "Basic page" node type.
$this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
// Create a file field on the "Basic page" node type.
$this->fieldName = strtolower($this->randomMachineName());
$this->createFileField($this->fieldName, 'node', 'page');
// Create and login user.
$permissions = array(
'access administration pages',
'administer content translation',
'administer content types',
'administer languages',
'create content translations',
'create page content',
'edit any page content',
'translate any entity',
'delete any page content',
);
$admin_user = $this->drupalCreateUser($permissions);
$this->drupalLogin($admin_user);
// Add a second and third language.
$edit = array();
$edit['predefined_langcode'] = 'fr';
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
$edit = array();
$edit['predefined_langcode'] = 'nl';
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
// Enable translation for "Basic page" nodes.
$edit = array(
'entity_types[node]' => 1,
'settings[node][page][translatable]' => 1,
"settings[node][page][fields][$this->fieldName]" => 1,
);
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
\Drupal::entityManager()->clearCachedDefinitions();
}
/**
* Tests synced file fields on translated nodes.
*/
public function testSyncedFiles() {
// Verify that the file field on the "Basic page" node type is translatable.
$definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
$this->assertTrue($definitions[$this->fieldName]->isTranslatable(), 'Node file field is translatable.');
// Create a default language node.
$default_language_node = $this->drupalCreateNode(array('type' => 'page', 'title' => 'Lost in translation'));
// Edit the node to upload a file.
$edit = array();
$name = 'files[' . $this->fieldName . '_0]';
$edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[0]->uri);
$this->drupalPostForm('node/' . $default_language_node->id() . '/edit', $edit, t('Save'));
$first_fid = $this->getLastFileId();
// Translate the node into French: remove the existing file.
$this->drupalPostForm('node/' . $default_language_node->id() . '/translations/add/en/fr', array(), t('Remove'));
// Upload a different file.
$edit = array();
$edit['title[0][value]'] = 'Bill Murray';
$name = 'files[' . $this->fieldName . '_0]';
$edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[1]->uri);
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
// This inspects the HTML after the post of the translation, the file
// should be displayed on the original node.
$this->assertRaw('file--mime-text-plain');
$second_fid = $this->getLastFileId();
\Drupal::entityTypeManager()->getStorage('file')->resetCache();
/* @var $file \Drupal\file\FileInterface */
// Ensure the file status of the first file permanent.
$file = File::load($first_fid);
$this->assertTrue($file->isPermanent());
// Ensure the file status of the second file is permanent.
$file = File::load($second_fid);
$this->assertTrue($file->isPermanent());
// Translate the node into dutch: remove the existing file.
$this->drupalPostForm('node/' . $default_language_node->id() . '/translations/add/en/nl', array(), t('Remove'));
// Upload a different file.
$edit = array();
$edit['title[0][value]'] = 'Scarlett Johansson';
$name = 'files[' . $this->fieldName . '_0]';
$edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[2]->uri);
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
$third_fid = $this->getLastFileId();
\Drupal::entityTypeManager()->getStorage('file')->resetCache();
// Ensure the first file is untouched.
$file = File::load($first_fid);
$this->assertTrue($file->isPermanent(), 'First file still exists and is permanent.');
// This inspects the HTML after the post of the translation, the file
// should be displayed on the original node.
$this->assertRaw('file--mime-text-plain');
// Ensure the file status of the second file is permanent.
$file = File::load($second_fid);
$this->assertTrue($file->isPermanent());
// Ensure the file status of the third file is permanent.
$file = File::load($third_fid);
$this->assertTrue($file->isPermanent());
// Edit the second translation: remove the existing file.
$this->drupalPostForm('fr/node/' . $default_language_node->id() . '/edit', array(), t('Remove'));
// Upload a different file.
$edit = array();
$edit['title[0][value]'] = 'David Bowie';
$name = 'files[' . $this->fieldName . '_0]';
$edit[$name] = drupal_realpath($this->drupalGetTestFiles('text')[3]->uri);
$this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
$replaced_second_fid = $this->getLastFileId();
\Drupal::entityTypeManager()->getStorage('file')->resetCache();
// Ensure the first and third files are untouched.
$file = File::load($first_fid);
$this->assertTrue($file->isPermanent(), 'First file still exists and is permanent.');
$file = File::load($third_fid);
$this->assertTrue($file->isPermanent());
// Ensure the file status of the replaced second file is permanent.
$file = File::load($replaced_second_fid);
$this->assertTrue($file->isPermanent());
// Ensure the file status of the old second file is now temporary.
$file = File::load($second_fid);
$this->assertTrue($file->isTemporary());
// Delete the third translation.
$this->drupalPostForm('nl/node/' . $default_language_node->id() . '/delete', array(), t('Delete Dutch translation'));
\Drupal::entityTypeManager()->getStorage('file')->resetCache();
// Ensure the first and replaced second files are untouched.
$file = File::load($first_fid);
$this->assertTrue($file->isPermanent(), 'First file still exists and is permanent.');
$file = File::load($replaced_second_fid);
$this->assertTrue($file->isPermanent());
// Ensure the file status of the third file is now temporary.
$file = File::load($third_fid);
$this->assertTrue($file->isTemporary());
// Delete the all translations.
$this->drupalPostForm('node/' . $default_language_node->id() . '/delete', array(), t('Delete all translations'));
\Drupal::entityTypeManager()->getStorage('file')->resetCache();
// Ensure the file status of the all files are now temporary.
$file = File::load($first_fid);
$this->assertTrue($file->isTemporary(), 'First file still exists and is temporary.');
$file = File::load($replaced_second_fid);
$this->assertTrue($file->isTemporary());
}
}

View file

@ -66,7 +66,8 @@ class FileTokenReplaceTest extends FileFieldTestBase {
$metadata_tests['[file:path]'] = $base_bubbleable_metadata;
$metadata_tests['[file:mime]'] = $base_bubbleable_metadata;
$metadata_tests['[file:size]'] = $base_bubbleable_metadata;
$metadata_tests['[file:url]'] = $base_bubbleable_metadata;
$bubbleable_metadata = clone $base_bubbleable_metadata;
$metadata_tests['[file:url]'] = $bubbleable_metadata->addCacheContexts(['url.site']);
$bubbleable_metadata = clone $base_bubbleable_metadata;
$metadata_tests['[file:created]'] = $bubbleable_metadata->addCacheTags(['rendered']);
$metadata_tests['[file:created:short]'] = $bubbleable_metadata;