Issue #1956434 by Berdir, amateescu: Fixed Can't edit nodes with entity reference fields.
parent
47fbd65789
commit
0b306f9385
|
|
@ -28,7 +28,8 @@ function entity_reference_field_info() {
|
|||
),
|
||||
'default_widget' => 'entity_reference_autocomplete',
|
||||
'default_formatter' => 'entity_reference_label',
|
||||
'field item class' => '\Drupal\Core\Entity\Field\Type\EntityReferenceItem',
|
||||
'data_type' => 'entity_reference_configurable_field',
|
||||
'field item class' => '\Drupal\entity_reference\Type\ConfigurableEntityReferenceItem',
|
||||
);
|
||||
return $field_info;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,26 +7,25 @@
|
|||
|
||||
namespace Drupal\entity_reference\Tests;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\entity_reference\Type\EntityReferenceItem;
|
||||
use Drupal\Core\Entity\Field\FieldItemInterface;
|
||||
use Drupal\Core\Entity\Field\FieldInterface;
|
||||
use Drupal\Core\Entity\Field\FieldItemInterface;
|
||||
use Drupal\field\Tests\FieldUnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests the new entity API for the entity reference field type.
|
||||
*/
|
||||
class EntityReferenceItemTest extends WebTestBase {
|
||||
class EntityReferenceItemTest extends FieldUnitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('field', 'field_sql_storage', 'entity_test', 'options', 'entity_reference');
|
||||
public static $modules = array('entity_reference', 'taxonomy', 'options');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Entity Reference field API',
|
||||
'name' => 'Entity Reference field item',
|
||||
'description' => 'Tests using entity fields of the entity reference field type.',
|
||||
'group' => 'Entity Reference',
|
||||
);
|
||||
|
|
@ -38,44 +37,65 @@ class EntityReferenceItemTest extends WebTestBase {
|
|||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installSchema('taxonomy', 'taxonomy_term_data');
|
||||
$this->installSchema('taxonomy', 'taxonomy_term_hierarchy');
|
||||
|
||||
$vocabulary = entity_create('taxonomy_vocabulary', array(
|
||||
'name' => $this->randomName(),
|
||||
'vid' => drupal_strtolower($this->randomName()),
|
||||
'langcode' => LANGUAGE_NOT_SPECIFIED,
|
||||
));
|
||||
$vocabulary->save();
|
||||
|
||||
$this->term = entity_create('taxonomy_term', array(
|
||||
'name' => $this->randomName(),
|
||||
'vid' => $vocabulary->id(),
|
||||
'langcode' => LANGUAGE_NOT_SPECIFIED,
|
||||
));
|
||||
$this->term->save();
|
||||
|
||||
// Use the util to create an instance.
|
||||
entity_reference_create_instance('entity_test', 'entity_test', 'field_test', 'Test entity reference', 'node');
|
||||
entity_reference_create_instance('entity_test', 'entity_test', 'field_test_taxonomy', 'Test entity reference', 'taxonomy_term');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests using entity fields of the taxonomy term reference field type.
|
||||
* Tests using entity fields of the entity reference field type.
|
||||
*/
|
||||
public function testEntityReferenceItem() {
|
||||
// Create a node.
|
||||
$node1 = $this->drupalCreateNode();
|
||||
$nid = $node1->id();
|
||||
$tid = $this->term->id();
|
||||
|
||||
// Just being able to create the entity like this verifies a lot of code.
|
||||
$entity = entity_create('entity_test', array('name' => 'foo'));
|
||||
$entity->field_test->target_id = $nid;
|
||||
$entity = entity_create('entity_test', array());
|
||||
$entity->field_test_taxonomy->target_id = $tid;
|
||||
$entity->name->value = $this->randomName();
|
||||
$entity->save();
|
||||
|
||||
$this->assertTrue($entity->field_test instanceof FieldInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_test[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_test->target_id, $nid);
|
||||
$this->assertEqual($entity->field_test->entity->title, $node1->label());
|
||||
$this->assertEqual($entity->field_test->entity->id(), $nid);
|
||||
$this->assertEqual($entity->field_test->entity->uuid(), $node1->uuid());
|
||||
$entity = entity_load('entity_test', $entity->id());
|
||||
$this->assertTrue($entity->field_test_taxonomy instanceof FieldInterface, 'Field implements interface.');
|
||||
$this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.');
|
||||
$this->assertEqual($entity->field_test_taxonomy->target_id, $tid);
|
||||
$this->assertEqual($entity->field_test_taxonomy->entity->name, $this->term->name);
|
||||
$this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid);
|
||||
$this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid());
|
||||
|
||||
// Change the name of the term via the reference.
|
||||
$new_name = $this->randomName();
|
||||
$entity->field_test->entity->title = $new_name;
|
||||
$entity->field_test->entity->save();
|
||||
|
||||
$entity->field_test_taxonomy->entity->name = $new_name;
|
||||
$entity->field_test_taxonomy->entity->save();
|
||||
// Verify it is the correct name.
|
||||
$node = node_load($nid);
|
||||
$this->assertEqual($node->label(), $new_name);
|
||||
$term = entity_load('taxonomy_term', $tid);
|
||||
$this->assertEqual($term->name, $new_name);
|
||||
|
||||
// Make sure the computed node reflects updates to the node id.
|
||||
$node2 = $this->drupalCreateNode();
|
||||
// Make sure the computed term reflects updates to the term id.
|
||||
$term2 = entity_create('taxonomy_term', array(
|
||||
'name' => $this->randomName(),
|
||||
'vid' => $this->term->vid,
|
||||
'langcode' => LANGUAGE_NOT_SPECIFIED,
|
||||
));
|
||||
$term2->save();
|
||||
|
||||
$entity->field_test->target_id = $node2->nid;
|
||||
$this->assertEqual($entity->field_test->entity->id(), $node2->id());
|
||||
$this->assertEqual($entity->field_test->entity->title, $node2->label());
|
||||
$entity->field_test_taxonomy->target_id = $term2->id();
|
||||
$this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->id());
|
||||
$this->assertEqual($entity->field_test_taxonomy->entity->name, $term2->name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_reference\Type\ConfigurableEntityReferenceItem.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_reference\Type;
|
||||
|
||||
use Drupal\Core\Entity\Field\Type\EntityReferenceItem;
|
||||
|
||||
/**
|
||||
* Defines the 'entity_reference_configurable' entity field item.
|
||||
*
|
||||
* Extends the Core 'entity_reference' entity field item with properties for
|
||||
* revision ids, labels (for autocreate) and access.
|
||||
*
|
||||
* Required settings (below the definition's 'settings' key) are:
|
||||
* - target_type: The entity type to reference.
|
||||
*/
|
||||
class ConfigurableEntityReferenceItem extends EntityReferenceItem {
|
||||
|
||||
/**
|
||||
* Definitions of the contained properties.
|
||||
*
|
||||
* @see ConfigurableEntityReferenceItem::getPropertyDefinitions()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static $propertyDefinitions;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Entity\Field\Type\EntityReferenceItem::getPropertyDefinitions().
|
||||
*/
|
||||
public function getPropertyDefinitions() {
|
||||
// Definitions vary by entity type, so key them by entity type.
|
||||
$target_type = $this->definition['settings']['target_type'];
|
||||
|
||||
if (!isset(self::$propertyDefinitions[$target_type])) {
|
||||
// Call the parent to define the target_id and entity properties.
|
||||
parent::getPropertyDefinitions();
|
||||
|
||||
static::$propertyDefinitions[$target_type]['revision_id'] = array(
|
||||
// @todo: Lookup the entity type's ID data type and use it here.
|
||||
'type' => 'integer',
|
||||
'label' => t('Revision ID'),
|
||||
'constraints' => array(
|
||||
'Range' => array('min' => 0),
|
||||
),
|
||||
);
|
||||
static::$propertyDefinitions[$target_type]['label'] = array(
|
||||
'type' => 'string',
|
||||
'label' => t('Label (auto-create)'),
|
||||
'computed' => TRUE,
|
||||
);
|
||||
static::$propertyDefinitions[$target_type]['access'] = array(
|
||||
'type' => 'boolean',
|
||||
'label' => t('Access'),
|
||||
'computed' => TRUE,
|
||||
);
|
||||
}
|
||||
return static::$propertyDefinitions[$target_type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Entity\Field\Type\EntityReferenceItem::setValue().
|
||||
*/
|
||||
public function setValue($values) {
|
||||
// Treat the values as property value of the entity field, if no array
|
||||
// is given. That way we support setting the field by entity ID or object.
|
||||
if (!is_array($values)) {
|
||||
$values = array('entity' => $values);
|
||||
}
|
||||
|
||||
foreach (array('revision_id', 'access', 'label') as $property) {
|
||||
if (array_key_exists($property, $values)) {
|
||||
$this->properties[$property]->setValue($values[$property]);
|
||||
unset($values[$property]);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass the remaining values through to the parent class.
|
||||
parent::setValue($values);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -372,16 +372,13 @@ function field_data_type_info() {
|
|||
$items = array();
|
||||
|
||||
// Expose data types for all the field type items.
|
||||
// @todo: Make 'field item class' mandatory.
|
||||
foreach ($field_types as $type_name => $type_info) {
|
||||
|
||||
if (!empty($type_info['field item class'])) {
|
||||
$items[$type_name . '_field'] = array(
|
||||
'label' => t('Field !label item', array('!label' => $type_info['label'])),
|
||||
'class' => $type_info['field item class'],
|
||||
'list class' => !empty($type_info['field class']) ? $type_info['field class'] : '\Drupal\Core\Entity\Field\Type\Field',
|
||||
);
|
||||
}
|
||||
$data_type = isset($type_info['data_type']) ? $type_info['data_type'] : $type_name . '_field';
|
||||
$items[$data_type] = array(
|
||||
'label' => t('Field !label item', array('!label' => $type_info['label'])),
|
||||
'class' => $type_info['field item class'],
|
||||
'list class' => !empty($type_info['field class']) ? $type_info['field class'] : '\Drupal\Core\Entity\Field\Type\Field',
|
||||
);
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
|
@ -441,7 +438,7 @@ function field_entity_field_info($entity_type) {
|
|||
// @todo: Allow for adding field type settings.
|
||||
$definition = array(
|
||||
'label' => t('Field !name', array('!name' => $field_name)),
|
||||
'type' => $field['type'] . '_field',
|
||||
'type' => isset($field_types[$field['type']]['data_type']) ? $field_types[$field['type']]['data_type'] : $field['type'] . '_field',
|
||||
'configurable' => TRUE,
|
||||
'translatable' => !empty($field['translatable'])
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue