headless_cms-1.0.3/modules/headless_cms_preview/headless_cms_preview.module

modules/headless_cms_preview/headless_cms_preview.module
<?php

/**
 * @file
 * Module file.
 */

declare(strict_types=1);

include_once 'headless_cms_preview.basefields.inc';

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\ContentEntityFormInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\headless_cms\HeadlessCmsUtility;
use Drupal\headless_cms_preview\Event\HeadlessPreviewUpdatedEvent;

/**
 * Implements hook_entity_base_field_info().
 */
function headless_cms_preview_entity_base_field_info(EntityTypeInterface $entity_type) {
  $fields = [];

  if ($entity_type->id() === 'consumer') {
    $fields = array_merge($fields, headless_cms_preview_consumer_basefields_01());
  }

  return $fields;
}

/**
 * Implements hook_entity_access().
 */
function headless_cms_preview_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
  /** @var \Drupal\headless_cms_preview\PreviewToken\PreviewToken|null $previewToken */
  $previewToken = \Drupal::service('headless_cms_preview.preview_token_negotiator')->negotiateFromRequest();
  if (!$previewToken) {
    return AccessResult::neutral();
  }

  $entityMatchesToken = $entity->getEntityTypeId() === $previewToken->entityTypeId && $entity->uuid() === $previewToken->entityUuid;

  // Allow view and update operations for the previewed entity.
  if ($operation === "update" && $entityMatchesToken) {
    return AccessResult::allowed()->setCacheMaxAge(0);
  }
  if ($operation === "view" && $entityMatchesToken) {
    return AccessResult::allowed()->setCacheMaxAge(0);
  }
  if ($operation === "view all revisions" && $entityMatchesToken) {
    return AccessResult::allowed()->setCacheMaxAge(0);
  }

  // Check referenced child entities.
  // If an entity (e.g. a paragraph) has the parent info set,
  // allow access to it, if it matches the parent in the preview token.
  if ($entity instanceof ContentEntityInterface) {
    if ($entity->hasField('parent_type') && $entity->get('parent_type')->getString() === $previewToken->entityTypeId && $entity->hasField('parent_id') && $entity->get("parent_id")->getString() === $previewToken->entityId) {
      return AccessResult::allowed()->setCacheMaxAge(0);
    }
  }

  // Fallback.
  return AccessResult::neutral();
}

/**
 * Implements hook_entity_access().
 *
 * @todo Evaluate if needed.
 */
function headless_cms_preview_entity_create_access_disabled(AccountInterface $account, array $context, $entity_bundle) {
  /** @var \Drupal\headless_cms_preview\PreviewToken\PreviewToken|null $previewToken */
  $previewToken = \Drupal::service('headless_cms_preview.preview_token_negotiator')->negotiateFromRequest();
  if (!$previewToken) {
    return AccessResult::neutral();
  }

  if ($entity_bundle === $previewToken->entityTypeBundle) {
    return AccessResult::allowed()->setCacheMaxAge(0);
  }

  // Fallback.
  return AccessResult::neutral();
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Add consumer specific form alterations.
 */
function headless_cms_preview_form_consumer_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
  HeadlessCmsUtility::alterConsumerForm($form);

  $form['additional_settings']['headless_cms_settings']['preview_settings'] = [
    '#type' => 'details',
    '#title' => new TranslatableMarkup('Preview'),
    '#open' => TRUE,

    'headless_cms_preview_url' => $form['headless_cms_preview_url'],
    'headless_cms_revision_url' => $form['headless_cms_revision_url'],
  ];

  unset($form['headless_cms_preview_url']);
  unset($form['headless_cms_revision_url']);
}

/**
 * Implements hook_form_alter().
 *
 * We want to add the preview button to the node edit form.
 */
