Provides backwards compatible (BC) access to entity fields.
Allows using entities converted to the new Entity Field API with the previous way of accessing fields or properties. For example, via the backwards compatible (BC) decorator you can do:
$node->title = $value;
$node->body[LANGUAGE_NONE][0]['value'] = $value;
Without the BC decorator the same assignment would have to look like this:
$node->title->value = $value;
$node->body->value = $value;
Without the BC decorator the language always default to the entity language, whereas a specific translation can be access via the getTranslation() method.
The BC decorator should be only used during conversion to the new entity field API, such that existing code can be converted iteratively. Any new code should directly use the new entity field API and avoid using the EntityBCDecorator, if possible.
@todo: Remove once everything is converted to use the new entity field API.
Expanded class hierarchy of EntityBCDecorator
class EntityBCDecorator implements IteratorAggregate, EntityInterface {
/**
* The EntityInterface object being decorated.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
protected $decorated;
/**
* Local cache for field definitions.
*
* @var array
*/
protected $definitions;
/**
* Constructs a Drupal\Core\Entity\EntityCompatibilityDecorator object.
*
* @param \Drupal\Core\Entity\EntityInterface $decorated
* The decorated entity.
* @param array &$definitions
* An array of field definitions.
*/
function __construct(EntityNG $decorated, array &$definitions) {
$this->decorated = $decorated;
$this->definitions =& $definitions;
}
/**
* Overrides Entity::getNGEntity().
*/
public function getNGEntity() {
return $this->decorated;
}
/**
* Overrides Entity::getBCEntity().
*/
public function getBCEntity() {
return $this;
}
/**
* Implements the magic method for getting object properties.
*
* Directly accesses the plain field values, as done in Drupal 7.
*/
public function &__get($name) {
// Directly return the original property.
if ($name == 'original') {
return $this->decorated->values[$name];
}
// We access the protected 'values' and 'fields' properties of the decorated
// entity via the magic getter - which returns them by reference for us. We
// do so, as providing references to these arrays would make $entity->values
// and $entity->fields reference themselves, which is problematic during
// __clone() (this is something we cannot work-a-round easily as an unset()
// on the variable is problematic in conjunction with the magic
// getter/setter).
if (!empty($this->decorated->fields[$name])) {
// Any field value set via the new Entity Field API will be stored inside
// the field objects managed by the entity, thus we need to ensure
// $this->decorated->values reflects the latest values first.
foreach ($this->decorated->fields[$name] as $langcode => $field) {
// Only set if it's not empty, otherwise there can be ghost values.
if (!$field
->isEmpty()) {
$this->decorated->values[$name][$langcode] = $field
->getValue();
}
}
// The returned values might be changed by reference, so we need to remove
// the field object to avoid the field object and the value getting out of
// sync. That way, the next field object instantiated by EntityNG will
// receive the possibly updated value.
unset($this->decorated->fields[$name]);
}
// When accessing values for entity properties that have been converted to
// an entity field, provide direct access to the plain value. This makes it
// possible to use the BC-decorator with properties; e.g., $node->title.
if (isset($this->definitions[$name]) && empty($this->definitions[$name]['configurable'])) {
if (!isset($this->decorated->values[$name][Language::LANGCODE_DEFAULT])) {
$this->decorated->values[$name][Language::LANGCODE_DEFAULT][0]['value'] = NULL;
}
if (is_array($this->decorated->values[$name][Language::LANGCODE_DEFAULT])) {
// This will work with all defined properties that have a single value.
// We need to ensure the key doesn't matter. Mostly it's 'value' but
// e.g. EntityReferenceItem uses target_id.
if (isset($this->decorated->values[$name][Language::LANGCODE_DEFAULT][0]) && count($this->decorated->values[$name][Language::LANGCODE_DEFAULT][0]) == 1) {
return $this->decorated->values[$name][Language::LANGCODE_DEFAULT][0][key($this->decorated->values[$name][Language::LANGCODE_DEFAULT][0])];
}
}
return $this->decorated->values[$name][Language::LANGCODE_DEFAULT];
}
else {
// Allow accessing field values in an entity default language other than
// Language::LANGCODE_DEFAULT by mapping the values to
// Language::LANGCODE_DEFAULT. This is necessary as EntityNG always keys
// default language values with Language::LANGCODE_DEFAULT while field API
// expects them to be keyed by langcode.
$langcode = $this->decorated
->language()->langcode;
if ($langcode != Language::LANGCODE_DEFAULT && isset($this->decorated->values[$name]) && is_array($this->decorated->values[$name])) {
if (isset($this->decorated->values[$name][Language::LANGCODE_DEFAULT]) && !isset($this->decorated->values[$name][$langcode])) {
$this->decorated->values[$name][$langcode] =& $this->decorated->values[$name][Language::LANGCODE_DEFAULT];
}
}
if (!isset($this->decorated->values[$name])) {
$this->decorated->values[$name] = NULL;
}
return $this->decorated->values[$name];
}
}
/**
* Implements the magic method for setting object properties.
*
* Directly writes to the plain field values, as done by Drupal 7.
*/
public function __set($name, $value) {
$defined = isset($this->definitions[$name]);
// When updating values for entity properties that have been converted to
// an entity field, directly write to the plain value. This makes it
// possible to use the BC-decorator with properties; e.g., $node->title.
if ($defined && empty($this->definitions[$name]['configurable'])) {
$this->decorated->values[$name][Language::LANGCODE_DEFAULT] = $value;
}
else {
if ($defined && is_array($value)) {
// If field API sets a value with a langcode in entity language, move it
// to Language::LANGCODE_DEFAULT.
// This is necessary as EntityNG always keys default language values
// with Language::LANGCODE_DEFAULT while field API expects them to be
// keyed by langcode.
foreach ($value as $langcode => $data) {
if ($langcode != Language::LANGCODE_DEFAULT && $langcode == $this->decorated
->language()->langcode) {
$value[Language::LANGCODE_DEFAULT] = $data;
unset($value[$langcode]);
}
}
}
$this->decorated->values[$name] = $value;
}
// Remove the field object to avoid the field object and the value getting
// out of sync. That way, the next field object instantiated by EntityNG
// will hold the updated value.
unset($this->decorated->fields[$name]);
}
/**
* Implements the magic method for isset().
*/
public function __isset($name) {
$value = $this
->__get($name);
return isset($value);
}
/**
* Implements the magic method for unset().
*/
public function __unset($name) {
// Set the value to NULL.
$value =& $this
->__get($name);
$value = NULL;
}
/**
* Implements the magic method for clone().
*/
function __clone() {
$this->decorated = clone $this->decorated;
}
/**
* Forwards the call to the decorated entity.
*/
public function uriRelationships() {
return $this->decorated
->uriRelationships();
}
/**
* Forwards the call to the decorated entity.
*/
public function access($operation = 'view', AccountInterface $account = NULL) {
return $this->decorated
->access($operation, $account);
}
/**
* Forwards the call to the decorated entity.
*/
public function get($property_name) {
// Ensure this works with not yet defined fields.
if (!isset($this->definitions[$property_name])) {
return $this
->__get($property_name);
}
return $this->decorated
->get($property_name);
}
/**
* Forwards the call to the decorated entity.
*/
public function set($property_name, $value, $notify = TRUE) {
// Ensure this works with not yet defined fields.
if (!isset($this->definitions[$property_name])) {
return $this
->__set($property_name, $value);
}
return $this->decorated
->set($property_name, $value);
}
/**
* Forwards the call to the decorated entity.
*/
public function getProperties($include_computed = FALSE) {
return $this->decorated
->getProperties($include_computed);
}
/**
* Forwards the call to the decorated entity.
*/
public function getPropertyValues() {
return $this->decorated
->getPropertyValues();
}
/**
* Forwards the call to the decorated entity.
*/
public function setPropertyValues($values) {
return $this->decorated
->setPropertyValues($values);
}
/**
* Forwards the call to the decorated entity.
*/
public function getPropertyDefinition($name) {
return $this->decorated
->getPropertyDefinition($name);
}
/**
* Forwards the call to the decorated entity.
*/
public function getPropertyDefinitions() {
return $this->decorated
->getPropertyDefinitions();
}
/**
* Forwards the call to the decorated entity.
*/
public function isEmpty() {
return $this->decorated
->isEmpty();
}
/**
* Forwards the call to the decorated entity.
*/
public function getIterator() {
return $this->decorated
->getIterator();
}
/**
* Forwards the call to the decorated entity.
*/
public function id() {
return $this->decorated
->id();
}
/**
* Forwards the call to the decorated entity.
*/
public function uuid() {
return $this->decorated
->uuid();
}
/**
* Forwards the call to the decorated entity.
*/
public function isNew() {
return $this->decorated
->isNew();
}
/**
* Forwards the call to the decorated entity.
*/
public function isNewRevision() {
return $this->decorated
->isNewRevision();
}
/**
* Forwards the call to the decorated entity.
*/
public function setNewRevision($value = TRUE) {
return $this->decorated
->setNewRevision($value);
}
/**
* Forwards the call to the decorated entity.
*/
public function enforceIsNew($value = TRUE) {
return $this->decorated
->enforceIsNew($value);
}
/**
* Forwards the call to the decorated entity.
*/
public function entityType() {
return $this->decorated
->entityType();
}
/**
* Forwards the call to the decorated entity.
*/
public function bundle() {
return $this->decorated
->bundle();
}
/**
* Forwards the call to the decorated entity.
*/
public function label($langcode = NULL) {
return $this->decorated
->label($langcode);
}
/**
* Forwards the call to the decorated entity.
*/
public function uri($rel = 'canonical') {
return $this->decorated
->uri($rel);
}
/**
* Forwards the call to the decorated entity.
*/
public function save() {
return $this->decorated
->save();
}
/**
* Forwards the call to the decorated entity.
*/
public function delete() {
return $this->decorated
->delete();
}
/**
* Forwards the call to the decorated entity.
*/
public function createDuplicate() {
return $this->decorated
->createDuplicate();
}
/**
* Forwards the call to the decorated entity.
*/
public function entityInfo() {
return $this->decorated
->entityInfo();
}
/**
* Forwards the call to the decorated entity.
*/
public function getRevisionId() {
return $this->decorated
->getRevisionId();
}
/**
* Forwards the call to the decorated entity.
*/
public function isDefaultRevision($new_value = NULL) {
return $this->decorated
->isDefaultRevision($new_value);
}
/**
* Forwards the call to the decorated entity.
*/
public function language() {
return $this->decorated
->language();
}
/**
* Forwards the call to the decorated entity.
*/
public function getTranslationLanguages($include_default = TRUE) {
return $this->decorated
->getTranslationLanguages($include_default);
}
/**
* Forwards the call to the decorated entity.
*/
public function getTranslation($langcode, $strict = TRUE) {
return $this->decorated
->getTranslation($langcode, $strict);
}
/**
* Forwards the call to the decorated entity.
*/
public function getType() {
return $this->decorated
->getType();
}
/**
* Forwards the call to the decorated entity.
*/
public function getDefinition() {
return $this->decorated
->getDefinition();
}
/**
* Forwards the call to the decorated entity.
*/
public function getValue() {
return $this->decorated
->getValue();
}
/**
* Forwards the call to the decorated entity.
*/
public function setValue($value, $notify = TRUE) {
return $this->decorated
->setValue($value, $notify);
}
/**
* Forwards the call to the decorated entity.
*/
public function getString() {
return $this->decorated
->getString();
}
/**
* Forwards the call to the decorated entity.
*/
public function getConstraints() {
return $this->decorated
->getConstraints();
}
/**
* Forwards the call to the decorated entity.
*/
public function validate() {
return $this->decorated
->validate();
}
/**
* Forwards the call to the decorated entity.
*/
public function getName() {
return $this->decorated
->getName();
}
/**
* Forwards the call to the decorated entity.
*/
public function getRoot() {
return $this->decorated
->getRoot();
}
/**
* Forwards the call to the decorated entity.
*/
public function getPropertyPath() {
return $this->decorated
->getPropertyPath();
}
/**
* Forwards the call to the decorated entity.
*/
public function getParent() {
return $this->decorated
->getParent();
}
/**
* Forwards the call to the decorated entity.
*/
public function setContext($name = NULL, TypedDataInterface $parent = NULL) {
$this->decorated
->setContext($name, $parent);
}
/**
* Forwards the call to the decorated entity.
*/
public function getExportProperties() {
$this->decorated
->getExportProperties();
}
/**
* Forwards the call to the decorated entity.
*/
public function onChange($property_name) {
$this->decorated
->onChange($property_name);
}
/**
* Forwards the call to the decorated entity.
*/
public function isTranslatable() {
return $this->decorated
->isTranslatable();
}
}
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EntityBCDecorator:: |
protected | property | The EntityInterface object being decorated. | |
EntityBCDecorator:: |
protected | property | Local cache for field definitions. | |
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides AccessibleInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Overrides Entity::getBCEntity(). Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function | Forwards the call to the decorated entity. | |
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Overrides Entity::getNGEntity(). Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TranslatableInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TranslatableInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TranslatableInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides ComplexDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides EntityInterface:: |
|
EntityBCDecorator:: |
public | function |
Forwards the call to the decorated entity. Overrides TypedDataInterface:: |
|
EntityBCDecorator:: |
function | Implements the magic method for clone(). | ||
EntityBCDecorator:: |
function | Constructs a Drupal\Core\Entity\EntityCompatibilityDecorator object. | ||
EntityBCDecorator:: |
public | function | Implements the magic method for getting object properties. | 1 |
EntityBCDecorator:: |
public | function | Implements the magic method for isset(). | |
EntityBCDecorator:: |
public | function | Implements the magic method for setting object properties. | |
EntityBCDecorator:: |
public | function | Implements the magic method for unset(). |