layout_builder_ipe-1.0.x-dev/src/Validation/Constraint/LayoutBuilderEntityChangedConstraintValidator.php

src/Validation/Constraint/LayoutBuilderEntityChangedConstraintValidator.php
<?php

namespace Drupal\layout_builder_ipe\Validation\Constraint;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraint;
use Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraintValidator;
use Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage;
use Drupal\layout_builder_ipe\LayoutBuilderIpeService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 * Validates the EntityChanged constraint.
 */
class LayoutBuilderEntityChangedConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {

  /**
   * The layout builder ipe service.
   *
   * @var \Drupal\layout_builder_ipe\LayoutBuilderIpeService
   */
  protected $layoutBuilderIpe;

  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * The current request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected $request;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Creates an LayoutBuilderEntityChangedConstraintValidator object.
   *
   * @param \Drupal\layout_builder_ipe\LayoutBuilderIpeService $layout_builder_ipe
   *   The layout builder IPE service.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack..
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   */
  public function __construct(LayoutBuilderIpeService $layout_builder_ipe, DateFormatterInterface $date_formatter, RequestStack $request_stack, EntityTypeManagerInterface $entity_type_manager) {
    $this->layoutBuilderIpe = $layout_builder_ipe;
    $this->dateFormatter = $date_formatter;
    $this->request = $request_stack->getCurrentRequest();
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container->get('layout_builder_ipe'), $container->get('date.formatter'), $container->get('request_stack'), $container->get('entity_type.manager'));
  }

  /**
   * {@inheritdoc}
   */
  public function validate($entity, Constraint $constraint) {
    if (isset($entity)) {
      /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
      if (!$entity->isNew()) {
        /** @var \Drupal\Core\Entity\ContentEntityInterface $saved_entity */
        $saved_entity = $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
        if ($this->layoutBuilderIpe->ipeEnabled($entity)) {
          // This is an entity that uses IPE.
          if ($this->layoutBuilderIpe->isLayoutBuilderIpeFormSubmission($entity)) {
            // This is a form submission from the layout builder form. All that
            // can be changed there is the layout, so all we need to check is if
            // the layout has changed.
            if ($this->hasLayoutChanges($saved_entity)) {
              // The layout has changed, so we add a violation.
              $placeholders = [
                '@updated' => $this->dateFormatter->format($saved_entity->getChangedTime()),
              ];
              $this->context->addViolation((string) (new FormattableMarkup($constraint->message, $placeholders)));
            }
          }
          else {
            // This is some other modification to the entity, presumably a
            // submission from the node edit form.
            if ($this->hasEntityChanges($saved_entity)) {
              // The entity has changed, so we add a violation.
              $entity_changed_constraint = new EntityChangedConstraint();
              $this->context->addViolation($entity_changed_constraint->message);
            }
          }
        }
        else {
          // This is an entity that doesn't use IPE, so we fall back to the
          // original EntityChanged constraint.
          $original_validator = new EntityChangedConstraintValidator();
          $original_validator->initialize($this->context);
          $original_validator->validate($entity, new EntityChangedConstraint());
        }
      }
    }
  }

  /**
   * See if the given entity has any layout changes.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   *
   * @return bool
   *   TRUE if the given entity has layout changes, FALSE otherwise.
   */
  public function hasLayoutChanges(EntityInterface $entity) {
    $original_hash = $this->request->get('layout_builder_ipe_layout_hash');
    if (empty($original_hash)) {
      return FALSE;
    }
    $section_storage = $this->layoutBuilderIpe->getSectionStorageForEntity($entity);
    if ($section_storage instanceof DefaultsSectionStorage) {
      // An edit to the default storage which will create an overridden storage
      // for the first time is a layout change, but shouldn't count, otherwise
      // layouts could never be customized.
      return FALSE;
    }
    $current_hash = $this->layoutBuilderIpe->hashLayout($section_storage);
    return $current_hash != $original_hash;
  }

  /**
   * See if the given entity has any entity changes (no layout).
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   *
   * @return bool
   *   TRUE if the given entity has entity changes, FALSE otherwise.
   */
  public function hasEntityChanges(EntityInterface $entity) {
    $original_hash = $this->request->get('layout_builder_ipe_entity_hash');
    if (empty($original_hash)) {
      return FALSE;
    }
    $current_hash = $this->layoutBuilderIpe->hashEntity($entity);
    return $current_hash != $original_hash;
  }

}

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

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