Issue #2114707 by Berdir, yched, amateescu, effulgentsia, fago: Allow per-bundle overrides of field definitions.
parent
eeefed730b
commit
7a6fb338b3
|
@ -213,9 +213,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
*/
|
||||
public function getDataDefinition() {
|
||||
$definition = EntityDataDefinition::create($this->getEntityTypeId());
|
||||
if ($this->bundle() != $this->getEntityTypeId()) {
|
||||
$definition->setBundles(array($this->bundle()));
|
||||
}
|
||||
return $definition;
|
||||
}
|
||||
|
||||
|
@ -485,8 +483,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
*/
|
||||
public function getFieldDefinitions() {
|
||||
if (!isset($this->fieldDefinitions)) {
|
||||
$bundle = $this->bundle != $this->entityTypeId ? $this->bundle : NULL;
|
||||
$this->fieldDefinitions = \Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $bundle);
|
||||
$this->fieldDefinitions = \Drupal::entityManager()->getFieldDefinitions($this->entityTypeId, $this->bundle());
|
||||
}
|
||||
return $this->fieldDefinitions;
|
||||
}
|
||||
|
@ -987,4 +984,11 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
|
|||
return $referenced_entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ interface ContentEntityInterface extends EntityInterface, RevisionableInterface,
|
|||
public function initTranslation($langcode);
|
||||
|
||||
/**
|
||||
* Defines the base fields of the entity type.
|
||||
* Provides base field definitions for an entity type.
|
||||
*
|
||||
* Implementations typically use the class \Drupal\Core\Field\FieldDefinition
|
||||
* for creating the field definitions; for example a 'name' field could be
|
||||
|
@ -50,16 +50,47 @@ interface ContentEntityInterface extends EntityInterface, RevisionableInterface,
|
|||
* ->setLabel(t('Name'));
|
||||
* @endcode
|
||||
*
|
||||
* @param string $entity_type
|
||||
* The entity type to return properties for. Useful when a single class is
|
||||
* used for multiple, possibly dynamic entity types.
|
||||
* If some elements in a field definition need to vary by bundle, use
|
||||
* \Drupal\Core\Entity\ContentEntityInterface::bundleFieldDefinitions().
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition. Useful when a single class is used for multiple,
|
||||
* possibly dynamic entity types.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of entity field definitions, keyed by field name.
|
||||
* An array of base field definitions for the entity type, keyed by field
|
||||
* name.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getFieldDefinitions()
|
||||
* @see \Drupal\Core\Entity\ContentEntityInterface::bundleFieldDefinitions()
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type);
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type);
|
||||
|
||||
/**
|
||||
* Provides or alters field definitions for a specific bundle.
|
||||
*
|
||||
* The field definitions returned here for the bundle take precedence on the
|
||||
* base field definitions specified by baseFieldDefinitions() for the entity
|
||||
* type.
|
||||
*
|
||||
* @todo Provide a better DX for field overrides.
|
||||
* See https://drupal.org/node/2145115.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition. Useful when a single class is used for multiple,
|
||||
* possibly dynamic entity types.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface[] $base_field_definitions
|
||||
* The list of base field definitions.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of bundle field definitions, keyed by field name.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getFieldDefinitions()
|
||||
* @see \Drupal\Core\Entity\ContentEntityInterface::baseFieldDefinitions()
|
||||
*/
|
||||
public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions);
|
||||
|
||||
/**
|
||||
* Returns whether the entity has a field with the given name.
|
||||
|
|
|
@ -78,13 +78,11 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface
|
|||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* An array of field information per entity type, i.e. containing definitions.
|
||||
* Static cache of base field definitions.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @see hook_entity_field_info()
|
||||
*/
|
||||
protected $entityFieldInfo;
|
||||
protected $baseFieldDefinitions;
|
||||
|
||||
/**
|
||||
* Static cache of field definitions per bundle and entity type.
|
||||
|
@ -296,87 +294,140 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldDefinitions($entity_type_id, $bundle = NULL) {
|
||||
if (!isset($this->entityFieldInfo[$entity_type_id])) {
|
||||
// First, try to load from cache.
|
||||
$cid = 'entity_field_definitions:' . $entity_type_id . ':' . $this->languageManager->getCurrentLanguage()->id;
|
||||
public function getBaseFieldDefinitions($entity_type_id) {
|
||||
// Check the static cache.
|
||||
if (!isset($this->baseFieldDefinitions[$entity_type_id])) {
|
||||
// Not prepared, try to load from cache.
|
||||
$cid = 'entity_base_field_definitions:' . $entity_type_id . ':' . $this->languageManager->getCurrentLanguage()->id;
|
||||
if ($cache = $this->cache->get($cid)) {
|
||||
$this->entityFieldInfo[$entity_type_id] = $cache->data;
|
||||
$this->baseFieldDefinitions[$entity_type_id] = $cache->data;
|
||||
}
|
||||
else {
|
||||
// @todo: Refactor to allow for per-bundle overrides.
|
||||
// See https://drupal.org/node/2114707.
|
||||
// Rebuild the definitions and put it into the cache.
|
||||
$this->baseFieldDefinitions[$entity_type_id] = $this->buildBaseFieldDefinitions($entity_type_id);
|
||||
$this->cache->set($cid, $this->baseFieldDefinitions[$entity_type_id], Cache::PERMANENT, array('entity_types' => TRUE, 'entity_field_info' => TRUE));
|
||||
}
|
||||
}
|
||||
return $this->baseFieldDefinitions[$entity_type_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds base field definitions for an entity type.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type ID. Only entity types that implement
|
||||
* \Drupal\Core\Entity\ContentEntityInterface are supported
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of field definitions, keyed by field name.
|
||||
*
|
||||
* @throws \LogicException
|
||||
* Thrown if one of the entity keys is flagged as translatable.
|
||||
*/
|
||||
protected function buildBaseFieldDefinitions($entity_type_id) {
|
||||
$entity_type = $this->getDefinition($entity_type_id);
|
||||
$class = $entity_type->getClass();
|
||||
|
||||
$base_definitions = $class::baseFieldDefinitions($entity_type_id);
|
||||
foreach ($base_definitions as &$base_definition) {
|
||||
$base_definition->setTargetEntityTypeId($entity_type_id);
|
||||
}
|
||||
$this->entityFieldInfo[$entity_type_id] = array(
|
||||
'definitions' => $base_definitions,
|
||||
// Contains definitions of optional (per-bundle) fields.
|
||||
'optional' => array(),
|
||||
// An array keyed by bundle name containing the optional fields added
|
||||
// by the bundle.
|
||||
'bundle map' => array(),
|
||||
);
|
||||
$base_field_definitions = $class::baseFieldDefinitions($entity_type);
|
||||
|
||||
// Invoke hooks.
|
||||
$result = $this->moduleHandler->invokeAll($entity_type_id . '_field_info');
|
||||
$this->entityFieldInfo[$entity_type_id] = NestedArray::mergeDeep($this->entityFieldInfo[$entity_type_id], $result);
|
||||
$result = $this->moduleHandler->invokeAll('entity_field_info', array($entity_type_id));
|
||||
$this->entityFieldInfo[$entity_type_id] = NestedArray::mergeDeep($this->entityFieldInfo[$entity_type_id], $result);
|
||||
// Invoke hook.
|
||||
$result = $this->moduleHandler->invokeAll('entity_base_field_info', array($entity_type));
|
||||
$base_field_definitions = NestedArray::mergeDeep($base_field_definitions, $result);
|
||||
|
||||
// Automatically set the field name for non-configurable fields.
|
||||
foreach (array('definitions', 'optional') as $key) {
|
||||
foreach ($this->entityFieldInfo[$entity_type_id][$key] as $field_name => &$definition) {
|
||||
if ($definition instanceof FieldDefinition) {
|
||||
$definition->setName($field_name);
|
||||
}
|
||||
foreach ($base_field_definitions as $field_name => $base_field_definition) {
|
||||
if ($base_field_definition instanceof FieldDefinition) {
|
||||
$base_field_definition->setName($field_name);
|
||||
$base_field_definition->setTargetEntityTypeId($entity_type_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke alter hooks.
|
||||
$hooks = array('entity_field_info', $entity_type_id . '_field_info');
|
||||
$this->moduleHandler->alter($hooks, $this->entityFieldInfo[$entity_type_id], $entity_type_id);
|
||||
// Invoke alter hook.
|
||||
$this->moduleHandler->alter('entity_base_field_info', $base_field_definitions, $entity_type);
|
||||
|
||||
// Ensure all basic fields are not defined as translatable.
|
||||
$keys = array_intersect_key(array_filter($entity_type->getKeys()), array_flip(array('id', 'revision', 'uuid', 'bundle')));
|
||||
$untranslatable_fields = array_flip(array('langcode') + $keys);
|
||||
foreach (array('definitions', 'optional') as $key) {
|
||||
foreach ($this->entityFieldInfo[$entity_type_id][$key] as $field_name => &$definition) {
|
||||
foreach ($base_field_definitions as $field_name => $definition) {
|
||||
if (isset($untranslatable_fields[$field_name]) && $definition->isTranslatable()) {
|
||||
throw new \LogicException(String::format('The @field field cannot be translatable.', array('@field' => $definition->getLabel())));
|
||||
}
|
||||
}
|
||||
|
||||
return $base_field_definitions;
|
||||
}
|
||||
|
||||
$this->cache->set($cid, $this->entityFieldInfo[$entity_type_id], Cache::PERMANENT, array('entity_types' => TRUE, 'entity_field_info' => TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bundle) {
|
||||
return $this->entityFieldInfo[$entity_type_id]['definitions'];
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldDefinitions($entity_type_id, $bundle) {
|
||||
if (!isset($this->fieldDefinitions[$entity_type_id][$bundle])) {
|
||||
$base_field_definitions = $this->getBaseFieldDefinitions($entity_type_id);
|
||||
// Not prepared, try to load from cache.
|
||||
$cid = 'entity_bundle_field_definitions:' . $entity_type_id . ':' . $bundle . ':' . $this->languageManager->getCurrentLanguage()->id;
|
||||
if ($cache = $this->cache->get($cid)) {
|
||||
$bundle_field_definitions = $cache->data;
|
||||
}
|
||||
else {
|
||||
// Add in per-bundle fields.
|
||||
if (!isset($this->fieldDefinitions[$entity_type_id][$bundle])) {
|
||||
$this->fieldDefinitions[$entity_type_id][$bundle] = $this->entityFieldInfo[$entity_type_id]['definitions'];
|
||||
if (isset($this->entityFieldInfo[$entity_type_id]['bundle map'][$bundle])) {
|
||||
$this->fieldDefinitions[$entity_type_id][$bundle] += array_intersect_key($this->entityFieldInfo[$entity_type_id]['optional'], array_flip($this->entityFieldInfo[$entity_type_id]['bundle map'][$bundle]));
|
||||
// Rebuild the definitions and put it into the cache.
|
||||
$bundle_field_definitions = $this->buildBuildFieldDefinitions($entity_type_id, $bundle, $base_field_definitions);
|
||||
$this->cache->set($cid, $bundle_field_definitions, Cache::PERMANENT, array('entity_types' => TRUE, 'entity_field_info' => TRUE));
|
||||
}
|
||||
// Field definitions consist of the bundle specific overrides and the
|
||||
// base fields, merge them together. Use array_replace() to replace base
|
||||
// fields with by bundle overrides and keep them in order, append
|
||||
// additional by bundle fields.
|
||||
$this->fieldDefinitions[$entity_type_id][$bundle] = array_replace($base_field_definitions, $bundle_field_definitions);
|
||||
}
|
||||
return $this->fieldDefinitions[$entity_type_id][$bundle];
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds field definitions for a specific bundle within an entity type.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type ID. Only entity types that implement
|
||||
* \Drupal\Core\Entity\ContentEntityInterface are supported.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface[] $base_field_definitions
|
||||
* The list of base field definitions.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of bundle field definitions, keyed by field name. Does
|
||||
* not include base fields.
|
||||
*/
|
||||
protected function buildBuildFieldDefinitions($entity_type_id, $bundle, array $base_field_definitions) {
|
||||
$entity_type = $this->getDefinition($entity_type_id);
|
||||
$class = $entity_type->getClass();
|
||||
|
||||
// Allow the entity class to override the base fields.
|
||||
$bundle_field_definitions = $class::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions);
|
||||
|
||||
// Invoke 'per bundle' hook.
|
||||
$result = $this->moduleHandler->invokeAll('entity_bundle_field_info', array($entity_type, $bundle, $base_field_definitions));
|
||||
$bundle_field_definitions = NestedArray::mergeDeep($bundle_field_definitions, $result);
|
||||
|
||||
// Automatically set the field name for non-configurable fields.
|
||||
foreach ($bundle_field_definitions as $field_name => $field_definition) {
|
||||
if ($field_definition instanceof FieldDefinition) {
|
||||
$field_definition->setName($field_name);
|
||||
$field_definition->setTargetEntityTypeId($entity_type_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke 'per bundle' alter hook.
|
||||
$this->moduleHandler->alter('entity_bundle_field_info', $bundle_field_definitions, $entity_type, $bundle);
|
||||
|
||||
return $bundle_field_definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clearCachedFieldDefinitions() {
|
||||
unset($this->entityFieldInfo);
|
||||
unset($this->fieldDefinitions);
|
||||
$this->baseFieldDefinitions = array();
|
||||
$this->fieldDefinitions = array();
|
||||
Cache::deleteTags(array('entity_field_info' => TRUE));
|
||||
}
|
||||
|
||||
|
|
|
@ -23,23 +23,38 @@ interface EntityManagerInterface extends PluginManagerInterface {
|
|||
public function getEntityTypeLabels();
|
||||
|
||||
/**
|
||||
* Gets an array of content entity field definitions.
|
||||
* Gets the base field definitions for a content entity type.
|
||||
*
|
||||
* If a bundle is passed, fields specific to this bundle are included.
|
||||
* Only fields that are not specific to a given bundle or set of bundles are
|
||||
* returned. This excludes configurable fields, as they are always attached
|
||||
* to a specific bundle.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type to get field definitions for. Only entity types that
|
||||
* implement \Drupal\Core\Entity\ContentEntityInterface are supported.
|
||||
* @param string $bundle
|
||||
* (optional) The entity bundle for which to get field definitions. If NULL
|
||||
* is passed, no bundle-specific fields are included. Defaults to NULL.
|
||||
* The entity type ID. Only entity types that implement
|
||||
* \Drupal\Core\Entity\ContentEntityInterface are supported.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of entity field definitions, keyed by field name.
|
||||
* The array of base field definitions for the entity type, keyed by field
|
||||
* name.
|
||||
*
|
||||
* @see \Drupal\Core\TypedData\TypedDataManager::create()
|
||||
* @throws \LogicException
|
||||
* Thrown if one of the entity keys is flagged as translatable.
|
||||
*/
|
||||
public function getFieldDefinitions($entity_type_id, $bundle = NULL);
|
||||
public function getBaseFieldDefinitions($entity_type_id);
|
||||
|
||||
/**
|
||||
* Gets the field definitions for a specific bundle.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type ID. Only entity types that implement
|
||||
* \Drupal\Core\Entity\ContentEntityInterface are supported.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* The array of field definitions for the bundle, keyed by field name.
|
||||
*/
|
||||
public function getFieldDefinitions($entity_type_id, $bundle);
|
||||
|
||||
/**
|
||||
* Creates a new access controller instance.
|
||||
|
|
|
@ -268,7 +268,7 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
}
|
||||
|
||||
$data = $query->execute();
|
||||
$field_definitions = \Drupal::entityManager()->getFieldDefinitions($this->entityTypeId);
|
||||
$field_definitions = \Drupal::entityManager()->getBaseFieldDefinitions($this->entityTypeId);
|
||||
$translations = array();
|
||||
if ($this->revisionDataTable) {
|
||||
$data_column_names = array_flip(array_diff(drupal_schema_fields_sql($this->entityType->getRevisionDataTable()), drupal_schema_fields_sql($this->entityType->getBaseTable())));
|
||||
|
@ -1187,7 +1187,7 @@ class FieldableDatabaseStorageController extends FieldableEntityStorageControlle
|
|||
$entity_type_id = $field->entity_type;
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$entity_type = $entity_manager->getDefinition($entity_type_id);
|
||||
$definitions = $entity_manager->getFieldDefinitions($entity_type_id);
|
||||
$definitions = $entity_manager->getBaseFieldDefinitions($entity_type_id);
|
||||
|
||||
// Define the entity ID schema based on the field definitions.
|
||||
$id_definition = $definitions[$entity_type->getKey('id')];
|
||||
|
|
|
@ -60,8 +60,12 @@ class EntityDataDefinition extends ComplexDataDefinitionBase implements EntityDa
|
|||
// @todo: Add support for handling multiple bundles.
|
||||
// See https://drupal.org/node/2169813.
|
||||
$bundles = $this->getBundles();
|
||||
$bundle = is_array($bundles) && count($bundles) == 1 ? reset($bundles) : NULL;
|
||||
$this->propertyDefinitions = \Drupal::entityManager()->getFieldDefinitions($entity_type_id, $bundle);
|
||||
if (is_array($bundles) && count($bundles) == 1) {
|
||||
$this->propertyDefinitions = \Drupal::entityManager()->getFieldDefinitions($entity_type_id, reset($bundles));
|
||||
}
|
||||
else {
|
||||
$this->propertyDefinitions = \Drupal::entityManager()->getBaseFieldDefinitions($entity_type_id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No entity type given.
|
||||
|
|
|
@ -7,60 +7,16 @@
|
|||
|
||||
namespace Drupal\Core\Field;
|
||||
|
||||
use Drupal\field\FieldInstanceConfigInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\field\Field;
|
||||
|
||||
/**
|
||||
* Represents a configurable entity field item list.
|
||||
*/
|
||||
class ConfigFieldItemList extends FieldItemList implements ConfigFieldItemListInterface {
|
||||
|
||||
/**
|
||||
* The Field instance definition.
|
||||
*
|
||||
* @var \Drupal\field\FieldInstanceConfigInterface
|
||||
*/
|
||||
protected $instance;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($definition, $name = NULL, TypedDataInterface $parent = NULL) {
|
||||
parent::__construct($definition, $name, $parent);
|
||||
// Definition can be the field config or field instance.
|
||||
if ($definition instanceof FieldInstanceConfigInterface) {
|
||||
$this->instance = $definition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldDefinition() {
|
||||
// Configurable fields have the field_config entity injected as definition,
|
||||
// but we want to return the more specific field instance here.
|
||||
// @todo: Overhaul this once we have per-bundle field definitions injected,
|
||||
// see https://drupal.org/node/2114707.
|
||||
if (!isset($this->instance)) {
|
||||
$entity = $this->getEntity();
|
||||
$instances = Field::fieldInfo()->getBundleInstances($entity->getEntityTypeId(), $entity->bundle());
|
||||
if (isset($instances[$this->getName()])) {
|
||||
$this->instance = $instances[$this->getName()];
|
||||
}
|
||||
else {
|
||||
// For base fields, fall back to return the general definition.
|
||||
return parent::getFieldDefinition();
|
||||
}
|
||||
}
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConstraints() {
|
||||
$constraints = array();
|
||||
$constraints = parent::getConstraints();
|
||||
// Check that the number of values doesn't exceed the field cardinality. For
|
||||
// form submitted values, this can only happen with 'multiple value'
|
||||
// widgets.
|
||||
|
|
|
@ -437,4 +437,13 @@ class TypedDataManager extends DefaultPluginManager {
|
|||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clearCachedDefinitions() {
|
||||
parent::clearCachedDefinitions();
|
||||
$this->prototypes = array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\aggregator\Entity;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
|
@ -120,7 +121,7 @@ class Feed extends ContentEntityBase implements FeedInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['fid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Feed ID'))
|
||||
->setDescription(t('The ID of the aggregator feed.'))
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\aggregator\Entity;
|
|||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\aggregator\ItemInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
|
||||
/**
|
||||
|
@ -60,7 +61,7 @@ class Item extends ContentEntityBase implements ItemInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['iid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Aggregator item ID'))
|
||||
->setDescription(t('The ID of the feed item.'))
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\custom_block\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\custom_block\CustomBlockInterface;
|
||||
|
||||
|
@ -163,7 +164,7 @@ class CustomBlock extends ContentEntityBase implements CustomBlockInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['id'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Custom block ID'))
|
||||
->setDescription(t('The custom block ID.'))
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Component\Utility\Number;
|
|||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
@ -210,7 +211,7 @@ class Comment extends ContentEntityBase implements CommentInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['cid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Comment ID'))
|
||||
->setDescription(t('The comment ID.'))
|
||||
|
|
|
@ -69,6 +69,7 @@ class CommentValidationTest extends EntityUnitTestBase {
|
|||
'entity_id' => $node->id(),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
'comment_body' => $this->randomName(),
|
||||
));
|
||||
|
||||
$violations = $comment->validate();
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\contact\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\contact\MessageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
|
||||
/**
|
||||
|
@ -139,7 +140,7 @@ class Message extends ContentEntityBase implements MessageInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['category'] = FieldDefinition::create('entity_reference')
|
||||
->setLabel(t('Category ID'))
|
||||
->setDescription(t('The ID of the associated category.'))
|
||||
|
|
|
@ -9,6 +9,8 @@ use Drupal\content_translation\Plugin\Derivative\ContentTranslationLocalTasks;
|
|||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityFormControllerInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TypedData\TranslatableInterface;
|
||||
|
@ -143,27 +145,23 @@ function content_translation_entity_bundle_info_alter(&$bundles) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_info_alter().
|
||||
* Implements hook_entity_base_field_info_alter().
|
||||
*/
|
||||
function content_translation_entity_field_info_alter(&$info, $entity_type) {
|
||||
$translation_settings = \Drupal::config('content_translation.settings')->get($entity_type);
|
||||
function content_translation_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
|
||||
$translation_settings = \Drupal::config('content_translation.settings')->get($entity_type->id());
|
||||
|
||||
if ($translation_settings) {
|
||||
// Currently field translatability is defined per-field but we may want to
|
||||
// make it per-instance instead, so leaving the possibility open for further
|
||||
// easier refactoring.
|
||||
$fields = array();
|
||||
// make it per-instance instead. In that case, we will need to implement
|
||||
// hook_bundle_field_info_alter() instead.
|
||||
$field_settings = array();
|
||||
foreach ($translation_settings as $bundle => $settings) {
|
||||
$fields += !empty($settings['content_translation']['fields']) ? $settings['content_translation']['fields'] : array();
|
||||
$field_settings += !empty($settings['content_translation']['fields']) ? $settings['content_translation']['fields'] : array();
|
||||
}
|
||||
|
||||
$keys = array('definitions', 'optional');
|
||||
foreach ($fields as $name => $translatable) {
|
||||
foreach ($keys as $key) {
|
||||
if (isset($info[$key][$name])) {
|
||||
$info[$key][$name]->setTranslatable((bool) $translatable);
|
||||
break;
|
||||
}
|
||||
foreach ($field_settings as $name => $translatable) {
|
||||
if (isset($fields[$name]) && $fields[$name] instanceof FieldDefinition) {
|
||||
$fields[$name]->setTranslatable((bool) $translatable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace Drupal\entity;
|
|||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Entity\Display\EntityDisplayInterface;
|
||||
|
||||
/**
|
||||
|
@ -325,20 +324,14 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
|
|||
* Returns the definitions of the fields that are candidate for display.
|
||||
*/
|
||||
protected function getFieldDefinitions() {
|
||||
// Entity displays are sometimes created for non-content entities.
|
||||
// @todo Prevent this in https://drupal.org/node/2095195.
|
||||
if (!\Drupal::entityManager()->getDefinition($this->targetEntityType)->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (!isset($this->fieldDefinitions)) {
|
||||
// @todo Replace this with \Drupal::entityManager()->getFieldDefinition()
|
||||
// when it can hand the $instance objects (and then reconsider the
|
||||
// $this->fieldDefinitions static cache ?)
|
||||
// https://drupal.org/node/2114707
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$entity_type = $entity_manager->getDefinition($this->targetEntityType);
|
||||
$definitions = array();
|
||||
if ($entity_type->isSubclassOf('\Drupal\Core\Entity\ContentEntityInterface')) {
|
||||
$entity = _field_create_entity_from_ids((object) array('entity_type' => $this->targetEntityType, 'bundle' => $this->bundle, 'entity_id' => NULL));
|
||||
foreach ($entity as $field_name => $items) {
|
||||
$definitions[$field_name] = $items->getFieldDefinition();
|
||||
}
|
||||
}
|
||||
$definitions = \Drupal::entityManager()->getFieldDefinitions($this->targetEntityType, $this->bundle);
|
||||
|
||||
// The display only cares about fields that specify display options.
|
||||
// Discard base fields that are not rendered through formatters / widgets.
|
||||
|
|
|
@ -23,14 +23,14 @@ class EntityReferenceAutocompleteTest extends EntityUnitTestBase {
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $entityType = 'entity_test_label';
|
||||
protected $entityType = 'entity_test';
|
||||
|
||||
/**
|
||||
* The bundle used in this test.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $bundle = 'entity_test_label';
|
||||
protected $bundle = 'entity_test';
|
||||
|
||||
/**
|
||||
* The name of the field used in this test.
|
||||
|
|
|
@ -124,31 +124,18 @@ function field_invoke_method($method, $target_function, EntityInterface $entity,
|
|||
* @param $options
|
||||
* An associative array of options, as provided to field_invoke_method(). Only
|
||||
* the following keys are considered:
|
||||
* - deleted
|
||||
* - field_name
|
||||
* - field_id
|
||||
* See field_invoke_method() for details.
|
||||
*
|
||||
* @return
|
||||
* The array of selected field definitions.
|
||||
*/
|
||||
function _field_invoke_get_field_definitions($entity_type, $bundle, $options) {
|
||||
// @todo Replace with \Drupal::entityManager()->getFieldDefinition() after
|
||||
// [#2047229] lands.
|
||||
$entity = _field_create_entity_from_ids((object) array('entity_type' => $entity_type, 'bundle' => $bundle, 'entity_id' => NULL));
|
||||
$field_definitions = array();
|
||||
$definitions = \Drupal::entityManager()->getFieldDefinitions($entity_type, $bundle);
|
||||
if (isset($options['field_name'])) {
|
||||
if ($entity->hasField($options['field_name'])) {
|
||||
$field_definitions[] = $entity->get($options['field_name'])->getFieldDefinition();
|
||||
$definitions = array_intersect_key($definitions, array($options['field_name'] => TRUE));
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($entity as $items) {
|
||||
$field_definitions[] = $items->getFieldDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
return $field_definitions;
|
||||
return $definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Template\Attribute;
|
||||
use Drupal\entity\Entity\EntityViewDisplay;
|
||||
use Drupal\field\Field;
|
||||
|
||||
/*
|
||||
* Load all public Field API functions. Drupal currently has no
|
||||
|
@ -189,29 +191,14 @@ function field_system_info_alter(&$info, $file, $type) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_info() to define all configured fields.
|
||||
* Implements hook_entity_bundle_field_info().
|
||||
*/
|
||||
function field_entity_field_info($entity_type) {
|
||||
$property_info = array();
|
||||
|
||||
foreach (field_info_instances($entity_type) as $bundle_name => $instances) {
|
||||
$optional = $bundle_name != $entity_type;
|
||||
// @todo: Improve hook_entity_field_info() to allow per-bundle field
|
||||
// definitions, such that we can pass on field instances as field
|
||||
// definitions here. See https://drupal.org/node/2114707.
|
||||
|
||||
foreach ($instances as $field_name => $instance) {
|
||||
if ($optional) {
|
||||
$property_info['optional'][$field_name] = $instance->getField();
|
||||
$property_info['bundle map'][$bundle_name][] = $field_name;
|
||||
function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
||||
if ($entity_type->isFieldable()) {
|
||||
// Configurable fields, which are always attached to a specific bundle, are
|
||||
// added 'by bundle'.
|
||||
return Field::fieldInfo()->getBundleInstances($entity_type->id(), $bundle);
|
||||
}
|
||||
else {
|
||||
$property_info['definitions'][$field_name] = $instance->getField();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $property_info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -162,7 +162,7 @@ class FieldAttachOtherTest extends FieldUnitTestBase {
|
|||
// Create two entities.
|
||||
$entity1 = entity_create('entity_test', array('id' => 1, 'type' => 'entity_test'));
|
||||
$entity1->{$this->field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
$entity2 = entity_create('entity_test', array('id' => 2, 'type' => 'test_bundle'));
|
||||
$entity2 = entity_create('entity_test', array('id' => 2, 'type' => 'entity_test'));
|
||||
$entity2->{$this->field_name}->setValue($this->_generateTestFieldValues(1));
|
||||
|
||||
// Run buildMultiple(), and check that the entities come out as expected.
|
||||
|
|
|
@ -104,17 +104,8 @@ abstract class DisplayOverviewBase extends OverviewBase {
|
|||
* The array of field definitions
|
||||
*/
|
||||
protected function getFieldDefinitions() {
|
||||
// @todo Replace this entire implementation with
|
||||
// \Drupal::entityManager()->getFieldDefinition() when it can hand the
|
||||
// $instance objects - https://drupal.org/node/2114707
|
||||
$entity = _field_create_entity_from_ids((object) array('entity_type' => $this->entity_type, 'bundle' => $this->bundle, 'entity_id' => NULL));
|
||||
$field_definitions = array();
|
||||
foreach ($entity as $field_name => $items) {
|
||||
$field_definitions[$field_name] = $items->getFieldDefinition();
|
||||
}
|
||||
|
||||
$context = $this->displayContext;
|
||||
return array_filter($field_definitions, function(FieldDefinitionInterface $field_definition) use ($context) {
|
||||
return array_filter($this->entityManager->getFieldDefinitions($this->entity_type, $this->bundle), function(FieldDefinitionInterface $field_definition) use ($context) {
|
||||
return $field_definition->isDisplayConfigurable($context);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\file\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\file\FileInterface;
|
||||
|
@ -240,7 +241,7 @@ class File extends ContentEntityBase implements FileInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['fid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('File ID'))
|
||||
->setDescription(t('The file ID.'))
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\node\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
@ -351,7 +352,7 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['nid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Node ID'))
|
||||
->setDescription(t('The node ID.'))
|
||||
|
@ -378,11 +379,8 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
->setDescription(t('The node language code.'));
|
||||
|
||||
$fields['title'] = FieldDefinition::create('text')
|
||||
// @todo Account for $node_type->title_label when per-bundle overrides are
|
||||
// possible - https://drupal.org/node/2114707.
|
||||
->setLabel(t('Title'))
|
||||
->setDescription(t('The title of this node, always treated as non-markup plain text.'))
|
||||
->setClass('\Drupal\node\NodeTitleItemList')
|
||||
->setRequired(TRUE)
|
||||
->setTranslatable(TRUE)
|
||||
->setSettings(array(
|
||||
|
@ -451,4 +449,17 @@ class Node extends ContentEntityBase implements NodeInterface {
|
|||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
||||
$node_type = node_type_load($bundle);
|
||||
$fields = array();
|
||||
if (isset($node_type->title_label)) {
|
||||
$fields['title'] = clone $base_field_definitions['title'];
|
||||
$fields['title']->setLabel($node_type->title_label);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\node\NodeTitleItemList.
|
||||
*/
|
||||
|
||||
namespace Drupal\node;
|
||||
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
|
||||
/**
|
||||
* @todo This class is a temporary hack for allowing the label of the node title
|
||||
* field to vary by node type. Remove it when https://drupal.org/node/2114707
|
||||
* is solved.
|
||||
*/
|
||||
class NodeTitleItemList extends FieldItemList {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* The typehint for $definition is a class rather than an interface, because
|
||||
* there is no interface for setLabel().
|
||||
*/
|
||||
public function __construct(FieldDefinition $definition, $name, NodeInterface $node) {
|
||||
$node_type = node_type_load($node->getType());
|
||||
if (isset($node_type->title_label)) {
|
||||
$definition->setLabel($node_type->title_label);
|
||||
}
|
||||
parent::__construct($definition, $name, $node);
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
* a special 'node test view' permission.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
|
@ -78,15 +79,15 @@ function node_access_test_permission() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_info().
|
||||
* Implements hook_entity_base_field_info().
|
||||
*/
|
||||
function node_access_test_entity_field_info($entity_type) {
|
||||
if ($entity_type === 'node') {
|
||||
$info['definitions']['private'] = FieldDefinition::create('boolean')
|
||||
function node_access_test_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() === 'node') {
|
||||
$fields['private'] = FieldDefinition::create('boolean')
|
||||
->setLabel(t('Private'))
|
||||
->setComputed(TRUE);
|
||||
|
||||
return $info;
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Enables users to rename URLs.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
|
@ -197,14 +198,14 @@ function path_form_taxonomy_term_form_alter(&$form, $form_state) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_info().
|
||||
* Implements hook_entity_base_field_info().
|
||||
*/
|
||||
function path_entity_field_info($entity_type) {
|
||||
if ($entity_type === 'taxonomy_term' || $entity_type === 'node') {
|
||||
$info['definitions']['path'] = FieldDefinition::create('path')
|
||||
function path_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() === 'taxonomy_term' || $entity_type->id() === 'node') {
|
||||
$fields['path'] = FieldDefinition::create('path')
|
||||
->setLabel(t('The path alias'))
|
||||
->setComputed(TRUE);
|
||||
|
||||
return $info;
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\shortcut\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Routing\UrlMatcher;
|
||||
use Drupal\Core\Url;
|
||||
|
@ -133,7 +134,7 @@ class Shortcut extends ContentEntityBase implements ShortcutInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['id'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('ID'))
|
||||
->setDescription(t('The ID of the shortcut.'))
|
||||
|
|
|
@ -659,62 +659,101 @@ function hook_entity_form_display_alter(\Drupal\Core\Entity\Display\EntityFormDi
|
|||
}
|
||||
|
||||
/**
|
||||
* Define custom entity fields.
|
||||
* Provides custom base field definitions for a content entity type.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type for which to define entity fields.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
*
|
||||
* @return array
|
||||
* An array of entity field information having the following optional entries:
|
||||
* - definitions: An array of field definitions to add to all entities of this
|
||||
* type, keyed by field name.
|
||||
* - optional: An array of field definitions for optional entity fields, keyed
|
||||
* by field name. Optional fields are fields that only exist for certain
|
||||
* bundles of the entity type.
|
||||
* - bundle map: An array keyed by bundle name, containing the names of
|
||||
* optional fields that entities of this bundle have.
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of field definitions, keyed by field name.
|
||||
*
|
||||
* @see hook_entity_field_info_alter()
|
||||
* @see hook_entity_base_field_info_alter()
|
||||
* @see hook_entity_bundle_field_info()
|
||||
* @see hook_entity_bundle_field_info_alter()
|
||||
* @see \Drupal\Core\Field\FieldDefinitionInterface
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getFieldDefinitions()
|
||||
* @see \Drupal\Core\TypedData\TypedDataManager::create()
|
||||
*/
|
||||
function hook_entity_field_info($entity_type_id) {
|
||||
if (mymodule_uses_entity_type($entity_type_id)) {
|
||||
$info = array();
|
||||
$info['definitions']['mymodule_text'] = FieldDefinition::create('string')
|
||||
function hook_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() == 'node') {
|
||||
$fields = array();
|
||||
$fields['mymodule_text'] = FieldDefinition::create('string')
|
||||
->setLabel(t('The text'))
|
||||
->setDescription(t('A text property added by mymodule.'))
|
||||
->setComputed(TRUE)
|
||||
->setClass('\Drupal\mymodule\EntityComputedText');
|
||||
|
||||
if ($entity_type_id == 'node') {
|
||||
// Add a property only to entities of the 'article' bundle.
|
||||
$info['optional']['mymodule_text_more'] = FieldDefinition::create('string')
|
||||
->setLabel(t('More text'))
|
||||
->setComputed(TRUE)
|
||||
->setClass('\Drupal\mymodule\EntityComputedMoreText');
|
||||
|
||||
$info['bundle map']['article'][0] = 'mymodule_text_more';
|
||||
}
|
||||
return $info;
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter defined entity fields.
|
||||
* Alters base field definitions for a content entity type.
|
||||
*
|
||||
* @param array $info
|
||||
* The entity field info array as returned by hook_entity_field_info().
|
||||
* @param string $entity_type_id
|
||||
* The entity type for which entity fields are defined.
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface[] $fields
|
||||
* The array of base field definitions for the entity type.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
*
|
||||
* @see hook_entity_field_info()
|
||||
* @see hook_entity_base_field_info()
|
||||
* @see hook_entity_bundle_field_info()
|
||||
* @see hook_entity_bundle_field_info_alter()
|
||||
*/
|
||||
function hook_entity_field_info_alter(&$info, $entity_type_id) {
|
||||
if (!empty($info['definitions']['mymodule_text'])) {
|
||||
function hook_entity_base_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
|
||||
// Alter the mymodule_text field to use a custom class.
|
||||
$info['definitions']['mymodule_text']->setClass('\Drupal\anothermodule\EntityComputedText');
|
||||
if ($entity_type->id() == 'node' && !empty($fields['mymodule_text'])) {
|
||||
$fields['mymodule_text']->setClass('\Drupal\anothermodule\EntityComputedText');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides field definitions for a specific bundle within an entity type.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface[] $base_field_definitions
|
||||
* The list of base field definitions for the entity type.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldDefinitionInterface[]
|
||||
* An array of bundle field definitions, keyed by field name.
|
||||
*
|
||||
* @see hook_entity_base_field_info()
|
||||
* @see hook_entity_base_field_info_alter()
|
||||
* @see hook_entity_bundle_field_info_alter()
|
||||
* @see \Drupal\Core\Field\FieldDefinitionInterface
|
||||
* @see \Drupal\Core\Entity\EntityManagerInterface::getFieldDefinitions()
|
||||
*/
|
||||
function hook_entity_bundle_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
||||
// Add a property only to nodes of the 'article' bundle.
|
||||
if ($entity_type->id() == 'node' && $bundle == 'article') {
|
||||
$fields = array();
|
||||
$fields['mymodule_text_more'] = FieldDefinition::create('string')
|
||||
->setLabel(t('More text'))
|
||||
->setComputed(TRUE)
|
||||
->setClass('\Drupal\mymodule\EntityComputedMoreText');
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alters bundle field definitions.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldDefinitionInterface[] $fields
|
||||
* The array of bundle field definitions.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
*
|
||||
* @see hook_entity_base_field_info()
|
||||
* @see hook_entity_base_field_info_alter()
|
||||
* @see hook_entity_bundle_field_info()
|
||||
*/
|
||||
function hook_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
|
||||
if ($entity_type->id() == 'node' && $bundle == 'article' && !empty($fields['mymodule_text'])) {
|
||||
// Alter the mymodule_text field to use a custom class.
|
||||
$fields['mymodule_text']->setClass('\Drupal\anothermodule\EntityComputedText');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -356,8 +356,9 @@ class EntityFieldTest extends EntityUnitTestBase {
|
|||
* The entity type to run the tests with.
|
||||
*/
|
||||
protected function checkIntrospection($entity_type) {
|
||||
// Test getting metadata upfront.
|
||||
$definitions = \Drupal::entityManager()->getFieldDefinitions($entity_type);
|
||||
// Test getting metadata upfront. The entity types used for this test have
|
||||
// a default bundle that is the same as the entity type.
|
||||
$definitions = \Drupal::entityManager()->getFieldDefinitions($entity_type, $entity_type);
|
||||
$this->assertEqual($definitions['name']->getType(), 'string', $entity_type .': Name field found.');
|
||||
$this->assertEqual($definitions['user_id']->getType(), 'entity_reference', $entity_type .': User field found.');
|
||||
$this->assertEqual($definitions['field_test_text']->getType(), 'text', $entity_type .': Test-text-field field found.');
|
||||
|
|
|
@ -513,16 +513,16 @@ class EntityTranslationTest extends EntityLanguageTestBase {
|
|||
$entity_type = 'entity_test_mulrev';
|
||||
$this->state->set('entity_test.field_definitions.translatable', array('name' => FALSE));
|
||||
$this->entityManager->clearCachedFieldDefinitions();
|
||||
$definitions = $this->entityManager->getFieldDefinitions($entity_type);
|
||||
$definitions = $this->entityManager->getBaseFieldDefinitions($entity_type);
|
||||
$this->assertFalse($definitions['name']->isTranslatable(), 'Field translatability can be disabled programmatically.');
|
||||
|
||||
$this->state->set('entity_test.field_definitions.translatable', array('name' => TRUE));
|
||||
$this->entityManager->clearCachedFieldDefinitions();
|
||||
$definitions = $this->entityManager->getFieldDefinitions($entity_type);
|
||||
$definitions = $this->entityManager->getBaseFieldDefinitions($entity_type);
|
||||
$this->assertTrue($definitions['name']->isTranslatable(), 'Field translatability can be enabled programmatically.');
|
||||
|
||||
// Check that field translatability is disabled by default.
|
||||
$base_field_definitions = EntityTestMulRev::baseFieldDefinitions($entity_type);
|
||||
$base_field_definitions = EntityTestMulRev::baseFieldDefinitions($this->entityManager->getDefinition($entity_type));
|
||||
$this->assertTrue(!isset($base_field_definitions['id']->translatable), 'Translatability for the <em>id</em> field is not defined.');
|
||||
$this->assertFalse($definitions['id']->isTranslatable(), 'Field translatability is disabled by default.');
|
||||
|
||||
|
@ -533,7 +533,7 @@ class EntityTranslationTest extends EntityLanguageTestBase {
|
|||
$message = format_string('Field %field cannot be translatable.', array('%field' => $name));
|
||||
|
||||
try {
|
||||
$definitions = $this->entityManager->getFieldDefinitions($entity_type);
|
||||
$this->entityManager->getBaseFieldDefinitions($entity_type);
|
||||
$this->fail($message);
|
||||
}
|
||||
catch (\LogicException $e) {
|
||||
|
|
|
@ -100,7 +100,7 @@ class EntityTypedDataDefinitionTest extends DrupalUnitTestBase {
|
|||
$field_definitions = $entity_definition->getPropertyDefinitions();
|
||||
// Comparison should ignore the internal static cache, so compare the
|
||||
// serialized objects instead.
|
||||
$this->assertEqual(serialize($field_definitions), serialize(\Drupal::entityManager()->getFieldDefinitions('node')));
|
||||
$this->assertEqual(serialize($field_definitions), serialize(\Drupal::entityManager()->getBaseFieldDefinitions('node')));
|
||||
$this->assertEqual($entity_definition->getPropertyDefinition('title')->getItemDefinition()->getDataType(), 'field_item:text');
|
||||
$this->assertNull($entity_definition->getMainPropertyName());
|
||||
$this->assertNull($entity_definition->getPropertyDefinition('invalid'));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
@ -73,12 +74,12 @@ function entity_test_entity_type_alter(array &$entity_types) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_field_info_alter().
|
||||
* Implements hook_entity_base_field_info_alter().
|
||||
*/
|
||||
function entity_test_entity_field_info_alter(&$info, $entity_type) {
|
||||
if ($entity_type == 'entity_test_mulrev' && ($names = \Drupal::state()->get('entity_test.field_definitions.translatable'))) {
|
||||
function entity_test_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() == 'entity_test_mulrev' && ($names = \Drupal::state()->get('entity_test.field_definitions.translatable'))) {
|
||||
foreach ($names as $name => $value) {
|
||||
$info['definitions'][$name]->setTranslatable($value);
|
||||
$fields[$name]->setTranslatable($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
@ -108,7 +109,7 @@ class EntityTest extends ContentEntityBase implements EntityOwnerInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['id'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('ID'))
|
||||
->setDescription(t('The ID of the test entity.'))
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,7 @@ class EntityTestBaseFieldDisplay extends EntityTest {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['test_no_display'] = FieldDefinition::create('text')
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
|
@ -46,7 +47,7 @@ class EntityTestMul extends EntityTest {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['default_langcode'] = FieldDefinition::create('boolean')
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\entity_test\Entity\EntityTestRev;
|
||||
|
||||
|
@ -46,7 +47,7 @@ class EntityTestMulRev extends EntityTestRev {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['revision_id'] = FieldDefinition::create('integer')
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
|
||||
|
@ -30,7 +31,8 @@ use Drupal\entity_test\Entity\EntityTest;
|
|||
* "id" = "id",
|
||||
* "uuid" = "uuid",
|
||||
* "revision" = "revision_id",
|
||||
* "bundle" = "type"
|
||||
* "bundle" = "type",
|
||||
* "label" = "name",
|
||||
* },
|
||||
* links = {
|
||||
* "canonical" = "entity_test.edit_entity_test_rev",
|
||||
|
@ -65,7 +67,7 @@ class EntityTestRev extends EntityTest {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['revision_id'] = FieldDefinition::create('integer')
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\taxonomy\Entity;
|
|||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
@ -197,7 +198,7 @@ class Term extends ContentEntityBase implements TermInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['tid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('Term ID'))
|
||||
->setDescription(t('The term ID.'))
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\user\Entity;
|
|||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Entity\EntityMalformedException;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\FieldDefinition;
|
||||
use Drupal\user\UserInterface;
|
||||
|
||||
|
@ -423,7 +424,7 @@ class User extends ContentEntityBase implements UserInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions($entity_type) {
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields['uid'] = FieldDefinition::create('integer')
|
||||
->setLabel(t('User ID'))
|
||||
->setDescription(t('The user ID.'))
|
||||
|
|
|
@ -102,7 +102,7 @@ class Entity extends ArgumentValidatorPluginBase {
|
|||
}
|
||||
$bundles_title = $entity_type->getBundleLabel() ?: $this->t('Bundles');
|
||||
if ($entity_type->isSubclassOf('Drupal\Core\Entity\ContentEntityInterface')) {
|
||||
$fields = $this->entityManager->getFieldDefinitions($entity_type_id);
|
||||
$fields = $this->entityManager->getBaseFieldDefinitions($entity_type_id);
|
||||
}
|
||||
$bundle_name = (empty($fields) || empty($fields[$bundle_type]['label'])) ? t('bundles') : $fields[$bundle_type]['label'];
|
||||
$form['bundles'] = array(
|
||||
|
|
|
@ -451,6 +451,18 @@ class EntityManagerTest extends UnitTestCase {
|
|||
$this->assertNull($this->entityManager->getAdminRouteInfo('apple', 'delicious'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getBaseFieldDefinitions() method.
|
||||
*
|
||||
* @covers ::getBaseFieldDefinitions()
|
||||
*/
|
||||
public function testGetBaseFieldDefinitions() {
|
||||
$field_definition = $this->setUpEntityWithFieldDefinition();
|
||||
|
||||
$expected = array('id' => $field_definition);
|
||||
$this->assertSame($expected, $this->entityManager->getBaseFieldDefinitions('test_entity_type'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getFieldDefinitions() method.
|
||||
*
|
||||
|
@ -460,84 +472,84 @@ class EntityManagerTest extends UnitTestCase {
|
|||
$field_definition = $this->setUpEntityWithFieldDefinition();
|
||||
|
||||
$expected = array('id' => $field_definition);
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type'));
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type', 'test_entity_bundle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getBaseFieldDefinitions() method with caching.
|
||||
*
|
||||
* @covers ::getBaseFieldDefinitions()
|
||||
*/
|
||||
public function testGetBaseFieldDefinitionsWithCaching() {
|
||||
$field_definition = $this->setUpEntityWithFieldDefinition();
|
||||
|
||||
$expected = array('id' => $field_definition);
|
||||
|
||||
$this->cache->expects($this->at(0))
|
||||
->method('get')
|
||||
->with('entity_base_field_definitions:test_entity_type:en', FALSE)
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->cache->expects($this->once())
|
||||
->method('set');
|
||||
$this->cache->expects($this->at(2))
|
||||
->method('get')
|
||||
->with('entity_base_field_definitions:test_entity_type:en', FALSE)
|
||||
->will($this->returnValue((object) array('data' => $expected)));
|
||||
|
||||
$this->assertSame($expected, $this->entityManager->getBaseFieldDefinitions('test_entity_type'));
|
||||
$this->entityManager->testClearEntityFieldInfo();
|
||||
$this->assertSame($expected, $this->entityManager->getBaseFieldDefinitions('test_entity_type'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the getFieldDefinitions() method with caching.
|
||||
*
|
||||
* @covers ::getFieldDefinitions()
|
||||
*/
|
||||
public function testGetFieldDefinitionsWithCaching() {
|
||||
$field_definition = $this->setUpEntityWithFieldDefinition();
|
||||
$field_definition = $this->setUpEntityWithFieldDefinition(FALSE, 'id', 0);
|
||||
|
||||
$expected = array('id' => $field_definition);
|
||||
|
||||
// @todo Investigate why this is 0 and 2, not 0/1 or 1/2.
|
||||
$this->cache->expects($this->at(0))
|
||||
->method('get')
|
||||
->with('entity_field_definitions:test_entity_type:en', FALSE)
|
||||
->with('entity_base_field_definitions:test_entity_type:en', FALSE)
|
||||
->will($this->returnValue((object) array('data' => $expected)));
|
||||
$this->cache->expects($this->at(1))
|
||||
->method('get')
|
||||
->with('entity_bundle_field_definitions:test_entity_type:test_bundle:en', FALSE)
|
||||
->will($this->returnValue(FALSE));
|
||||
$this->cache->expects($this->at(2))
|
||||
->method('get')
|
||||
->with('entity_field_definitions:test_entity_type:en', FALSE)
|
||||
->will($this->returnValue((object) array('data' => array('definitions' => $expected))));
|
||||
|
||||
$this->cache->expects($this->once())
|
||||
->method('set');
|
||||
$this->cache->expects($this->at(3))
|
||||
->method('get')
|
||||
->with('entity_base_field_definitions:test_entity_type:en', FALSE)
|
||||
->will($this->returnValue((object) array('data' => $expected)));
|
||||
$this->cache->expects($this->at(4))
|
||||
->method('get')
|
||||
->with('entity_bundle_field_definitions:test_entity_type:test_bundle:en', FALSE)
|
||||
->will($this->returnValue((object) array('data' => $expected)));
|
||||
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type'));
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type', 'test_bundle'));
|
||||
$this->entityManager->testClearEntityFieldInfo();
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type'));
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type', 'test_bundle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getFieldDefinitions() method with bundle map.
|
||||
* Tests the getBaseFieldDefinitions() method with an invalid definition.
|
||||
*
|
||||
* @covers ::getFieldDefinitions()
|
||||
*/
|
||||
public function testGetFieldDefinitionsWithBundleMap() {
|
||||
$field_definition = $this->setUpEntityWithFieldDefinition(TRUE);
|
||||
|
||||
$this->moduleHandler->expects($this->at(0))
|
||||
->method('invokeAll')
|
||||
->will($this->returnValue(array()));
|
||||
$this->moduleHandler->expects($this->at(1))
|
||||
->method('invokeAll')
|
||||
->will($this->returnValue(array(
|
||||
'bundle map' => array(
|
||||
'test_entity_bundle' => array(
|
||||
'custom_field',
|
||||
),
|
||||
),
|
||||
'optional' => array(
|
||||
'custom_field' => $field_definition,
|
||||
),
|
||||
)));
|
||||
|
||||
$expected = array('id' => $field_definition);
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type'));
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type', 'test_entity_type'));
|
||||
|
||||
$expected['custom_field'] = $field_definition;
|
||||
$this->assertSame($expected, $this->entityManager->getFieldDefinitions('test_entity_type', 'test_entity_bundle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getFieldDefinitions() method with an invalid definition.
|
||||
*
|
||||
* @covers ::getFieldDefinitions()
|
||||
* @covers ::getBaseFieldDefinitions()
|
||||
*
|
||||
* @expectedException \LogicException
|
||||
*/
|
||||
public function testGetFieldDefinitionsInvalidDefinition() {
|
||||
public function testGetBaseFieldDefinitionsInvalidDefinition() {
|
||||
$langcode_definition = $this->setUpEntityWithFieldDefinition(FALSE, 'langcode');
|
||||
$langcode_definition->expects($this->once())
|
||||
->method('isTranslatable')
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->entityManager->getFieldDefinitions('test_entity_type');
|
||||
$this->entityManager->getBaseFieldDefinitions('test_entity_type');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -552,30 +564,33 @@ class EntityManagerTest extends UnitTestCase {
|
|||
* @return \Drupal\Core\Field\FieldDefinition|\PHPUnit_Framework_MockObject_MockObject
|
||||
* A field definition object.
|
||||
*/
|
||||
protected function setUpEntityWithFieldDefinition($custom_invoke_all = FALSE, $field_definition_id = 'id') {
|
||||
protected function setUpEntityWithFieldDefinition($custom_invoke_all = FALSE, $field_definition_id = 'id', $base_field_definition_calls = 1) {
|
||||
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
|
||||
$entity = $this->getMock('Drupal\Tests\Core\Entity\TestContentEntityInterface');
|
||||
$entity_class = get_class($entity);
|
||||
|
||||
$entity_type->expects($this->exactly(2))
|
||||
$entity_type->expects($this->any())
|
||||
->method('getClass')
|
||||
->will($this->returnValue($entity_class));
|
||||
$entity_type->expects($this->once())
|
||||
$entity_type->expects($this->any())
|
||||
->method('getKeys')
|
||||
->will($this->returnValue(array()));
|
||||
$field_definition = $this->getMockBuilder('Drupal\Core\Field\FieldDefinition')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$entity_class::staticExpects($this->once())
|
||||
$entity_class::staticExpects($this->exactly($base_field_definition_calls))
|
||||
->method('baseFieldDefinitions')
|
||||
->will($this->returnValue(array(
|
||||
$field_definition_id => $field_definition,
|
||||
)));
|
||||
$entity_class::staticExpects($this->any())
|
||||
->method('bundleFieldDefinitions')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$this->moduleHandler->expects($this->once())
|
||||
$this->moduleHandler->expects($this->any())
|
||||
->method('alter');
|
||||
if (!$custom_invoke_all) {
|
||||
$this->moduleHandler->expects($this->exactly(2))
|
||||
$this->moduleHandler->expects($this->any())
|
||||
->method('invokeAll')
|
||||
->will($this->returnValue(array()));
|
||||
}
|
||||
|
@ -804,7 +819,8 @@ class TestEntityManager extends EntityManager {
|
|||
* Allows the $entityFieldInfo property to be cleared.
|
||||
*/
|
||||
public function testClearEntityFieldInfo() {
|
||||
$this->entityFieldInfo = NULL;
|
||||
$this->baseFieldDefinitions = array();
|
||||
$this->fieldDefinitions = array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ class FieldableDatabaseStorageControllerTest extends UnitTestCase {
|
|||
->with('test_entity')
|
||||
->will($this->returnValue($definition));
|
||||
$entity_manager->expects($this->any())
|
||||
->method('getFieldDefinitions')
|
||||
->method('getBaseFieldDefinitions')
|
||||
->with('test_entity')
|
||||
->will($this->returnValue($fields));
|
||||
|
||||
|
|
Loading…
Reference in New Issue