function headless_cms_preview_form_alter(&$form, FormStateInterface &$form_state, $form_id) {
  $config = \Drupal::config('headless_cms_preview.settings');
  $enabledBundles = $config->get('enabled_bundles');

  $formIds = [];
  foreach ($enabledBundles as $bundle) {
    $formIds[] = "node_{$bundle}_form";
    $formIds[] = "node_{$bundle}_edit_form";
  }

  if (in_array($form_id, $formIds)) {
    $hasPreview = isset($form_state->getStorage()['has_been_previewed']);
    $formObject = $form_state->getFormObject();

    if (!$formObject instanceof ContentEntityFormInterface) {
      return;
    }

    $entity = $formObject->getEntity();
    // @phpstan-ignore property.notFound
    $previewMode = $entity->type?->entity?->getPreviewMode();

    $form['#attached']['library'][] = 'headless_cms_preview/save_preview_persistence';

    if ($hasPreview && $formObject instanceof ContentEntityFormInterface) {
      $currentUserId = \Drupal::currentUser()->id();

      $tokenValue = \Drupal::service('headless_cms_preview.preview_token_manager')->encode(
        $currentUserId,
        $entity->uuid(),
        $entity->getEntityTypeId(),
        $entity->bundle(),
      );

      $manager = \Drupal::service('headless_cms_preview.consumer_headless_preview_manager');
      $urls = $manager->getPreviewUrlsForAllConsumers($entity->getEntityTypeId(), $entity->bundle(), $entity->uuid(), $tokenValue);

      $form['headless_preview'] = [
        '#type' => 'details',
        '#title' => 'Preview',
        '#group' => 'advanced',
        '#open' => TRUE,

        'urls' => [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#prefix' => Markup::create(vsprintf('<strong>%s</strong>', [
            new TranslatableMarkup('Preview URLs:'),
          ])),

          'jsonapi' => [
            '#type' => 'markup',
            '#markup' => vsprintf('<div><a href="%s/%s/%s/%s/%s/preview" target="_blank">%s ⧉</a></div>', [
              \Drupal::request()->getSchemeAndHttpHost(),
              'jsonapi',
              $entity->getEntityTypeId(),
              $entity->bundle(),
              $entity->uuid(),
              new TranslatableMarkup('JSON:API'),
            ]),
          ],
        ],

        'token_value' => [
          '#type' => 'markup',
          '#markup' => Markup::create(vsprintf('<div style="margin-top: 15px"><div><strong>%s</strong></div><input class="form-text form-element form-element--type-text" id="preview-token-value" value="%s" readonly />', [
            new TranslatableMarkup('Preview Token:'),
            $tokenValue,
          ])),
          '#weight' => 10,
        ],
      ];

      foreach ($urls as $label => $url) {
        $form['headless_preview']['urls'][$label] = [
          '#type' => 'markup',
          '#markup' => "<div><a href='{$url}' target='_blank'>{$label} ⧉</a></div>",
        ];
      }
    }

    $form['actions']['save_preview'] = [
      '#type' => 'submit',
      '#access' => $previewMode != DRUPAL_DISABLED && ($entity->access('create') || $entity->access('update')),
      '#value' => new TranslatableMarkup('Save Preview'),
      '#weight' => 20,
      '#submit' => [
        '::submitForm',
        '::preview',
        '_headless_cms_preview_form_save_preview_submit',
      ],
      '#gin_action_item' => TRUE,
    ];
  }

}

/**
 * Reload the page for headless previews.
 */
function _headless_cms_preview_form_save_preview_submit(&$form, FormStateInterface $form_state) {
  $formObj = $form_state->getFormObject();
  $eventDispatcher = \Drupal::service('event_dispatcher');

  if ($formObj instanceof EntityFormInterface) {
    $entity = $formObj->getEntity();
    $query_options = ['query' => ['uuid' => $entity->uuid()]];
    $toUrl = $entity->isNew() ? Url::fromRoute('node.add', ['node_type' => $entity->bundle()], $query_options) : $entity->toUrl('edit-form', $query_options);

    if ($destination = \Drupal::request()->query->get('destination')) {
      $toUrl->setRouteParameter("destination", $destination);
    }

    \Drupal::request()->query->remove('destination');
    $form_state->setRedirectUrl($toUrl);

    // Dispatch event.
    $event = new HeadlessPreviewUpdatedEvent($entity, \Drupal::currentUser());
    $eventDispatcher->dispatch($event, $event::EVENT_NAME);
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc