diff --git a/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php index 3a0734b089e91fdfb501acc3f5387dcfa1fc598d..6f8382a44599fc52f860fc246432cd65f7881d88 100644 --- a/core/lib/Drupal/Core/Entity/Field/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Field.php @@ -56,6 +56,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface $this->list[0] = $this->createItem(0); } + /** + * {@inheritdoc} + */ + public function getEntity() { + return $this->getParent(); + } + /** * {@inheritdoc} */ diff --git a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php index 80b0412ffc1a484b859fc6d3f0b99cc762db66da..4708418970f52fdc7807d40becc54c9e322c6893 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php @@ -27,6 +27,14 @@ */ interface FieldInterface extends ListInterface, AccessibleInterface { + /** + * Gets the entity that field belongs to. + * + * @return \Drupal\Core\Entity\EntityInterface + * The entity object. + */ + public function getEntity(); + /** * Sets the langcode of the field values held in the object. * diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index 0ac0a5d489c9e5e380c0775455cb5afe53809867..15744c0d5e5bf975db8197608e4ce87b7f268b71 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -36,6 +36,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface } } + /** + * {@inheritdoc} + */ + public function getEntity() { + return $this->getParent()->getEntity(); + } + /** * {@inheritdoc} */ diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php index e1f5d51b1e4b54d5f1884dd5b5628fa80a8303fe..71fc08646a7e612be0ab4621b48f7b265c0ce895 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php @@ -23,6 +23,14 @@ */ interface FieldItemInterface extends ComplexDataInterface { + /** + * Gets the entity that field belongs to. + * + * @return \Drupal\Core\Entity\EntityInterface + * The entity object. + */ + public function getEntity(); + /** * Gets the langcode of the field values held in the object. * diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php index ca3d99ffd90d4201e553f37129cb4f646b8147cb..79ce7c917fcb43027ab2faa408f5f8a4023df675 100644 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php +++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/EntityChangedConstraintValidator.php @@ -21,9 +21,7 @@ class EntityChangedConstraintValidator extends ConstraintValidator { */ public function validate($value, Constraint $constraint) { if (isset($value)) { - // We are on the field item level, so we need to go two levels up for the - // entity object. - $entity = $this->context->getMetadata()->getTypedData()->getParent()->getParent(); + $entity = $this->context->getMetadata()->getTypedData()->getEntity(); if (!$entity->isNew()) { $saved_entity = \Drupal::entityManager()->getStorageController($entity->entityType())->loadUnchanged($entity->id()); diff --git a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php index 1295776e91b58d104d42bf431549146e1145c5c8..4398a1beee95e195dd3f5c94410b395465740b36 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php +++ b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php @@ -26,8 +26,7 @@ public function getValue() { if (!isset($this->parent)) { throw new InvalidArgumentException('Computed properties require context for computation.'); } - $field = $this->parent->getParent(); - $entity = $field->getParent(); + $entity = $this->parent->getEntity(); $this->value = node_mark($entity->nid->target_id, $entity->changed->value); } return $this->value; diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php index 443e509d918d44f49ed636b83fcc654c88e8a78b..6b3c1379e71fce444fdf9b004d46467ef6113653 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigEntityReferenceItemBase.php @@ -147,8 +147,7 @@ public function getSettableOptions() { if (function_exists($callback)) { // We are at the field item level, so we need to go two levels up to get // to the entity object. - $entity = $this->getParent()->getParent(); - return $callback($this->getFieldDefinition(), $entity); + return $callback($this->getFieldDefinition(), $this->getEntity()); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php index eb2e4dbbf792100e9aacb8c6ee25edb075824cb7..2eb001334603c0eed29efe7b51d2f9bb5f7f90bc 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/FieldType/ConfigField.php @@ -37,8 +37,9 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface * {@inheritdoc} */ public function getFieldDefinition() { - if (!isset($this->instance) && $parent = $this->getParent()) { - $instances = FieldAPI::fieldInfo()->getBundleInstances($parent->entityType(), $parent->bundle()); + if (!isset($this->instance)) { + $entity = $this->getEntity(); + $instances = FieldAPI::fieldInfo()->getBundleInstances($entity->entityType(), $entity->bundle()); $this->instance = $instances[$this->getName()]; } return $this->instance; @@ -69,7 +70,7 @@ public function getConstraints() { * {@inheritdoc} */ protected function getDefaultValue() { - return $this->getFieldDefinition()->getFieldDefaultValue($this->getParent()); + return $this->getFieldDefinition()->getFieldDefaultValue($this->getEntity()); } /** @@ -77,12 +78,11 @@ protected function getDefaultValue() { */ public function defaultValuesForm(array &$form, array &$form_state) { if (empty($this->getFieldDefinition()->default_value_function)) { - $entity = $this->getParent(); $widget = $this->defaultValueWidget($form_state); // Place the input in a separate place in the submitted values tree. $element = array('#parents' => array('default_value_input')); - $element += $widget->form($entity, $entity->language()->id, $this, $element, $form_state); + $element += $widget->form($this->getEntity(), $this->getLangcode(), $this, $element, $form_state); return $element; } @@ -92,11 +92,11 @@ public function defaultValuesForm(array &$form, array &$form_state) { * {@inheritdoc} */ public function defaultValuesFormValidate(array $element, array &$form, array &$form_state) { - $entity = $this->getParent(); - $langcode = $entity->language()->id; - $widget = $this->defaultValueWidget($form_state); + $entity = $this->getEntity(); + $langcode = $this->getLangcode(); // Extract the submitted value, and validate it. + $widget = $this->defaultValueWidget($form_state); $widget->extractFormValues($entity, $langcode, $this, $element, $form_state); $violations = $this->validate(); @@ -116,12 +116,9 @@ public function defaultValuesFormValidate(array $element, array &$form, array &$ * {@inheritdoc} */ public function defaultValuesFormSubmit(array $element, array &$form, array &$form_state) { - $entity = $this->getParent(); - $langcode = $entity->language()->id; - $widget = $this->defaultValueWidget($form_state); - // Extract the submitted value, and return it as an array. - $widget->extractFormValues($entity, $langcode, $this, $element, $form_state); + $widget = $this->defaultValueWidget($form_state); + $widget->extractFormValues($this->getEntity(), $this->getLangcode(), $this, $element, $form_state); return $this->getValue(); } @@ -136,7 +133,7 @@ public function defaultValuesFormSubmit(array $element, array &$form, array &$fo */ protected function defaultValueWidget(array &$form_state) { if (!isset($form_state['default_value_widget'])) { - $entity = $this->getParent(); + $entity = $this->getEntity(); // Force a non-required widget. $this->getFieldDefinition()->required = FALSE; diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php index ce171badf369552cd95d506637bfdecba60d14d8..f99b0c61204c18150d11dda589ac4f315e0512a2 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigField.php @@ -7,7 +7,6 @@ namespace Drupal\field\Plugin\field\field_type; -use Drupal\Core\Entity\EntityInterface; use Drupal\field\Plugin\Type\FieldType\ConfigField; use Drupal\field\FieldInstanceInterface; use Symfony\Component\Validator\ConstraintViolation; @@ -40,8 +39,7 @@ public function validate() { $legacy_errors = array(); $this->legacyCallback('validate', array(&$legacy_errors)); - $entity = $this->getParent(); - $langcode = $entity->language()->id; + $langcode = $this->getLangcode(); $field_name = $this->getFieldDefinition()->getFieldName(); if (isset($legacy_errors[$field_name][$langcode])) { @@ -108,19 +106,16 @@ protected function legacyCallback($hook, $args = array()) { $module = $definition['provider']; $callback = "{$module}_field_{$hook}"; if (function_exists($callback)) { - $entity = $this->getParent(); - $langcode = $entity->language()->id; - // We need to remove the empty "prototype" item here. // @todo Revisit after http://drupal.org/node/1988492. $this->filterEmptyValues(); - // Legcacy callbacks alter $items by reference. + // Legacy callbacks alter $items by reference. $items = (array) $this->getValue(TRUE); $args = array_merge(array( - $entity, + $this->getEntity(), $this->getFieldInstance()->getField(), $this->getFieldInstance(), - $langcode, + $this->getLangcode(), &$items ), $args); call_user_func_array($callback, $args); diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php index 10fa23d36978ec2d507127218925f5f26251037b..e46622fb7422622b1d4e2c195b0182f12d954fed 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php +++ b/core/modules/field/lib/Drupal/field/Plugin/field/field_type/LegacyConfigFieldItem.php @@ -88,8 +88,7 @@ public function instanceSettingsForm(array $form, array &$form_state) { */ public function prepareCache() { if ($callback = $this->getLegacyCallback('load')) { - $entity = $this->getParent()->getParent(); - $langcode = $entity->language()->id; + $entity = $this->getEntity(); $entity_id = $entity->id(); // hook_field_load() receives items keyed by entity id, and alters then by @@ -100,7 +99,7 @@ public function prepareCache() { array($entity_id => $entity), $this->getFieldInstance()->getField(), array($entity_id => $this->getFieldInstance()), - $langcode, + $this->getLangcode(), &$items, EntityStorageControllerInterface::FIELD_LOAD_CURRENT, ); @@ -120,8 +119,7 @@ public function getSettableOptions() { $definition = $this->getPluginDefinition(); $callback = "{$definition['provider']}_options_list"; if (function_exists($callback)) { - $entity = $this->getParent()->getParent(); - return $callback($this->getFieldDefinition(), $entity); + return $callback($this->getFieldDefinition(), $this->getEntity()); } } diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php index 71436543cf7fef5e80c883088d9634b64194b9ad..a4f54f0d85d2f8c5e2787a30e68f2106e606e888 100644 --- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php +++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityReferenceItemNormalizer.php @@ -47,7 +47,7 @@ public function normalize($field_item, $format = NULL, array $context = array()) // entity so that the items are properly added to the _links and _embedded // objects. $field_name = $field_item->getParent()->getName(); - $entity = $field_item->getRoot(); + $entity = $field_item->getEntity(); $field_uri = $this->linkManager->getRelationUri($entity->entityType(), $entity->bundle(), $field_name); return array( '_links' => array( diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php index 725fca35b097757b328ed4fcec5e56d642887b36..71d6672976953e23541bdc1abfb66a9a0037ee33 100644 --- a/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php +++ b/core/modules/hal/lib/Drupal/hal/Normalizer/FieldNormalizer.php @@ -31,7 +31,7 @@ public function normalize($field, $format = NULL, array $context = array()) { $normalized_field_items = array(); // Get the field definition. - $entity = $field->getParent(); + $entity = $field->getEntity(); $field_name = $field->getName(); $field_definition = $entity->getPropertyDefinition($field_name); diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php index f218438b86947c5bd33a6112e5814d2d1ded27c5..5081195f568b5ceaedf83b2db453c856c45f1c61 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php @@ -143,7 +143,7 @@ protected function getOptions(FieldItemInterface $item) { $module_handler = \Drupal::moduleHandler(); $context = array( 'fieldDefinition' => $this->fieldDefinition, - 'entity' => $item->getParent()->getParent(), + 'entity' => $item->getEntity(), ); $module_handler->alter('options_list', $options, $context); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 12de782c73555903d91f53623736b5b891ed6337..ebc328dacd89e471a10e53119bbf8218a38d9280 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -391,12 +391,14 @@ protected function checkIntrospection($entity_type) { $field = $entity->user_id; $this->assertIdentical($field->getRoot(), $entity, 'Entity is root object.'); + $this->assertIdentical($field->getEntity(), $entity, 'getEntity() returns the entity.'); $this->assertEqual($field->getPropertyPath(), 'user_id'); $this->assertEqual($field->getName(), 'user_id'); $this->assertIdentical($field->getParent(), $entity, 'Parent object matches.'); $field_item = $field[0]; $this->assertIdentical($field_item->getRoot(), $entity, 'Entity is root object.'); + $this->assertIdentical($field_item->getEntity(), $entity, 'getEntity() returns the entity.'); $this->assertEqual($field_item->getPropertyPath(), 'user_id.0'); $this->assertEqual($field_item->getName(), '0'); $this->assertIdentical($field_item->getParent(), $field, 'Parent object matches.'); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php index e651e8bdce1c4b0667a9ea00f7c16e5078ae7cd7..21a3a2c76a1cddcd15d7fe904ff749945c41305a 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php @@ -75,7 +75,7 @@ public function formElement(FieldInterface $items, $delta, array $element, $lang '#default_value' => taxonomy_implode_tags($tags), '#autocomplete_route_name' => $this->getSetting('autocomplete_route_name'), '#autocomplete_route_parameters' => array( - 'entity_type' => $items->getParent()->entityType(), + 'entity_type' => $items->getEntity()->entityType(), 'field_name' => $this->fieldDefinition->getFieldName(), ), '#size' => $this->getSetting('size'),