You are here

function geysir_preprocess_field in Geysir 8

Implements hook_preprocess_HOOK().

Using hook_preprocess_field().

File

./geysir.module, line 140
Geysir module file.

Code

function geysir_preprocess_field(&$vars) {
  if (empty($vars['field_type']) || $vars['field_type'] !== 'entity_reference_revisions') {
    return;
  }

  // Do not apply Geysir on Admin routes. This avoids rendering the buttons
  // when a paragraph is set to preview in form mode.
  // At the same time check if the admin route is not a Geysir route.
  $route = \Drupal::routeMatch()
    ->getRouteName();
  if (\Drupal::service('router.admin_context')
    ->isAdminRoute() && strpos($route, 'geysir.') !== 0) {
    return;
  }
  $element =& $vars['element'];

  /** @var Drupal\Core\Entity\FieldableEntityInterface $parent */
  $parent = $element['#object'];

  // Skip nested paragraphs.
  if (!$parent instanceof NodeInterface) {
    return;
  }

  // Check update access for current node + permission to use Geysir.
  if (!$parent
    ->isLatestRevision() || !$parent
    ->access('update') || !\Drupal::currentUser()
    ->hasPermission('geysir manage paragraphs from front-end')) {
    return;
  }

  /** @var Drupal\entity_reference_revisions\EntityReferenceRevisionsFieldItemList $field */
  $field = $element['#items'];
  $field_definition = $field
    ->getFieldDefinition();
  $field_storage_definition = $field_definition
    ->getFieldStorageDefinition();
  if ($field_storage_definition
    ->getSetting('target_type') !== 'paragraph') {
    return;
  }
  $can_add_more_fields = $field_storage_definition
    ->getCardinality() == -1 || count($vars['items']) < $field_storage_definition
    ->getCardinality();
  $field_wrapper_id = Html::getUniqueId('geysir--' . $vars['field_name']);
  $langcode = Drupal::languageManager()
    ->getCurrentLanguage()
    ->getId();
  $translated_parent = FALSE;
  $non_paragraph_parent = geysir_get_non_paragraph_parent($parent);
  if ($non_paragraph_parent
    ->isTranslatable()) {
    $parent_translation = Drupal::service('entity.repository')
      ->getTranslationFromContext($non_paragraph_parent);
    $translated_parent = !$parent_translation
      ->isDefaultTranslation();
  }
  $delta = 0;
  while (!empty($element[$delta])) {
    $links = [];

    /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
    $paragraph = $element[$delta]['#paragraph'];
    $paragraph_to_cut = $paragraph;

    // Use the parent revision id if available, otherwise the parent id.
    $parent_revision_id = $parent
      ->getRevisionId() ? $parent
      ->getRevisionId() : $parent
      ->id();
    if (!$translated_parent && $can_add_more_fields) {

      // Add link - before.
      $links['add_before'] = [
        'title' => t('Add before'),
        'url' => Url::fromRoute('geysir.modal.add_form', [
          'parent_entity_type' => $parent
            ->getEntityType()
            ->id(),
          'parent_entity_bundle' => $parent
            ->bundle(),
          'parent_entity_revision' => $parent_revision_id,
          'field' => $vars['field_name'],
          'field_wrapper_id' => $field_wrapper_id,
          'delta' => $delta,
          'paragraph' => $paragraph
            ->id(),
          'paragraph_revision' => $paragraph
            ->getRevisionId(),
          'position' => 'before',
          'js' => 'nojs',
        ]),
        'attributes' => [
          'class' => [
            'use-ajax',
            'geysir-button',
          ],
          'data-dialog-type' => 'modal',
          'title' => t('Add before'),
        ],
      ];

      // Add link - after.
      $links['add_after'] = [
        'title' => t('Add after'),
        'url' => Url::fromRoute('geysir.modal.add_form', [
          'parent_entity_type' => $parent
            ->getEntityType()
            ->id(),
          'parent_entity_bundle' => $parent
            ->bundle(),
          'parent_entity_revision' => $parent_revision_id,
          'field' => $vars['field_name'],
          'field_wrapper_id' => $field_wrapper_id,
          'delta' => $delta,
          'paragraph' => $paragraph
            ->id(),
          'paragraph_revision' => $paragraph
            ->getRevisionId(),
          'position' => 'after',
          'js' => 'nojs',
        ]),
        'attributes' => [
          'class' => [
            'use-ajax',
            'geysir-button',
          ],
          'data-dialog-type' => 'modal',
          'title' => t('Add after'),
        ],
      ];
    }

    // Edit link.
    $links['edit'] = [
      'title' => t('Edit'),
      'url' => Url::fromRoute('geysir.modal.edit_form', [
        'parent_entity_type' => $parent
          ->getEntityType()
          ->id(),
        'parent_entity_bundle' => $parent
          ->bundle(),
        'parent_entity_revision' => $parent_revision_id,
        'field' => $vars['field_name'],
        'field_wrapper_id' => $field_wrapper_id,
        'delta' => $delta,
        'paragraph' => $paragraph
          ->id(),
        'paragraph_revision' => $paragraph
          ->getRevisionId(),
        'js' => 'nojs',
      ]),
      'attributes' => [
        'class' => [
          'use-ajax',
          'geysir-button',
        ],
        'data-dialog-type' => 'modal',
        'title' => t('Edit'),
      ],
    ];
    if ($translated_parent) {
      if ($paragraph
        ->isDefaultTranslation()) {
        $links['edit'] = [
          'title' => t('Translate'),
          'url' => Url::fromRoute('geysir.modal.translate_form', [
            'parent_entity_type' => $parent
              ->getEntityType()
              ->id(),
            'parent_entity_bundle' => $parent
              ->bundle(),
            'parent_entity_revision' => $parent_revision_id,
            'field' => $vars['field_name'],
            'field_wrapper_id' => $field_wrapper_id,
            'delta' => $delta,
            'paragraph' => $paragraph
              ->id(),
            'paragraph_revision' => $paragraph
              ->getRevisionId(),
            'js' => 'nojs',
          ]),
          'attributes' => [
            'class' => [
              'use-ajax',
              'geysir-button',
            ],
            'data-dialog-type' => 'modal',
            'title' => t('Translate'),
          ],
        ];
      }
      if (!$paragraph
        ->isTranslatable()) {
        unset($links['edit']);
      }
    }
    if (!$translated_parent) {
      if (count($element['#items']) > 1) {

        // Cut link.
        $links['cut'] = [
          'title' => t('Cut'),
          'url' => Url::fromRoute('geysir.cut', [
            'parent_entity_type' => $parent
              ->getEntityType()
              ->id(),
            'parent_entity_bundle' => $parent
              ->bundle(),
            'parent_entity_revision' => $parent_revision_id,
            'field' => $vars['field_name'],
            'field_wrapper_id' => $field_wrapper_id,
            'delta' => $delta,
            'paragraph_to_cut' => $paragraph
              ->id(),
            'paragraph_revision' => $paragraph
              ->getRevisionId(),
            'js' => 'nojs',
          ]),
          'attributes' => [
            'data-geysir-field-paragraph-field-wrapper' => $field_wrapper_id,
            'class' => [
              'geysir-button',
            ],
            'data-dialog-type' => 'modal',
            'title' => t('Cut'),
          ],
        ];
      }

      // Delete link.
      $links['delete'] = [
        'title' => t('Delete'),
        'url' => Url::fromRoute('geysir.modal.delete_form', [
          'parent_entity_type' => $parent
            ->getEntityType()
            ->id(),
          'parent_entity_bundle' => $parent
            ->bundle(),
          'parent_entity_revision' => $parent_revision_id,
          'field' => $vars['field_name'],
          'field_wrapper_id' => $field_wrapper_id,
          'delta' => $delta,
          'paragraph' => $paragraph
            ->id(),
          'paragraph_revision' => $paragraph
            ->getRevisionId(),
          'js' => 'nojs',
        ]),
        'attributes' => [
          'class' => [
            'use-ajax',
            'geysir-button',
          ],
          'data-dialog-type' => 'modal',
          'title' => t('Delete'),
        ],
      ];
      if ($field_definition
        ->isRequired() && count($element['#items']) == 1) {
        $links['delete']['title'] = t('Cannot remove the last item of a required field');
        $links['delete']['url'] = Url::fromUserInput('#');
        $links['delete']['attributes']['class'][] = 'disabled';
        $links['delete']['attributes']['title'] = t('Cannot remove the last item of a required field');
      }

      // Paste link - before.
      $links['paste_before'] = [
        'title' => t('Paste'),
        'url' => Url::fromRoute('geysir.paste', [
          'parent_entity_type' => $parent
            ->getEntityType()
            ->id(),
          'parent_entity_bundle' => $parent
            ->bundle(),
          'parent_entity_revision' => $parent_revision_id,
          'field' => $vars['field_name'],
          'field_wrapper_id' => $field_wrapper_id,
          'delta' => $delta,
          'position' => 'before',
          'paragraph_revision' => $paragraph
            ->getRevisionId(),
          'paragraph_to_paste' => $paragraph_to_cut
            ->id(),
          'js' => 'nojs',
        ]),
        'attributes' => [
          'data-geysir-field-paragraph-field-wrapper' => $field_wrapper_id,
          'class' => [
            'use-ajax',
            'geysir-button',
            'geysir-paste',
          ],
          'data-dialog-type' => 'modal',
          'title' => t('Paste'),
        ],
      ];

      // Paste link - after.
      $links['paste_after'] = [
        'title' => t('Paste'),
        'url' => Url::fromRoute('geysir.paste', [
          'parent_entity_type' => $parent
            ->getEntityType()
            ->id(),
          'parent_entity_bundle' => $parent
            ->bundle(),
          'parent_entity_revision' => $parent_revision_id,
          'field' => $vars['field_name'],
          'field_wrapper_id' => $field_wrapper_id,
          'delta' => $delta,
          'position' => 'after',
          'paragraph_revision' => $paragraph
            ->getRevisionId(),
          'paragraph_to_paste' => $paragraph_to_cut
            ->id(),
          'js' => 'nojs',
        ]),
        'attributes' => [
          'data-geysir-field-paragraph-field-wrapper' => $field_wrapper_id,
          'class' => [
            'use-ajax',
            'geysir-button',
            'geysir-paste',
          ],
          'data-dialog-type' => 'modal',
          'title' => t('Paste'),
        ],
      ];
    }
    $context = [
      'paragraph' => $paragraph,
      'parent' => $parent,
      'delta' => $delta,
      'field_definition' => $field_definition,
    ];
    \Drupal::moduleHandler()
      ->alter('geysir_paragraph_links', $links, $context);
    $links_array = [
      '#theme' => 'links',
      '#links' => $links,
      '#attributes' => [
        'class' => [
          'geysir-field-paragraph-links',
          'links',
        ],
      ],
      '#attached' => [
        'library' => [
          'core/drupal.dialog.ajax',
          'geysir/geysir',
        ],
      ],
    ];
    $vars['items'][$delta]['content']['#theme_wrappers'][] = 'geysir_field_paragraph_wrapper';
    $vars['items'][$delta]['content']['#geysir_field_paragraph_links'] = Drupal::service('renderer')
      ->render($links_array);

    /** @var \Drupal\paragraphs\Entity\Paragraph $paragraph */
    $paragraph = $vars['items'][$delta]['content']['#paragraph'];
    if ($paragraph
      ->isTranslatable() && $paragraph
      ->hasTranslation($langcode)) {
      $vars['items'][$delta]['content']['#paragraph'] = $paragraph
        ->getTranslation($langcode);
    }
    $delta++;
  }

  // Attach the field wrapper ID in a data-attribute.
  $vars['attributes']['data-geysir-field-paragraph-field-wrapper'] = $field_wrapper_id;
}