You are here

public function EntityReferenceHierarchy::postSave in Entity Reference Hierarchy 3.x

Same name and namespace in other branches
  1. 8.2 src/Plugin/Field/FieldType/EntityReferenceHierarchy.php \Drupal\entity_hierarchy\Plugin\Field\FieldType\EntityReferenceHierarchy::postSave()

Defines custom post-save behavior for field values.

This method is called during the process of saving an entity, just after values are written into storage. This is useful mostly when the business logic to be implemented always requires the entity identifier, even when storing a new entity. For instance, when implementing circular entity references, the referenced entity will be created on pre-save with a dummy value for the referring entity identifier, which will be updated with the actual one on post-save.

In the rare cases where item properties depend on the entity identifier, massaging logic will have to be implemented on post-save and returning TRUE will allow them to be rewritten to the storage with the updated values.

Parameters

bool $update: Specifies whether the entity is being updated or created.

Return value

bool Whether field items should be rewritten to the storage as a consequence of the logic implemented by the custom behavior.

Overrides FieldItemBase::postSave

File

src/Plugin/Field/FieldType/EntityReferenceHierarchy.php, line 122

Class

EntityReferenceHierarchy
Plugin implementation of the 'entity_reference_hierarchy' field type.

Namespace

Drupal\entity_hierarchy\Plugin\Field\FieldType

Code

public function postSave($update) {
  if (\Drupal::state()
    ->get('entity_hierarchy_disable_writes', FALSE)) {
    return;
  }

  // Get the key factory and tree storage services.
  $nodeKeyFactory = $this
    ->getNodeKeyFactory();
  $storage = $this
    ->getTreeStorage();

  // Get the field name.
  $fieldDefinition = $this
    ->getFieldDefinition();
  $fieldName = $fieldDefinition
    ->getName();
  $entityTypeId = $fieldDefinition
    ->getTargetEntityTypeId();
  $this
    ->lockTree($fieldName, $entityTypeId);

  // Get the parent/child entities and their node-keys in the nested set.
  $parentEntity = $this
    ->get('entity')
    ->getValue();
  if (!$parentEntity) {

    // Parent entity has been deleted.
    // If this node was in the tree, it needs to be moved to a root node.
    $stubNode = $nodeKeyFactory
      ->fromEntity($this
      ->getEntity());
    if (($existingNode = $storage
      ->getNode($stubNode)) && $existingNode
      ->getDepth() > 0) {
      $storage
        ->moveSubTreeToRoot($existingNode);
    }
    $this
      ->releaseLock($fieldName, $entityTypeId);
    return;
  }
  $parentKey = $nodeKeyFactory
    ->fromEntity($parentEntity);
  $childEntity = $this
    ->getEntity();
  $childKey = $nodeKeyFactory
    ->fromEntity($childEntity);

  // Determine if this is a new node in the tree.
  $isNewNode = FALSE;
  if (!($childNode = $storage
    ->getNode($childKey))) {
    $isNewNode = TRUE;

    // As we're going to be adding instead of moving, a key is all we require.
    $childNode = $childKey;
  }

  // Does the parent already exist in the tree.
  if ($existingParent = $storage
    ->getNode($parentKey)) {

    // If there are no siblings, we simply insert/move below.
    $insertPosition = new InsertPosition($existingParent, $isNewNode, InsertPosition::DIRECTION_BELOW);

    // But if there are siblings, we need to ascertain the correct position in
    // the order.
    if ($siblingEntities = $this
      ->getSiblingEntityWeights($storage, $existingParent, $childNode)) {

      // Group the siblings by their weight.
      $weightOrderedSiblings = $this
        ->groupSiblingsByWeight($siblingEntities, $fieldName);
      $weight = $this
        ->get('weight')
        ->getValue();
      $insertPosition = $this
        ->getInsertPosition($weightOrderedSiblings, $weight, $isNewNode) ?: $insertPosition;
    }
    $insertPosition
      ->performInsert($storage, $childNode);
    $this
      ->releaseLock($fieldName, $entityTypeId);
    return;
  }

  // We need to create a node for the parent in the tree.
  $parentNode = $storage
    ->addRootNode($parentKey);
  (new InsertPosition($parentNode, $isNewNode, InsertPosition::DIRECTION_BELOW))
    ->performInsert($storage, $childNode);
  $this
    ->releaseLock($fieldName, $entityTypeId);
}