Commit 98294873 authored by catch's avatar catch
Browse files

Issue #1839068 by Berdir, fago: Implement the new entity field API for the file field type.

parent 5c9e37df
......@@ -996,6 +996,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options
* An array of field items keyed by delta if available, FALSE otherwise.
*/
function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) {
$entity = $entity->getBCEntity();
$langcode = field_language($entity, $field_name, $langcode);
return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : FALSE;
}
......
......@@ -29,6 +29,7 @@ function file_field_info() {
),
'default_widget' => 'file_generic',
'default_formatter' => 'file_default',
'field item class' => '\Drupal\file\Type\FileItem',
),
);
}
......
......@@ -590,7 +590,7 @@ function file_theme() {
return array(
// file.module.
'file_link' => array(
'variables' => array('file' => NULL, 'icon_directory' => NULL),
'variables' => array('file' => NULL, 'icon_directory' => NULL, 'description' => NULL),
),
'file_icon' => array(
'variables' => array('file' => NULL, 'icon_directory' => NULL),
......@@ -1238,6 +1238,7 @@ function file_managed_file_pre_render($element) {
* - icon_directory: (optional) A path to a directory of icons to be used for
* files. Defaults to the value of the "icon.directory"
* variable.
* - description: A description to be displayed instead of the filename.
*
* @ingroup themeable
*/
......@@ -1247,7 +1248,7 @@ function theme_file_link($variables) {
$url = file_create_url($file->uri);
// theme_file_icon() requires a file entity, make sure it gets one.
$icon = theme('file_icon', array('file' => ($file instanceof File) ? $file : file_load($file->fid), 'icon_directory' => $icon_directory));
$icon = theme('file_icon', array('file' => $file, 'icon_directory' => $icon_directory));
// Set options as per anchor format described at
// http://microformats.org/wiki/file-format-examples
......@@ -1258,11 +1259,11 @@ function theme_file_link($variables) {
);
// Use the description as the link text if available.
if (empty($file->description)) {
if (empty($variables['description'])) {
$link_text = $file->filename;
}
else {
$link_text = $file->description;
$link_text = $variables['description'];
$options['attributes']['title'] = check_plain($file->filename);
}
......
......@@ -35,7 +35,8 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
foreach ($items as $delta => $item) {
$elements[$delta] = array(
'#theme' => 'file_link',
'#file' => (object) $item,
'#file' => file_load($item['fid']),
'#description' => $item['description'],
);
}
......
......@@ -41,7 +41,9 @@ function testNodeDisplay() {
// Create a new node *without* the file field set, and check that the field
// is not shown for each node display.
$node = $this->drupalCreateNode(array('type' => $type_name));
$file_formatters = array('file_default', 'file_table', 'file_url_plain', 'hidden');
// Check file_default last as the assertions below assume that this is the
// case.
$file_formatters = array('file_table', 'file_url_plain', 'hidden', 'file_default');
foreach ($file_formatters as $formatter) {
$edit = array(
"fields[$field_name][type]" => $formatter,
......@@ -55,7 +57,6 @@ function testNodeDisplay() {
// Create a new node with the uploaded file.
$nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
$this->drupalGet('node/' . $nid . '/edit');
// Check that the default formatter is displaying with the file name.
$node = node_load($nid, TRUE);
......@@ -69,5 +70,13 @@ function testNodeDisplay() {
$this->assertNoRaw($default_output, t('Field is hidden when "display" option is unchecked.'));
// Add a description and make sure that it is displayed.
$description = $this->randomName();
$edit = array(
$field_name . '[' . LANGUAGE_NOT_SPECIFIED . '][0][description]' => $description,
$field_name . '[' . LANGUAGE_NOT_SPECIFIED . '][0][display]' => TRUE,
);
$this->drupalPost('node/' . $nid . '/edit', $edit, t('Save and keep published'));
$this->assertText($description);
}
}
......@@ -285,7 +285,7 @@ function testPrivateFileComment() {
$this->drupalLogin($user);
$comment = comment_load($cid);
$comment_file = file_load($comment->{'field_' . $name}[LANGUAGE_NOT_SPECIFIED][0]['fid']);
$comment_file = $comment->{'field_' . $name}->entity;
$this->assertFileExists($comment_file, t('New file saved to disk on node creation.'));
// Test authenticated file download.
$url = file_create_url($comment_file->uri);
......
<?php
/**
* @file
* Contains \Drupal\file\Tests\FileItemTest.
*/
namespace Drupal\file\Tests;
use Drupal\Core\Entity\Field\FieldItemInterface;
use Drupal\Core\Entity\Field\FieldInterface;
use Drupal\field\Tests\FieldItemUnitTestBase;
/**
* Tests the new entity API for the file field type.
*/
class FileItemTest extends FieldItemUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('file');
/**
* Created file entity.
*
* @var \Drupal\file\Plugin\Core\Entity\File
*/
protected $file;
public static function getInfo() {
return array(
'name' => 'File field item API',
'description' => 'Tests using entity fields of the file field type.',
'group' => 'File',
);
}
public function setUp() {
parent::setUp();
$this->installSchema('file', 'file_managed');
$this->installSchema('file', 'file_usage');
$field = array(
'field_name' => 'file_test',
'type' => 'file',
'cardinality' => FIELD_CARDINALITY_UNLIMITED,
);
field_create_field($field);
$instance = array(
'entity_type' => 'entity_test',
'field_name' => 'file_test',
'bundle' => 'entity_test',
'widget' => array(
'type' => 'options_select',
),
);
field_create_instance($instance);
file_put_contents('public://example.txt', $this->randomName());
$this->file = entity_create('file', array(
'uri' => 'public://example.txt',
));
$this->file->save();
}
/**
* Tests using entity fields of the file field type.
*/
public function testFileItem() {
// Create a test entity with the
$entity = entity_create('entity_test', array());
$entity->file_test->fid = $this->file->id();
$entity->file_test->display = 1;
$entity->file_test->description = $description = $this->randomName();
$entity->name->value = $this->randomName();
$entity->save();
$entity = entity_load('entity_test', $entity->id());
$this->assertTrue($entity->file_test instanceof FieldInterface, 'Field implements interface.');
$this->assertTrue($entity->file_test[0] instanceof FieldItemInterface, 'Field item implements interface.');
$this->assertEqual($entity->file_test->fid, $this->file->id());
$this->assertEqual($entity->file_test->display, 1);
$this->assertEqual($entity->file_test->description, $description);
$this->assertEqual($entity->file_test->entity->uri, $this->file->uri);
$this->assertEqual($entity->file_test->entity->id(), $this->file->id());
$this->assertEqual($entity->file_test->entity->uuid(), $this->file->uuid());
// Make sure the computed files reflects updates to the file.
file_put_contents('public://example-2.txt', $this->randomName());
$file2 = entity_create('file', array(
'uri' => 'public://example-2.txt',
));
$file2->save();
$entity->file_test->fid = $file2->id();
$this->assertEqual($entity->file_test->entity->id(), $file2->id());
$this->assertEqual($entity->file_test->entity->uri, $file2->uri);
}
}
<?php
/**
* @file
* Contains \Drupal\file\Type\FileItem.
*/
namespace Drupal\file\Type;
use Drupal\Core\Entity\Field\FieldItemBase;
/**
* Defines the 'file_field' entity field item.
*/
class FileItem extends FieldItemBase {
/**
* Property definitions of the contained properties.
*
* @see FileItem::getPropertyDefinitions()
*
* @var array
*/
static $propertyDefinitions;
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
*/
public function getPropertyDefinitions() {
if (!isset(static::$propertyDefinitions)) {
static::$propertyDefinitions['fid'] = array(
'type' => 'integer',
'label' => t('Referenced file id.'),
);
static::$propertyDefinitions['display'] = array(
'type' => 'boolean',
'label' => t('Flag to control whether this file should be displayed when viewing content.'),
);
static::$propertyDefinitions['description'] = array(
'type' => 'string',
'label' => t('A description of the file.'),
);
static::$propertyDefinitions['entity'] = array(
'type' => 'entity',
'constraints' => array(
'EntityType' => 'file',
),
'label' => t('File'),
'description' => t('The referenced file'),
// The entity object is computed out of the fid.
'computed' => TRUE,
'read-only' => FALSE,
'settings' => array('id source' => 'fid'),
);
}
return static::$propertyDefinitions;
}
/**
* Overrides \Drupal\Core\Entity\Field\FieldItemBase::setValue().
*/
public function setValue($values) {
// Treat the values as property value of the entity field, if no array
// is given.
if (!is_array($values)) {
$values = array('entity' => $values);
}
if (isset($values['display'])) {
$this->properties['display']->setValue($values['display']);
}
if (isset($values['description'])) {
$this->properties['description']->setValue($values['description']);
}
// Entity is computed out of the ID, so we only need to update the ID. Only
// set the entity field if no ID is given.
if (isset($values['fid'])) {
$this->properties['fid']->setValue($values['fid']);
}
elseif (isset($values['entity'])) {
$this->properties['entity']->setValue($values['entity']);
}
else {
$this->properties['entity']->setValue(NULL);
}
unset($values['entity'], $values['fid'], $values['display'], $values['description']);
if ($values) {
throw new \InvalidArgumentException('Property ' . key($values) . ' is unknown.');
}
}
}
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