You are here

function layout_paragraphs_paragraph_presave in Layout Paragraphs 2.0.x

Same name and namespace in other branches
  1. 1.0.x layout_paragraphs.module \layout_paragraphs_paragraph_presave()

Implements hook_ENTITY_presave().

Updates references to parent layout section uuids in cases where paragraphs are duplicated, for example when using the Replicate module.

@todo Consider changing approach if this issue is addressed in core: https://www.drupal.org/project/drupal/issues/3040556 (It is not possible to react to an entity being duplicated)

File

./layout_paragraphs.module, line 129
Contains layout_paragraphs.module.

Code

function layout_paragraphs_paragraph_presave(Paragraph $paragraph) {
  $behavior_settings = $paragraph
    ->getAllBehaviorSettings();
  $parent_uuid = $behavior_settings['layout_paragraphs']['parent_uuid'] ?? NULL;
  if (empty($parent_uuid)) {
    return;
  }

  // If there is no host, the parent hasn't been saved and we are not cloning.
  $host = $paragraph
    ->getParentEntity();
  if (empty($host)) {
    return;
  }

  // If the parent component cannot be loaded, we are not cloning.
  $parent_component = \Drupal::service('entity.repository')
    ->loadEntityByUuid('paragraph', $parent_uuid);
  if (empty($parent_component)) {
    return;
  }

  // If the parent component does not have a parent entity, we are not cloning.
  $parent_host = $parent_component
    ->getParentEntity();
  if (empty($parent_host)) {
    return;
  }

  // If the current paragraph's host's id does not match
  // the paragraph's parent's host's id, we ARE cloning.
  if ($host
    ->id() !== $parent_host
    ->id()) {

    // Map the UUIDs to deltas from the clone source.
    $items = _layout_paragraphs_get_paragraphs($parent_component);
    foreach ($items as $delta => $item) {
      $uuid_map[$item
        ->uuid()] = $delta;
    }

    // Map the deltas to UUIds from the clone destination.
    $items = _layout_paragraphs_get_paragraphs($paragraph);
    $delta_map = [];
    foreach ($items as $delta => $item) {
      $delta_map[$delta] = $item
        ->uuid();
    }

    // Assign the correct uuid.
    $parent_delta = $uuid_map[$parent_uuid];
    $correct_uuid = $delta_map[$parent_delta];

    // Since paragraph::preSave() has already been called,
    // we have to set the serialized behavior settings directly
    // rather than using setBehaviorSettings().
    $behavior_settings['layout_paragraphs']['parent_uuid'] = $correct_uuid;
    $paragraph
      ->set('behavior_settings', serialize($behavior_settings));
  }
}