Cannot access parent entity in hook_entity_create

Created on 21 December 2021, over 2 years ago
Updated 9 August 2023, 11 months ago

Problem/Motivation

When creating a hook_entity_create to eg. set default values based on contextual info like the parent entity, we don't have access to the parent entity. That's because the parent_type, parent_id and parent_field_name fields aren't being passed to EntityStorageInterface::create when creating the widget, they are set using a setter immediately afterwards (code)

Steps to reproduce

Add hook_entity_create to a custom module and try to access the host entity using $entity->getParentEntity().

Proposed resolution

Pass the parent_type, parent_id and parent_field_name fields to the values array instead of setting them after the entity is created.

πŸ› Bug report
Status

Needs review

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium DieterHolvoet Brussels

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¦πŸ‡ΊAustralia silverham

    +1 to this. I also have issues loading the temporary parent node entity in hook_field_widget_single_element_form_alter()

    This work around for now is to use : $node = $parent_entity = $form_state->getFormObject()->getEntity();

    Sample code below shows how to set the form default values as you enter paragraphs depending on how many.

    
    /**
     * Implements hook_field_widget_single_element_PLUGIN_ID_form_alter().
     *
     * @see \Drupal\Core\Field\WidgetBase::formSingleElement()
     */
    function my_module_field_widget_single_element_string_textfield_form_alter(array &$element, FormStateInterface $form_state, array $context) {
      $field_name = $context['items']->getName();
      $default_value = 'My default value to compare';
      if (($field_name == 'field_my_text_field')
        && ($context['items']->getEntity()->getEntityTypeId() == 'paragraph')
        && ($context['items']->getEntity()->bundle() == 'my_paragraph_type')) {
        $field_parents_no_subform = array_slice($element['#field_parents'], 0, -2);
        $parent_field_name = end($field_parents_no_subform);
        // Don't use $context['items']->getEntity()->getParentEntity()
        // it gets the current database node not the form temp node.
        // @see https://www.drupal.org/project/paragraphs/issues/3255456
        $parent_entity = $form_state->getFormObject()->getEntity();
        // Change new fields default to empty, by 
        if ($parent_entity->hasField($parent_field_name)) {
          $values = $parent_entity->get($parent_field_name)->getValue();
          if ((count($values) > 1) && ($element['value']['#default_value'] == $default_value)) {
            $element['value']['#default_value'] = '';
          }
        }
        // Change existing fields from default to empty.
        $input = $form_state->getUserInput();
        if (isset($input[$parent_field_name])) {
          $field_structure = array_merge(
            $element['#field_parents'],
            [
              $field_name,
              '0',
              'value',
            ]
          );
          // Get Value at
          // $input['field_parent'][$context['delta']]['subform'][$field_name]['0']['value'];.
          $current_value = NestedArray::getValue($input, $field_structure);
          if ($current_value == $default_value) {
            NestedArray::setValue($input, $field_structure, '');
            $form_state->setUserInput($input);
          }
        }
      }
    }
    
  • πŸ‡³πŸ‡±Netherlands Maico de Jong

    Had the same "issue" when trying to alter the paragraphs field options in the allowed_values_function callback based on the parent entity. (node)

    MR 46 worked great

Production build 0.69.0 2024