Issue #1839068 by Berdir, fago: Implement the new entity field API for the file field type.
parent
5c9e37df0a
commit
98294873f5
|
@ -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 @@ class GenericFileFormatter extends FormatterBase {
|
|||
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 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
|||
// 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 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
|||
|
||||
// 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 @@ class FileFieldDisplayTest extends FileFieldTestBase {
|
|||
|
||||
$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 @@ class FileFieldWidgetTest extends FileFieldTestBase {
|
|||
$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);
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<?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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?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.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue