xero_sync-8.x-1.x-dev/src/XeroSyncEntityHandler.php

src/XeroSyncEntityHandler.php
<?php

namespace Drupal\xero_sync;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Drupal\xero_sync\Event\XeroSyncAppropriateEvent;
use Drupal\xero_sync\Event\XeroSyncEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Handles interaction with entities.
 *
 * It knows which field on an entity contains information identifying its
 * Xero item.
 *
 * Typically used in response to entity CRUD hooks, to
 * creates queue jobs for syncing entities with Xero items.
 */
class XeroSyncEntityHandler implements XeroSyncEntityHandlerInterface {

  use XeroSyncUtilitiesTrait;

  /**
   * The default name of the field that holds the synced Xero item's id.
   */
  const DEFAULT_FIELD_NAME = 'xero_sync';

  /**
   * The Xero Sync queue job manager.
   *
   * @var \Drupal\xero_sync\XeroSyncJobManagerInterface
   */
  protected $jobManager;

  /**
   * The Xero Sync synchronizer.
   *
   * @var \Drupal\xero_sync\XeroSyncSynchronizerInterface
   */
  protected $synchronizer;

  /**
   * The typed data manager.
   *
   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
   */
  protected $typedDataManager;

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

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * Constructs a new XeroSyncEntityHandler object.
   *
   * @param \Drupal\xero_sync\XeroSyncJobManagerInterface $job_manager
   *   The Xero Sync queue job manager.
   * @param \Drupal\xero_sync\XeroSyncSynchronizerInterface $synchronizer
   *   The Xero Sync synchronizer.
   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
   *   The typed data manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   The event dispatcher.
   */
  public function __construct(XeroSyncJobManagerInterface $job_manager, XeroSyncSynchronizerInterface $synchronizer, TypedDataManagerInterface $typed_data_manager, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher) {
    $this->jobManager = $job_manager;
    $this->synchronizer = $synchronizer;
    $this->typedDataManager = $typed_data_manager;
    $this->entityTypeManager = $entity_type_manager;
    $this->eventDispatcher = $event_dispatcher;
  }

  /**
   * {@inheritDoc}
   */
  public function handleInsert(EntityInterface $entity) {
    $this->syncIfAppropriate($entity);
  }

  /**
   * {@inheritDoc}
   */
  public function handleDelete(EntityInterface $entity) {
    $this->unsyncIfAppropriate($entity, NULL, NULL, TRUE);
  }

  /**
   * {@inheritDoc}
   */
  public function handleUpdate(EntityInterface $entity) {
    $field = $this->getSyncField($entity);
    if ($field) {
      $hasXeroId = !$field->isEmpty();

      if (!isset($entity->original)) {
        if ($hasXeroId) {
          $this->handleXeroIdPresent($entity);
          return;
        }
      }
      else {
        $originalField = $this->getSyncField($entity->original);
        $hadXeroId = !$originalField->isEmpty();

        if ($hadXeroId) {
          if (!$hasXeroId) {
            $this->handleXeroIdRemoved($entity);
            return;
          }
          $changedId = $field->first()->guid !== $originalField->first()->guid;
          $changedType = $field->first()->type !== $originalField->first()->type;
          if ($changedId || $changedType) {
            $this->handleXeroIdChanged($entity);
            return;
          }
          $this->handleXeroIdUnchanged($entity);
          return;
        }

        if ($hasXeroId) {
          $this->handleXeroIdAdded($entity);
          return;
        }
      }
    }

    $this->handleXeroIdAbsent($entity);
  }

  /**
   * {@inheritDoc}
   */
  public function getFieldName($entityType, $bundle = NULL) {
    return self::DEFAULT_FIELD_NAME;
  }

  /**
   * {@inheritDoc}
   */
  public function getAppropriatenessFlags(EntityInterface $entity) {
    $event = new XeroSyncAppropriateEvent($entity);
    $eventId = XeroSyncEvents::SYNC_IS_APPROPRIATE . "." . $entity->getEntityTypeId();
    $event = $this->eventDispatcher->dispatch($event, $eventId);
    return $event->getFlags();
  }

  /**
   * {@inheritDoc}
   */
  public function syncIfAppropriate(EntityInterface $entity, $create = NULL, $update = NULL) {
    // If create and update are not specified, use the event to determine if
    // they are appropriate.
    if (is_null($create) || is_null($update)) {
      $flags = $this->getAppropriatenessFlags($entity);
      $create = $create ?? $flags['create'];
      $update = $update ?? $flags['update'];
    }
    if ($create || $update) {
      $this->jobManager->queueEntitySync($entity, $create, $update);
    }
  }

  /**
   * {@inheritDoc}
   */
  public function unsyncIfAppropriate(EntityInterface $entity, $itemType = NULL, $itemId = NULL, $serialize_entity = FALSE) {
    // Even if the entity should not normally be synced, unsync it if a synced
    // item is specified.
    if (!is_null($itemId)) {
      $shouldUnsync = TRUE;
    }
    else {
      $flags = $this->getAppropriatenessFlags($entity);
      $shouldUnsync = $flags['update'];
    }

    // Even if the entity should not normally be synced, we should still unsync
    // it if it has previously been synced.
    if (!$shouldUnsync) {
      $field = $this->getSyncField($entity);
      if ($field) {
        $shouldUnsync = !$field->isEmpty();
      }
    }
    if ($shouldUnsync) {
      $this->jobManager->queueEntityUnsync($entity, $itemType, $itemId, $serialize_entity);
    }
  }

  /**
   * {@inheritDoc}
   */
  public function syncMultipleIfAppropriate($entity_type, $entity_ids = NULL, $create = NULL, $update = NULL) {
    $storage = $this->entityTypeManager->getStorage($entity_type);
    if (is_null($entity_ids)) {
      $query = $storage->getQuery()->accessCheck(FALSE);
      $entity_ids = $query->execute();
    }
    foreach ($entity_ids as $entity_id) {
      $entity = $storage->load($entity_id);
      $this->syncIfAppropriate($entity, $create, $update);
    }
  }

  /**
   * {@inheritDoc}
   */
  public function unsyncMultipleIfAppropriate($entity_type, $entity_ids = NULL, $serialize_entity = FALSE) {
    $storage = $this->entityTypeManager->getStorage($entity_type);
    if (is_null($entity_ids)) {
      $query = $storage->getQuery()->accessCheck(FALSE);
      $entity_ids = $query->execute();
    }
    foreach ($entity_ids as $entity_id) {
      $entity = $storage->load($entity_id);
      $this->unsyncIfAppropriate($entity, NULL, NULL, $serialize_entity);
    }
  }

  /**
   * Handle the case where the referenced synced item is different.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdChanged(FieldableEntityInterface $entity) {
    $itemType = $this->getSyncedItemType($entity->original);
    $itemId = $this->getSyncedItemGuid($entity->original);
    $this->unsyncIfAppropriate($entity, $itemType, $itemId);
    $this->syncIfAppropriate($entity);
  }

  /**
   * Handle the case where a synced item is still referenced.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdUnchanged(FieldableEntityInterface $entity) {
    $itemType = $this->getSyncedItemType($entity->original);
    $itemId = $this->getSyncedItemGuid($entity->original);
    $item = $this->buildXeroItemWithId($itemType, $itemId);
    $item->synced = TRUE;
    if ($this->synchronizer->isItemUpdateNeeded($entity, $item, $entity->original)) {
      $this->syncIfAppropriate($entity);
    }
  }

  /**
   * Handle the case where the synced item is no longer referenced.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdRemoved(FieldableEntityInterface $entity) {
    $itemType = $this->getSyncedItemType($entity->original);
    $itemId = $this->getSyncedItemGuid($entity->original);
    $this->unsyncIfAppropriate($entity, $itemType, $itemId);
  }

  /**
   * Handle the case where a synced item is newly referenced.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdAdded(FieldableEntityInterface $entity) {
    $this->syncIfAppropriate($entity);
  }

  /**
   * Handle where no synced item is/was referenced, or previous state unknown.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdAbsent(EntityInterface $entity) {
    $this->syncIfAppropriate($entity);
  }

  /**
   * Handle the case where a synced item is present but previous state unknown.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity.
   */
  protected function handleXeroIdPresent(EntityInterface $entity) {
    $this->syncIfAppropriate($entity);
  }

}

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

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