diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index c016093..94545c7 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php @@ -9,6 +9,7 @@ use Drupal\Core\Database\Connection; use Drupal\Core\Entity\Query\QueryInterface; +use Drupal\Core\Language\Language; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Uuid\Uuid; use Drupal\field\FieldInfo; @@ -569,15 +570,20 @@ protected function doLoadFieldItems($entities, $age) { } // Load field data. + $all_langcodes = array_keys(language_list()); foreach ($fields as $field_name => $field) { $table = $load_current ? static::_fieldTableName($field) : static::_fieldRevisionTableName($field); + // If the field is translatable ensure that only values having valid + // languages are retrieved. Since we are loading values for multiple + // entities, we cannot limit the query to the available translations. + $langcodes = $field['translatable'] ? $all_langcodes : array(Language::LANGCODE_NOT_SPECIFIED); $results = $this->database->select($table, 't') ->fields('t') ->condition($load_current ? 'entity_id' : 'revision_id', $ids, 'IN') - ->condition('langcode', field_available_languages($this->entityType, $field), 'IN') - ->orderBy('delta') ->condition('deleted', 0) + ->condition('langcode', $langcodes, 'IN') + ->orderBy('delta') ->execute(); $delta_count = array(); @@ -597,7 +603,7 @@ protected function doLoadFieldItems($entities, $age) { } // Add the item to the field values for the entity. - $entities[$row->entity_id]->{$field_name}[$row->langcode][] = $item; + $entities[$row->entity_id]->getTranslation($row->langcode)->{$field_name}[$delta_count[$row->entity_id][$row->langcode]] = $item; $delta_count[$row->entity_id][$row->langcode]++; } } @@ -621,29 +627,19 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { $table_name = static::_fieldTableName($field); $revision_name = static::_fieldRevisionTableName($field); - $all_langcodes = field_available_languages($entity_type, $field); - $field_langcodes = array_intersect($all_langcodes, array_keys((array) $entity->$field_name)); - // Delete and insert, rather than update, in case a value was added. if ($update) { - // Delete language codes present in the incoming $entity->$field_name. - // Delete all language codes if $entity->$field_name is empty. - $langcodes = !empty($entity->$field_name) ? $field_langcodes : $all_langcodes; - if ($langcodes) { - // Only overwrite the field's base table if saving the default revision - // of an entity. - if ($entity->isDefaultRevision()) { - $this->database->delete($table_name) - ->condition('entity_id', $id) - ->condition('langcode', $langcodes, 'IN') - ->execute(); - } - $this->database->delete($revision_name) + // Only overwrite the field's base table if saving the default revision + // of an entity. + if ($entity->isDefaultRevision()) { + $this->database->delete($table_name) ->condition('entity_id', $id) - ->condition('revision_id', $vid) - ->condition('langcode', $langcodes, 'IN') ->execute(); } + $this->database->delete($revision_name) + ->condition('entity_id', $id) + ->condition('revision_id', $vid) + ->execute(); } // Prepare the multi-insert query. @@ -655,8 +651,12 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { $query = $this->database->insert($table_name)->fields($columns); $revision_query = $this->database->insert($revision_name)->fields($columns); - foreach ($field_langcodes as $langcode) { - $items = (array) $entity->{$field_name}[$langcode]; + $langcodes = $field['translatable'] ? array_keys($entity->getTranslationLanguages()) : array(Language::LANGCODE_NOT_SPECIFIED); + foreach ($langcodes as $langcode) { + $items = $entity->getTranslation($langcode)->{$field_name}->getValue(); + if (!isset($items)) { + continue; + } $delta_count = 0; foreach ($items as $delta => $item) { // We now know we have someting to insert. diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php index 42ea348..c813aeae 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php @@ -332,9 +332,6 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) { public function save(EntityInterface $entity) { $transaction = $this->database->startTransaction(); try { - // Ensure we are dealing with the actual entity. - $entity = $entity->getNGEntity(); - // Sync the changes made in the fields array to the internal values array. $entity->updateOriginalValues(); @@ -574,11 +571,6 @@ public function delete(array $entities) { $entity_class = $this->entityClass; $entity_class::preDelete($this, $entities); - // Ensure we are dealing with the actual entities. - foreach ($entities as $id => $entity) { - $entities[$id] = $entity->getNGEntity(); - } - foreach ($entities as $entity) { $this->invokeHook('predelete', $entity); } diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php index 68404ba..7eddaee 100644 --- a/core/lib/Drupal/Core/Entity/Entity.php +++ b/core/lib/Drupal/Core/Entity/Entity.php @@ -414,20 +414,6 @@ public function getExportProperties() { } /** - * Implements \Drupal\Core\Entity\EntityInterface::getBCEntity(). - */ - public function getBCEntity() { - return $this; - } - - /** - * Implements \Drupal\Core\Entity\EntityInterface::getNGEntity(). - */ - public function getNGEntity() { - return $this; - } - - /** * {@inheritdoc} */ public function getDefinition() { diff --git a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php deleted file mode 100644 index bfb13ee..0000000 --- a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php +++ /dev/null @@ -1,629 +0,0 @@ -title = $value; - * $node->body[LANGUAGE_NONE][0]['value'] = $value; - * @endcode - * Without the BC decorator the same assignment would have to look like this: - * @code - * $node->title->value = $value; - * $node->body->value = $value; - * @endcode - * 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. - */ -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(TRUE); - } - } - // 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])) { - // We need to ensure the key doesn't matter. Mostly it's 'value' but - // e.g. EntityReferenceItem uses target_id - so just take the first one. - if (isset($this->decorated->values[$name][Language::LANGCODE_DEFAULT][0]) && is_array($this->decorated->values[$name][Language::LANGCODE_DEFAULT][0])) { - return $this->decorated->values[$name][Language::LANGCODE_DEFAULT][0][current(array_keys($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->getUntranslated()->language()->id; - 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()->id) { - $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]); - $this->decorated->onChange($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) { - return $this->decorated->getTranslation($langcode); - } - - /** - * 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 applyDefaultValue($notify = TRUE) { - return $this->decorated->applyDefaultValue($notify); - } - - /* - * {@inheritdoc} - */ - public function preSave(EntityStorageControllerInterface $storage_controller) { - $this->decorated->preSave($storage_controller); - } - - /** - * {@inheritdoc} - */ - public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) { - $this->decorated->preSave($storage_controller, $record); - } - - /** - * {@inheritdoc} - */ - public function postSave(EntityStorageControllerInterface $storage_controller, $update = TRUE) { - $this->decorated->postSave($storage_controller, $update); - } - - /** - * {@inheritdoc} - */ - public static function preCreate(EntityStorageControllerInterface $storage_controller, array &$values) { - } - - public function postCreate(EntityStorageControllerInterface $storage_controller) { - $this->decorated->postCreate($storage_controller); - } - - /** - * {@inheritdoc} - */ - public static function preDelete(EntityStorageControllerInterface $storage_controller, array $entities) { - } - - /** - * {@inheritdoc} - */ - public static function postDelete(EntityStorageControllerInterface $storage_controller, array $entities) { - } - - /** - * {@inheritdoc} - */ - public static function postLoad(EntityStorageControllerInterface $storage_controller, array $entities) { - } - - /** - * Forwards the call to the decorated entity. - */ - public function isTranslatable() { - return $this->decorated->isTranslatable(); - } - - /** - * Forwards the call to the decorated entity. - */ - public function getUntranslated() { - return $this->decorated->getUntranslated(); - } - - /** - * Forwards the call to the decorated entity. - */ - public function hasTranslation($langcode) { - return $this->decorated->hasTranslation($langcode); - } - - /** - * Forwards the call to the decorated entity. - */ - public function addTranslation($langcode, array $values = array()) { - return $this->decorated->addTranslation($langcode, $values); - } - - /** - * Forwards the call to the decorated entity. - */ - public function removeTranslation($langcode) { - $this->decorated->removeTranslation($langcode); - } - - /** - * Forwards the call to the decorated entity. - */ - public function initTranslation($langcode) { - $this->decorated->initTranslation($langcode); - } - - /** - * {@inheritdoc} - */ - public static function baseFieldDefinitions($entity_type) { - return array(); - } - -} diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php index 147baff..552813b 100644 --- a/core/lib/Drupal/Core/Entity/EntityFormController.php +++ b/core/lib/Drupal/Core/Entity/EntityFormController.php @@ -274,31 +274,10 @@ public function validate(array $form, array &$form_state) { $violations = array(); - // @todo Simplify when all entity types are converted to EntityNG. - if ($entity instanceof EntityNG) { - foreach ($entity as $field_name => $field) { - $field_violations = $field->validate(); - if (count($field_violations)) { - $violations[$field_name] = $field_violations; - } - } - } - else { - // For BC entities, iterate through each field instance and - // instantiate NG items objects manually. - $definitions = \Drupal::entityManager()->getFieldDefinitions($entity_type, $entity->bundle()); - foreach (field_info_instances($entity_type, $entity->bundle()) as $field_name => $instance) { - $langcode = field_is_translatable($entity_type, $instance->getField()) ? $entity_langcode : Language::LANGCODE_NOT_SPECIFIED; - - // Create the field object. - $items = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); - // @todo Exception : calls setValue(), tries to set the 'formatted' - // property. - $field = \Drupal::typedData()->create($definitions[$field_name], $items, $field_name, $entity); - $field_violations = $field->validate(); - if (count($field_violations)) { - $violations[$field->getName()] = $field_violations; - } + foreach ($entity as $field_name => $field) { + $field_violations = $field->validate(); + if (count($field_violations)) { + $violations[$field_name] = $field_violations; } } diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php index 9d58820..7d0056c 100644 --- a/core/lib/Drupal/Core/Entity/EntityInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityInterface.php @@ -291,26 +291,6 @@ public function isDefaultRevision($new_value = NULL); public function getExportProperties(); /** - * Gets a backward compatibility decorator entity. - * - * @return \Drupal\Core\Entity\EntityInterface - * The backward compatible entity. - * - * @see \Drupal\Core\Entity\EntityInterface::getNGEntity() - */ - public function getBCEntity(); - - /** - * Removes any possible (backward compatibility) decorator in use. - * - * @return \Drupal\Core\Entity\EntityInterface - * The original, not backward compatible entity object. - * - * @see \Drupal\Core\Entity\EntityInterface::getBCEntity() - */ - public function getNGEntity(); - - /** * Returns the translation support status. * * @return bool diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php index d0b6b4c..d092b2c 100644 --- a/core/lib/Drupal/Core/Entity/EntityNG.php +++ b/core/lib/Drupal/Core/Entity/EntityNG.php @@ -70,13 +70,6 @@ class EntityNG extends Entity { protected $fields = array(); /** - * An instance of the backward compatibility decorator. - * - * @var EntityBCDecorator - */ - protected $bcEntity; - - /** * Local cache for the entity language. * * @var \Drupal\Core\Language\Language @@ -308,13 +301,6 @@ protected function getTranslatedField($property_name, $langcode) { if (isset($this->values[$property_name][$langcode])) { $value = $this->values[$property_name][$langcode]; } - // @todo Remove this once the BC decorator is gone. - elseif ($property_name != 'langcode' && $langcode == Language::LANGCODE_DEFAULT) { - $default_langcode = $this->language()->id; - if (isset($this->values[$property_name][$default_langcode])) { - $value = $this->values[$property_name][$default_langcode]; - } - } $field = \Drupal::typedData()->getPropertyInstance($this, $property_name, $value); $field->setLangcode($langcode); $this->fields[$property_name][$langcode] = $field; @@ -572,6 +558,10 @@ protected function initializeTranslation($langcode) { * {@inheritdoc} */ public function hasTranslation($langcode) { + $default_language = $this->language ?: $this->getDefaultLanguage(); + if ($langcode == $default_language->id) { + $langcode = Language::LANGCODE_DEFAULT; + } return !empty($this->translations[$langcode]['status']); } @@ -617,10 +607,10 @@ public function addTranslation($langcode, array $values = array()) { */ public function removeTranslation($langcode) { if (isset($this->translations[$langcode]) && $langcode != Language::LANGCODE_DEFAULT && $langcode != $this->getDefaultLanguage()->id) { - foreach ($this->getPropertyDefinitions() as $definition) { + foreach ($this->getPropertyDefinitions() as $name => $definition) { if (!empty($definition['translatable'])) { - unset($this->values[$langcode]); - unset($this->fields[$langcode]); + unset($this->values[$name][$langcode]); + unset($this->fields[$name][$langcode]); } } $this->translations[$langcode]['status'] = static::TRANSLATION_REMOVED; @@ -666,18 +656,6 @@ public function translations() { } /** - * Overrides Entity::getBCEntity(). - */ - public function getBCEntity() { - if (!isset($this->bcEntity)) { - // Initialize field definitions so that we can pass them by reference. - $this->getPropertyDefinitions(); - $this->bcEntity = new EntityBCDecorator($this, $this->fieldDefinitions); - } - return $this->bcEntity; - } - - /** * Updates the original values with the interim changes. */ public function updateOriginalValues() { @@ -697,8 +675,8 @@ public function updateOriginalValues() { /** * Implements the magic method for setting object properties. * - * Uses default language always. - * For compatibility mode to work this must return a reference. + * @todo: A lot of code still uses non-fields (e.g. $entity->content in render + * controllers by reference. Clean that up. */ public function &__get($name) { // If this is an entity field, handle it accordingly. We first check whether @@ -714,11 +692,6 @@ public function &__get($name) { $return = $this->getTranslatedField($name, $this->activeLangcode); return $return; } - // Allow the EntityBCDecorator to directly access the values and fields. - // @todo: Remove once the EntityBCDecorator gets removed. - if ($name == 'values' || $name == 'fields') { - return $this->$name; - } // Else directly read/write plain values. That way, non-field entity // properties can always be accessed directly. if (!isset($this->values[$name])) { @@ -745,6 +718,11 @@ public function __set($name, $value) { elseif ($this->getPropertyDefinition($name)) { $this->getTranslatedField($name, $this->activeLangcode)->setValue($value); } + // The translations array is unset when cloning the entity object, we just + // need to restore it. + elseif ($name == 'translations') { + $this->translations = $value; + } // Else directly read/write plain values. That way, fields not yet converted // to the entity field API can always be directly accessed. else { @@ -806,8 +784,6 @@ public function createDuplicate() { * Magic method: Implements a deep clone. */ public function __clone() { - $this->bcEntity = NULL; - // Avoid deep-cloning when we are initializing a translation object, since // it will represent the same entity, only with a different active language. if (!$this->translationInitialize) { @@ -817,7 +793,15 @@ public function __clone() { $this->fields[$name][$langcode]->setContext($name, $this); } } + + // Ensure the translations array is actually cloned by removing the + // original reference and re-creating its values. $this->clearTranslationCache(); + $translations = $this->translations; + unset($this->translations); + // This will trigger the magic setter as the translations array is + // undefined now. + $this->translations = $translations; } } diff --git a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php index 5ee2309..87b86c0 100644 --- a/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php +++ b/core/lib/Drupal/Core/Entity/FieldableEntityStorageControllerBase.php @@ -42,11 +42,6 @@ protected function loadFieldItems(array $entities, $age) { $info = entity_get_info($this->entityType); $use_cache = $load_current && $info['field_cache']; - // Ensure we are working with a BC mode entity. - foreach ($entities as $id => $entity) { - $entities[$id] = $entity->getBCEntity(); - } - // Assume all entities will need to be queried. Entities found in the cache // will be removed from the list. $queried_entities = $entities; @@ -65,8 +60,13 @@ protected function loadFieldItems(array $entities, $age) { $cid = "field:{$this->entityType}:$id"; if (isset($cache[$cid])) { unset($queried_entities[$id]); - foreach ($cache[$cid]->data as $field_name => $values) { - $entity->$field_name = $values; + foreach ($cache[$cid]->data as $langcode => $values) { + $translation = $entity->getTranslation($langcode); + // We do not need to worry about field translatability here, the + // translation object will manage that automatically. + foreach ($values as $field_name => $items) { + $translation->$field_name = $items; + } } } } @@ -87,8 +87,11 @@ protected function loadFieldItems(array $entities, $age) { foreach ($queried_entities as $id => $entity) { $data = array(); $instances = field_info_instances($this->entityType, $entity->bundle()); - foreach ($instances as $instance) { - $data[$instance['field_name']] = $queried_entities[$id]->{$instance['field_name']}; + foreach ($entity->getTranslationLanguages() as $langcode => $language) { + $translation = $entity->getTranslation($langcode); + foreach ($instances as $instance) { + $data[$langcode][$instance['field_name']] = $translation->{$instance['field_name']}->getValue(); + } } $cid = "field:{$this->entityType}:$id"; cache('field')->set($cid, $data); @@ -110,9 +113,6 @@ protected function loadFieldItems(array $entities, $age) { * TRUE if the entity is being updated, FALSE if it is being inserted. */ protected function saveFieldItems(EntityInterface $entity, $update = TRUE) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - $this->doSaveFieldItems($entity, $update); if ($update) { @@ -134,9 +134,6 @@ protected function saveFieldItems(EntityInterface $entity, $update = TRUE) { * The entity. */ protected function deleteFieldItems(EntityInterface $entity) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - $this->doDeleteFieldItems($entity); $entity_info = $entity->entityInfo(); @@ -156,7 +153,7 @@ protected function deleteFieldItems(EntityInterface $entity) { * The entity. It must have a revision ID attribute. */ protected function deleteFieldItemsRevision(EntityInterface $entity) { - $this->doDeleteFieldItemsRevision($entity->getBCEntity()); + $this->doDeleteFieldItemsRevision($entity); } /** diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReference.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReference.php index 4741c19..b586bd6 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReference.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityReference.php @@ -99,10 +99,6 @@ public function setValue($value, $notify = TRUE) { // Both the entity ID and the entity object may be passed as value. The // reference may also be unset by passing NULL as value. if (!isset($value) || $value instanceof EntityInterface) { - // Ensure we reference a NG Entity object. - if (isset($value)) { - $value = $value->getNGEntity(); - } $this->target = $value; } elseif (!is_scalar($value) || empty($this->definition['constraints']['EntityType'])) { diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php index 80ad70a..9607dd1 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php @@ -142,8 +142,7 @@ public function addField($field, $type, $langcode) { } $entity = $entity_manager ->getStorageController($entity_type) - ->create($values) - ->getNGEntity(); + ->create($values); $propertyDefinitions = $entity->$field_name->getPropertyDefinitions(); // If the column is not yet known, ie. the @@ -196,8 +195,7 @@ public function addField($field, $type, $langcode) { } $entity = $entity_manager ->getStorageController($entity_type) - ->create($values) - ->getNGEntity(); + ->create($values); $propertyDefinitions = $entity->$specifier->getPropertyDefinitions(); $relationship_specifier = $specifiers[$key + 1]; $next_index_prefix = $relationship_specifier; diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 49a3adc..27965bf 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -610,19 +610,9 @@ function content_translation_form_alter(array &$form, array &$form_state) { // Handle fields shared between translations when there is at least one // translation available or a new one is being created. if (!$entity->isNew() && (!isset($translations[$form_langcode]) || count($translations) > 1)) { - $entity = $entity->getNGEntity(); - if ($entity instanceof EntityNG) { - foreach ($entity->getPropertyDefinitions() as $property_name => $definition) { - if (isset($form[$property_name])) { - $form[$property_name]['#multilingual'] = !empty($definition['translatable']); - } - } - } - else { - foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { - $field_name = $instance['field_name']; - $field = $instance->getField(); - $form[$field_name]['#multilingual'] = !empty($field['translatable']); + foreach ($entity->getPropertyDefinitions() as $property_name => $definition) { + if (isset($form[$property_name])) { + $form[$property_name]['#multilingual'] = !empty($definition['translatable']); } } } @@ -647,18 +637,7 @@ function content_translation_field_language_alter(&$display_language, $context) foreach ($entity->translation as $langcode => $translation) { if ($langcode == $context['langcode'] || !content_translation_view_access($entity, $langcode)) { - // Unset unaccessible field translations: if the field is untranslatable - // unsetting a language different from Language::LANGCODE_NOT_SPECIFIED has no - // effect. - foreach ($instances as $instance) { - // @todo BC entities have the same value accessibile both with the - // entity language and with Language::LANGCODE_DEFAULT. We need need to unset - // both until we remove the BC layer. - if ($langcode == $entity_langcode) { - unset($entity->{$instance['field_name']}[Language::LANGCODE_DEFAULT]); - } - unset($entity->{$instance['field_name']}[$langcode]); - } + $entity->removeTranslation($langcode); } } diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc index 966d259..d97ffe1 100644 --- a/core/modules/content_translation/content_translation.pages.inc +++ b/core/modules/content_translation/content_translation.pages.inc @@ -236,23 +236,8 @@ function content_translation_edit_page(EntityInterface $entity, Language $langua * The language to be used as target. */ function content_translation_prepare_translation(EntityInterface $entity, Language $source, Language $target) { - // @todo Unify field and property handling. - $entity = $entity->getNGEntity(); - if ($entity instanceof EntityNG) { - $source_translation = $entity->getTranslation($source->id); - $entity->addTranslation($target->id, $source_translation->getPropertyValues()); - } - else { - $instances = field_info_instances($entity->entityType(), $entity->bundle()); - foreach ($instances as $field_name => $instance) { - $field = $instance->getField(); - if (!empty($field['translatable'])) { - $value = $entity->get($field_name); - $value[$target->id] = isset($value[$source->id]) ? $value[$source->id] : array(); - $entity->set($field_name, $value); - } - } - } + $source_translation = $entity->getTranslation($source->id); + $entity->addTranslation($target->id, $source_translation->getPropertyValues()); } /** diff --git a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php index 9fd4b0e..46a5b89 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php @@ -37,12 +37,6 @@ public function __construct(EntityManager $entityManager) { * {@inheritdoc} */ public function synchronizeFields(EntityInterface $entity, $sync_langcode, $original_langcode = NULL) { - // Field synchronization is only supported for NG entities. - $entity = $entity->getNGEntity(); - if (!($entity instanceof EntityNG)) { - return; - } - $translations = $entity->getTranslationLanguages(); // If we have no information about what to sync to, if we are creating a new diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ConfigTestTranslationUITest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ConfigTestTranslationUITest.php index bb3c3fe..a83e3f9 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ConfigTestTranslationUITest.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ConfigTestTranslationUITest.php @@ -54,23 +54,24 @@ protected function getNewEntityValues($langcode) { } /** - * Overrides ContentTranslationTest::testTranslationUI(). + * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::::testTranslationUI(). * - * @todo This override is a copy-paste of parts of the parent method. Turn - * ConfigTest into a properly translatable entity and remove this override. + * @todo Config entities are not translatable, but Content Translation module + * doesn't have a clean way to enforce that, so this test is here to ensure + * the module doesn't interfere with basic config entity storage. + * Reconsider the purpose of this test after http://drupal.org/node/2004244 + * and either remove it or rewrite it to more clearly test what is needed. */ function testTranslationUI() { // Create a new test entity with original values in the default language. $default_langcode = $this->langcodes[0]; - $values[$default_langcode] = $this->getNewEntityValues($default_langcode); - $id = $this->createEntity($values[$default_langcode], $default_langcode); + $values = $this->getNewEntityValues($default_langcode); + $id = $this->createEntity($values, $default_langcode); $entity = entity_load($this->entityType, $id, TRUE); $this->assertTrue($entity, 'Entity found in the database.'); - $translation = $this->getTranslation($entity, $default_langcode); - foreach ($values[$default_langcode] as $property => $value) { - $stored_value = $this->getValue($translation, $property, $default_langcode); - $value = is_array($value) ? $value[0]['value'] : $value; + foreach ($values as $property => $value) { + $stored_value = $entity->{$property}; $message = format_string('@property correctly stored in the default language.', array('@property' => $property)); $this->assertIdentical($stored_value, $value, $message); } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php index 56649cb..ef579b2 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationUITest.php @@ -258,9 +258,7 @@ protected function getFormSubmitAction(EntityInterface $entity) { * The translation object to act on. */ protected function getTranslation(EntityInterface $entity, $langcode) { - // @todo remove once EntityBCDecorator is gone. - $entity = $entity->getNGEntity(); - return $entity instanceof EntityNG ? $entity->getTranslation($langcode) : $entity; + return $entity->getTranslation($langcode); } /** @@ -278,13 +276,7 @@ protected function getTranslation(EntityInterface $entity, $langcode) { */ protected function getValue(EntityInterface $translation, $property, $langcode) { $key = $property == 'user_id' ? 'target_id' : 'value'; - // @todo remove EntityBCDecorator condition once EntityBCDecorator is gone. - if (($translation instanceof EntityInterface) && !($translation instanceof EntityNG) && !($translation instanceof EntityBCDecorator)) { - return is_array($translation->$property) ? $translation->{$property}[$langcode][0][$key] : $translation->$property; - } - else { - return $translation->get($property)->{$key}; - } + return $translation->get($property)->{$key}; } } diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index f12459b..58773f5 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -353,13 +353,11 @@ function _field_invoke_widget_target($form_display) { * values. */ function field_attach_preprocess(EntityInterface $entity, $element, &$variables) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); foreach (field_info_instances($entity->entityType(), $entity->bundle()) as $instance) { $field_name = $instance['field_name']; if (isset($element[$field_name]['#language'])) { $langcode = $element[$field_name]['#language']; - $variables[$field_name] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : NULL; + $variables[$field_name] = $entity->getTranslation($langcode)->{$field_name}->getValue(); } } diff --git a/core/modules/field/field.deprecated.inc b/core/modules/field/field.deprecated.inc index 8ac601e..61babe5 100644 --- a/core/modules/field/field.deprecated.inc +++ b/core/modules/field/field.deprecated.inc @@ -558,9 +558,6 @@ function field_read_instances($conditions = array(), $include_additional = array * @see field_form_set_state() */ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langcode = NULL, array $options = array()) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - // Set #parents to 'top-level' by default. $form += array('#parents' => array()); @@ -615,11 +612,6 @@ function field_attach_form(EntityInterface $entity, &$form, &$form_state, $langc * @deprecated as of Drupal 8.0. Use the entity system instead. */ function field_attach_form_validate(EntityInterface $entity, $form, &$form_state, array $options = array()) { - // Only support NG entities. - if (!($entity->getNGEntity() instanceof EntityNG)) { - return; - } - $has_violations = FALSE; foreach ($entity as $field_name => $field) { $definition = $field->getDefinition(); @@ -663,9 +655,6 @@ function field_attach_form_validate(EntityInterface $entity, $form, &$form_state * @deprecated as of Drupal 8.0. Use the entity system instead. */ function field_attach_extract_form_values(EntityInterface $entity, $form, &$form_state, array $options = array()) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - // Extract field values from submitted values. $form_display = $form_state['form_display']; field_invoke_method('extractFormValues', _field_invoke_widget_target($form_display), $entity, $form, $form_state, $options); @@ -714,9 +703,6 @@ function field_attach_prepare_view($entity_type, array $entities, array $display $prepare = array(); foreach ($entities as $id => $entity) { if (empty($entity->_field_view_prepared)) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - // Add this entity to the items to be prepared. $prepare[$id] = $entity; @@ -770,8 +756,6 @@ function field_attach_prepare_view($entity_type, array $entities, array $display * @deprecated as of Drupal 8.0. Use the entity system instead. */ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $langcode = NULL, array $options = array()) { - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); // Determine the actual language code to display for each field, given the // language codes available in the field data. $options['langcode'] = field_language($entity, NULL, $langcode); @@ -783,8 +767,6 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan }; $null = NULL; $output = field_invoke_method('view', $target_function, $entity, $null, $null, $options); - // Remove the BC layer now. - $entity = $entity->getNGEntity(); // Let other modules alter the renderable array. $view_mode = $display->originalMode; @@ -822,7 +804,6 @@ function field_attach_view(EntityInterface $entity, EntityDisplay $display, $lan * $entity->getTranslation($langcode)->{$field_name} */ function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) { - $entity = $entity->getBCEntity(); $langcode = field_language($entity, $field_name, $langcode); return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); } diff --git a/core/modules/field/field.module b/core/modules/field/field.module index cc7ad90..d6b71ed 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -577,8 +577,7 @@ function _field_filter_xss_display_allowed_tags() { * @param $field_name * The name of the field to display. * @param $item - * The field value to display, as found in - * $entity->field_name[$langcode][$delta]. + * The field item value to display. * @param $display * Can be either the name of a view mode, or an array of display settings. See * field_view_field() for more information. @@ -592,9 +591,6 @@ function _field_filter_xss_display_allowed_tags() { function field_view_value(EntityInterface $entity, $field_name, $item, $display = array(), $langcode = NULL) { $output = array(); - // Ensure we are working with a BC mode entity. - $entity = $entity->getBCEntity(); - if ($field = field_info_field($entity->entityType(), $field_name)) { // Determine the langcode that will be used by language fallback. $langcode = field_language($entity, $field_name, $langcode); @@ -602,7 +598,7 @@ function field_view_value(EntityInterface $entity, $field_name, $item, $display // Push the item as the single value for the field, and defer to // field_view_field() to build the render array for the whole field. $clone = clone $entity; - $clone->{$field_name}[$langcode] = array($item); + $clone->getTranslation($langcode)->{$field_name}->setValue(array($item)); $elements = field_view_field($clone, $field_name, $display, $langcode); // Extract the part of the render array we need. @@ -700,7 +696,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options $display_langcode = field_language($entity, $field_name, $langcode); // Invoke the formatter's prepareView() and view() methods. - $items = $entity->getNGEntity()->getTranslation($display_langcode)->get($field_name); + $items = $entity->getTranslation($display_langcode)->get($field_name); $id = $entity->id(); $formatter->prepareView(array($id => $entity), $display_langcode, array($id => $items)); $result = $formatter->view($entity, $display_langcode, $items); diff --git a/core/modules/field/field.multilingual.inc b/core/modules/field/field.multilingual.inc index d02595c..ac12d1c 100644 --- a/core/modules/field/field.multilingual.inc +++ b/core/modules/field/field.multilingual.inc @@ -89,16 +89,16 @@ function field_language_fallback(&$field_langcodes, EntityInterface $entity, $la foreach ($field_langcodes as $field_name => $field_langcode) { // If the requested language is defined for the current field use it, // otherwise search for a fallback value among the fallback candidates. - if (isset($entity->{$field_name}[$langcode])) { + if (_field_translated_value_exists($entity, $langcode, $field_name)) { $field_langcodes[$field_name] = $langcode; } - elseif (!empty($entity->{$field_name})) { + else { if (!isset($fallback_candidates)) { require_once DRUPAL_ROOT . '/core/includes/language.inc'; $fallback_candidates = language_fallback_get_candidates(); } foreach ($fallback_candidates as $fallback_langcode) { - if (isset($entity->{$field_name}[$fallback_langcode])) { + if (_field_translated_value_exists($entity, $fallback_langcode, $field_name)) { $field_langcodes[$field_name] = $fallback_langcode; break; } @@ -309,7 +309,7 @@ function field_language(EntityInterface $entity, $field_name = NULL, $langcode = // if the field translation is not available. It is up to translation // handlers to implement language fallback rules. foreach (field_info_instances($entity_type, $bundle) as $instance) { - if (isset($entity->{$instance['field_name']}[$langcode])) { + if (_field_translated_value_exists($entity, $langcode, $instance['field_name'])) { $display_langcode[$instance['field_name']] = $langcode; } else { @@ -351,3 +351,16 @@ function field_language(EntityInterface $entity, $field_name = NULL, $langcode = return $display_langcode; } + +/** + * Returns TRUE if a non-empty value exists for a given entity/language/field. + */ +function _field_translated_value_exists(EntityInterface $entity, $langcode, $field_name) { + if (!$entity->hasTranslation($langcode)) { + return FALSE; + } + $field = $entity->getTranslation($langcode)->$field_name; + $field->filterEmptyValues(); + $value = $field->getValue(); + return !empty($value); +} diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php index 0130e7a..c79c6d4 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php @@ -277,7 +277,7 @@ function testFieldAttachCache() { $controller->resetCache(); $controller->load($entity->id()); $cache = cache('field')->get($cid); - $this->assertEqual($cache->data[$this->field_name_2][$langcode], $values, 'Cached: correct cache entry on load'); + $this->assertEqual($cache->data[$langcode][$this->field_name_2], $values, 'Cached: correct cache entry on load'); // Update with different values, and check that the cache entry is wiped. $values = $this->_generateTestFieldValues($this->field_2->getFieldCardinality()); @@ -293,7 +293,7 @@ function testFieldAttachCache() { $controller->resetCache(); $controller->load($entity->id()); $cache = cache('field')->get($cid); - $this->assertEqual($cache->data[$this->field_name_2][$langcode], $values, 'Cached: correct cache entry on load'); + $this->assertEqual($cache->data[$langcode][$this->field_name_2], $values, 'Cached: correct cache entry on load'); // Create a new revision, and check that the cache entry is wiped. $entity = entity_create($entity_type, array( @@ -310,7 +310,7 @@ function testFieldAttachCache() { $controller->resetCache(); $controller->load($entity->id()); $cache = cache('field')->get($cid); - $this->assertEqual($cache->data[$this->field_name_2][$langcode], $values, 'Cached: correct cache entry on load'); + $this->assertEqual($cache->data[$langcode][$this->field_name_2], $values, 'Cached: correct cache entry on load'); // Delete, and check that the cache entry is wiped. $entity->delete(); diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php index 1035212..2de2456 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachStorageTest.php @@ -230,7 +230,7 @@ function testFieldAttachSaveEmptyDataDefaultValue() { // Insert: Field is NULL. $entity = clone($entity_init); - $entity->getBCEntity()->{$this->field_name} = NULL; + $entity->{$this->field_name} = NULL; $entity->enforceIsNew(); $entity = $this->entitySaveReload($entity); $this->assertTrue($entity->{$this->field_name}->isEmpty(), 'Insert: NULL field results in no value saved'); diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php index 0830af4..0edb901 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php @@ -318,7 +318,7 @@ function testFieldDisplayLanguage() { \Drupal::state()->set('field_test.language_fallback', FALSE); $entity->getTranslation($requested_langcode)->{$this->field_name}->value = mt_rand(1, 127); drupal_static_reset('field_language'); - $display_langcode = field_language($entity->getBCEntity(), $this->field_name, $requested_langcode); + $display_langcode = field_language($entity, $this->field_name, $requested_langcode); $this->assertEqual($display_langcode, $requested_langcode, 'Display language behave correctly when language fallback is disabled'); } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php index f6d1c8d..4f0a5d9 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php @@ -231,14 +231,7 @@ public function submitForm(array &$form, array &$form_state) { * The field item object. */ protected function getFieldItem(EntityInterface $entity, $field_name) { - if ($entity instanceof EntityNG) { - $item = $entity->get($field_name)->offsetGet(0); - } - else { - $definitions = $this->entityManager->getFieldDefinitions($entity->entityType(), $entity->bundle()); - $item = $this->typedData->create($definitions[$field_name], array(), $field_name, $entity)->offsetGet(0); - } - return $item; + return $entity->get($field_name)->offsetGet(0); } } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php index 18e7f17..d358f0e 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php @@ -218,14 +218,7 @@ public function delete(array &$form, array &$form_state) { * The field object. */ protected function getFieldItems(EntityInterface $entity, $field_name) { - if ($entity instanceof EntityNG) { - $item = $entity->get($field_name); - } - else { - $definitions = \Drupal::entityManager()->getFieldDefinitions($entity->entityType(), $entity->bundle()); - $item = \Drupal::typedData()->create($definitions[$field_name], $this->instance->default_value, $field_name, $entity); - } - return $item; + return $entity->get($field_name); } /** diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php index 85b7450..055b852 100644 --- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php +++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php @@ -63,7 +63,7 @@ function testUninstallProcess() { $language_manager->init(); // Check the UI language. - // @todo: If the global user is an EntityBCDecorator, getting the roles + // @todo: If the global user is an Entity, getting the roles // from it within LocaleLookup results in a loop that invokes LocaleLookup // again. global $user; diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityBCDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityBCDecoratorTest.php deleted file mode 100644 index f9746d2..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityBCDecoratorTest.php +++ /dev/null @@ -1,78 +0,0 @@ - 'Entity Backward Compatibility Decorator', - 'description' => 'Tests the Entity Backward Compatibility Decorator', - 'group' => 'Entity API', - ); - } - - public function setUp() { - parent::setUp(); - $this->installSchema('user', array('users_roles', 'users_data')); - $this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_access')); - $this->installSchema('comment', array('comment', 'node_comment_statistics')); - } - - /** - * Tests using the entity BC decorator with entity properties. - * - * @see \Drupal\Core\Entity\EntityBCDecorator - */ - public function testBCDecorator() { - // Test using comment subject via the BC decorator. - $this->createUser(); - $node = entity_create('node', array( - 'type' => 'page', - 'uid' => 1, - )); - $node->save(); - $comment = entity_create('comment', array( - 'nid' => $node->id(), - 'subject' => 'old-value', - )); - $comment->save(); - $bc_entity = $comment->getBCEntity(); - - // Test reading of a defined property. - $this->assertEqual($bc_entity->subject, 'old-value', 'Accessing entity property via BC decorator.'); - // Test writing of a defined property via the decorator. - $bc_entity->subject = 'new'; - $this->assertEqual($bc_entity->subject, 'new', 'Updated defined entity property via BC decorator.'); - $this->assertEqual($comment->subject->value, 'new', 'Updated defined entity property via BC decorator.'); - - // Test writing of a defined property. - $comment->subject->value = 'newer'; - $this->assertEqual($bc_entity->subject, 'newer', 'Updated defined entity property via default entity class.'); - $this->assertEqual($comment->subject->value, 'newer', 'Updated defined entity property via default entity class.'); - - // Test handling of an undefined property. - $this->assertFalse(isset($bc_entity->foo), 'Checking if isset() on undefnied property.'); - $bc_entity->foo = 'bar'; - $this->assertEqual($bc_entity->foo, 'bar', 'Accessing undefined entity property via BC decorator.'); - $this->assertEqual($comment->foo, 'bar', 'Accessing undefined entity property via default entity class.'); - $this->assertTrue(isset($bc_entity->foo), 'Checking if isset() on undefnied property.'); - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php index dc2fb1f..ec480a7 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php @@ -380,7 +380,7 @@ function testEntityTranslationAPI() { $entity->name->value = $name; $name_translated = $langcode . '_' . $this->randomName(); $translation = $entity->addTranslation($langcode); - $this->assertNotEqual($entity, $translation, 'The entity and the translation object differ from one another.'); + $this->assertNotIdentical($entity, $translation, 'The entity and the translation object differ from one another.'); $this->assertTrue($entity->hasTranslation($langcode), 'The new translation exists.'); $this->assertEqual($translation->language()->id, $langcode, 'The translation language matches the specified one.'); $this->assertEqual($translation->getUntranslated()->language()->id, $default_langcode, 'The original language can still be retrieved.'); @@ -404,7 +404,7 @@ function testEntityTranslationAPI() { // language. $langcode2 = $this->langcodes[2]; $translation = $entity->getTranslation($langcode2); - $value = $entity != $translation && $translation->language()->id == $langcode2 && $entity->hasTranslation($langcode2); + $value = $entity !== $translation && $translation->language()->id == $langcode2 && $entity->hasTranslation($langcode2); $this->assertTrue($value, 'A new translation object can be obtained also by specifying a valid language.'); $this->assertEqual($entity->language()->id, $default_langcode, 'The original language has been preserved.'); $translation->save(); @@ -478,7 +478,7 @@ function testEntityTranslationAPI() { $entity->getTranslation($langcode); $cloned = clone $entity; $translation = $cloned->getTranslation($langcode); - $this->assertNotEqual($entity, $translation->getUntranslated(), 'A cloned entity object has no reference to the original one.'); + $this->assertNotIdentical($entity, $translation->getUntranslated(), 'A cloned entity object has no reference to the original one.'); // Check that per-language defaults are properly populated. $entity = $this->reloadEntity($entity); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php index 27834a3..384c815 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php @@ -70,12 +70,12 @@ function testFieldAccess() { $values = array('name' => 'test'); $account = entity_create('user', $values); - $this->assertFalse($entity->field_test_text->access('view', $account->getNGEntity()), 'Access to the field was denied.'); + $this->assertFalse($entity->field_test_text->access('view', $account), 'Access to the field was denied.'); $entity->field_test_text = 'access alter value'; - $this->assertFalse($entity->field_test_text->access('view', $account->getNGEntity()), 'Access to the field was denied.'); + $this->assertFalse($entity->field_test_text->access('view', $account), 'Access to the field was denied.'); $entity->field_test_text = 'standard value'; - $this->assertTrue($entity->field_test_text->access('view', $account->getNGEntity()), 'Access to the field was granted.'); + $this->assertTrue($entity->field_test_text->access('view', $account), 'Access to the field was granted.'); } } diff --git a/core/modules/text/lib/Drupal/text/Tests/TextWithSummaryItemTest.php b/core/modules/text/lib/Drupal/text/Tests/TextWithSummaryItemTest.php index 4cc2249..ef9a7df 100644 --- a/core/modules/text/lib/Drupal/text/Tests/TextWithSummaryItemTest.php +++ b/core/modules/text/lib/Drupal/text/Tests/TextWithSummaryItemTest.php @@ -122,8 +122,8 @@ function testProcessedCache() { // Inject values into the cache to make sure that these are used as-is and // not re-calculated. $data = array( - 'summary_field' => array( - Language::LANGCODE_DEFAULT => array( + Language::LANGCODE_DEFAULT => array( + 'summary_field' => array( 0 => array( 'value' => $value, 'summary' => $summary, diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAdminListingTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAdminListingTest.php index 9dfbe65..182812d 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserAdminListingTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserAdminListingTest.php @@ -34,17 +34,17 @@ public function testUserListing() { // Create a bunch of users. $accounts = array(); for ($i = 0; $i < 3; $i++) { - $account = $this->drupalCreateUser()->getNGEntity(); + $account = $this->drupalCreateUser(); $accounts[$account->label()] = $account; } // Create a blocked user. - $account = $this->drupalCreateUser()->getNGEntity(); + $account = $this->drupalCreateUser(); $account->block(); $account->save(); $accounts[$account->label()] = $account; // Create a user at a certain timestamp. - $account = $this->drupalCreateUser()->getNGEntity(); + $account = $this->drupalCreateUser(); $account->created = 1363219200; $account->save(); $accounts[$account->label()] = $account; @@ -53,7 +53,7 @@ public function testUserListing() { $rid_1 = $this->drupalCreateRole(array(), 'custom_role_1', 'custom_role_1'); $rid_2 = $this->drupalCreateRole(array(), 'custom_role_2', 'custom_role_2'); - $account = $this->drupalCreateUser()->getNGEntity(); + $account = $this->drupalCreateUser(); $account->addRole($rid_1); $account->addRole($rid_2); $account->save(); @@ -61,7 +61,7 @@ public function testUserListing() { $role_account_name = $account->label(); // Create an admin user and look at the listing. - $admin_user = $this->drupalCreateUser(array('administer users'))->getNGEntity(); + $admin_user = $this->drupalCreateUser(array('administer users')); $accounts[$admin_user->label()] = $admin_user; $accounts['admin'] = entity_load('user', 1); diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 9dca692..9cbcf0e 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -7,7 +7,6 @@ namespace Drupal\user; -use Drupal\Core\Entity\EntityBCDecorator; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Password\PasswordInterface; use Drupal\Core\Database\Connection; diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php index 75deeba..aa78fb9 100644 --- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php +++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php @@ -1025,20 +1025,6 @@ public function setOriginalID($id) { } /** - * Implements Drupal\Core\Entity\EntityInterface::getBCEntity(). - */ - public function getBCEntity() { - return $this->storage->getBCEntity(); - } - - /** - * Implements \Drupal\Core\Entity\EntityInterface::getNGEntity(). - */ - public function getNGEntity() { - return $this->storage->getNGEntity(); - } - - /** * Implements \Drupal\Core\Entity\EntityInterface::isTranslatable(). */ public function isTranslatable() {