diff --git a/core/lib/Drupal/Core/Entity/Field/Field.php b/core/lib/Drupal/Core/Entity/Field/Field.php index 3a0734b..6f8382a 100644 --- a/core/lib/Drupal/Core/Entity/Field/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Field.php @@ -59,6 +59,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface /** * {@inheritdoc} */ + public function getEntity() { + return $this->getParent(); + } + + /** + * {@inheritdoc} + */ public function setLangcode($langcode) { $this->langcode = $langcode; } diff --git a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php index 80b0412..4708418 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldInterface.php @@ -28,6 +28,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. * * @param string $langcode diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index 0ac0a5d..15744c0 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -39,6 +39,13 @@ public function __construct(array $definition, $name = NULL, TypedDataInterface /** * {@inheritdoc} */ + public function getEntity() { + return $this->getParent()->getEntity(); + } + + /** + * {@inheritdoc} + */ public function getLangcode() { return $this->parent->getLangcode(); } diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php index e1f5d51..71fc086 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemInterface.php @@ -24,6 +24,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. * * @return $langcode diff --git a/core/modules/comment/lib/Drupal/comment/CommentNewValue.php b/core/modules/comment/lib/Drupal/comment/CommentNewValue.php index 1295776..4398a1b 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 443e509..6b3c137 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 eb2e4db..2eb0013 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 ce171ba..f99b0c6 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 10fa23d..e46622f 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 7143654..a4f54f0 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 725fca3..71d6672 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/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php index 0479e38..99a1884 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Validation/Constraint/NodeChangedConstraintValidator.php @@ -20,9 +20,7 @@ class NodeChangedConstraintValidator 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 - // node object. - $node = $this->context->getMetadata()->getTypedData()->getParent()->getParent(); + $node = $this->context->getMetadata()->getTypedData()->getEntity(); $id = $node->id(); $language = $node->language(); if ($id && (node_last_changed($id, $language->id) > $value)) { 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 f218438..5081195 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 12de782..ebc328d 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 e651e8b..21a3a2c 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'), diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php b/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php index 417d354..7ad122a 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/field_type/TextItemBase.php @@ -78,7 +78,6 @@ public function prepareCache() { $text_processing = $this->getFieldSetting('text_processing'); if (!$text_processing || filter_format_allowcache($this->get('format')->getValue())) { $itemBC = $this->getValue(); - $langcode = $this->getParent()->getParent()->language()->id; // The properties that need sanitizing are the ones that are the 'text // source' of a TextProcessed computed property. // @todo Clean up this mess by making the TextProcessed property type @@ -86,7 +85,7 @@ public function prepareCache() { foreach ($this->getPropertyDefinitions() as $definition) { if (isset($definition['class']) && ($definition['class'] == '\Drupal\text\TextProcessed')) { $source_property = $definition['settings']['text source']; - $this->set('safe_' . $source_property, text_sanitize($text_processing, $langcode, $itemBC, $source_property)); + $this->set('safe_' . $source_property, text_sanitize($text_processing, $this->getLangcode(), $itemBC, $source_property)); } } } diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php index 352420d..91c16cd 100644 --- a/core/modules/text/lib/Drupal/text/TextProcessed.php +++ b/core/modules/text/lib/Drupal/text/TextProcessed.php @@ -66,11 +66,11 @@ public function getValue($langcode = NULL) { } $field = $this->parent->getParent(); - $entity = $field->getParent(); + $entity = $field->getEntity(); $instance = field_info_instance($entity->entityType(), $field->getName(), $entity->bundle()); if (!empty($instance['settings']['text_processing']) && $this->format->getValue()) { - return check_markup($this->text->getValue(), $this->format->getValue(), $entity->language()->id); + return check_markup($this->text->getValue(), $this->format->getValue(), $field->getLangcode()); } else { // If no format is available, still make sure to sanitize the text.