You are here

class SubscriberTracker in Acquia Content Hub 8.2

Subscriber Tracker database table methods.

Hierarchy

Expanded class hierarchy of SubscriberTracker

16 files declare their use of SubscriberTracker
AcquiaContentHubSubscriberAuditCommands.php in modules/acquia_contenthub_subscriber/src/Commands/AcquiaContentHubSubscriberAuditCommands.php
acquia_contenthub_unsubscribe.install in modules/acquia_contenthub_unsubscribe/acquia_contenthub_unsubscribe.install
Acquia Content Hub - Unsubscribe module install file.
acquia_contenthub_unsubscribe.module in modules/acquia_contenthub_unsubscribe/acquia_contenthub_unsubscribe.module
Drupal Module: Acquia Content Hub unsubscribe.
ContentHubImportQueueWorker.php in modules/acquia_contenthub_subscriber/src/Plugin/QueueWorker/ContentHubImportQueueWorker.php
DeleteAssets.php in modules/acquia_contenthub_subscriber/src/EventSubscriber/HandleWebhook/DeleteAssets.php

... See full list

1 string reference to 'SubscriberTracker'
acquia_contenthub_subscriber.services.yml in modules/acquia_contenthub_subscriber/acquia_contenthub_subscriber.services.yml
modules/acquia_contenthub_subscriber/acquia_contenthub_subscriber.services.yml
1 service uses SubscriberTracker
acquia_contenthub_subscriber.tracker in modules/acquia_contenthub_subscriber/acquia_contenthub_subscriber.services.yml
Drupal\acquia_contenthub_subscriber\SubscriberTracker

File

modules/acquia_contenthub_subscriber/src/SubscriberTracker.php, line 12

Namespace

Drupal\acquia_contenthub_subscriber
View source
class SubscriberTracker {
  use AcquiaContentHubStatusMetricsTrait;

  /**
   * The status used to indicate that a tracked item is to be reimported.
   */
  const QUEUED = 'queued';

  /**
   * The status used to indicate that a tracked item has been imported.
   */
  const IMPORTED = 'imported';

  /**
   * The status used to indicate an entity should no longer receive updates.
   */
  const AUTO_UPDATE_DISABLED = 'auto_update_disabled';

  /**
   * The name of the tracking table.
   */
  const IMPORT_TRACKING_TABLE = 'acquia_contenthub_subscriber_import_tracking';

  /**
   * PublisherTracker constructor.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database connection.
   */
  public function __construct(Connection $database) {
    $this->database = $database;
  }

  /**
   * Checks if a particular entity uuid is tracked.
   *
   * @param mixed $uuids
   *   The uuid of an entity.
   *
   * @return bool
   *   Whether or not the entity is tracked in the subscriber tables.
   */
  public function isTracked($uuids) {
    if (!is_array($uuids)) {
      $uuids = [
        $uuids,
      ];
    }
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't');
    $query
      ->fields('t', [
      'entity_type',
      'entity_id',
      'entity_uuid',
    ]);
    $query
      ->condition('entity_uuid', $uuids, 'IN');
    $results = $query
      ->execute()
      ->fetchAll();
    if (array_diff($uuids, array_column($results, 'entity_uuid'))) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Gets a list of uuids that are not yet tracked.
   *
   * @param string[] $uuids
   *   List of UUID strings.
   *
   * @return array
   *   The list of UUIDs of untracked entities.
   */
  public function getUntracked(array $uuids) {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t');
    $query
      ->condition('t.entity_uuid', $uuids, 'IN');
    $query
      ->condition('t.entity_id', NULL, 'IS NOT NULL');
    $results = $query
      ->execute();
    $uuids = array_combine($uuids, $uuids);
    foreach ($results as $result) {

      // @todo this should be compared against a known hash.
      if ($result->hash) {
        unset($uuids[$result->entity_uuid]);
      }
    }
    return array_values($uuids);
  }

  /**
   * Add tracking for an entity in a self::EXPORTED state.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity for which to add tracking.
   * @param string $hash
   *   A sha1 hash of the data attribute for change management.
   * @param string|null $remote_uuid
   *   A remote uuid if relevant.
   *
   * @throws \Exception
   */
  public function track(EntityInterface $entity, string $hash, $remote_uuid = NULL) {
    $values = [
      'entity_uuid' => $remote_uuid ?? $entity
        ->uuid(),
      'entity_type' => $entity
        ->getEntityTypeId(),
      'entity_id' => $entity
        ->id(),
      'last_imported' => date('c'),
    ];
    $this
      ->insertOrUpdate($values, self::IMPORTED, $hash);
  }

  /**
   * Add tracking for an entity in a self::QUEUED state.
   *
   * @var string $uuid
   *   The entity uuid to enqueue.
   *
   * @throws \Exception
   */
  public function queue($uuid) {
    $values = [
      'entity_uuid' => $uuid,
    ];
    $this
      ->insertOrUpdate($values, self::QUEUED);
  }

  /**
   * Determines if an entity will be inserted or updated with a status.
   *
   * @param array $values
   *   The array of values to insert.
   * @param string $status
   *   The status of the tracking.
   * @param string $hash
   *   The hash string.
   *
   * @return \Drupal\Core\Database\StatementInterface|int|null
   *   Database statement.
   *
   * @throws \Exception
   */
  protected function insertOrUpdate(array $values, $status, $hash = "") {
    if (empty($values['entity_uuid'])) {
      throw new \Exception("Cannot track a subscription without an entity uuid.");
    }
    $values['status'] = $status;
    if ($hash) {
      $values['hash'] = $hash;
    }
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t', [
      'first_imported',
    ]);
    $query
      ->condition('entity_uuid', $values['entity_uuid']);
    $results = $query
      ->execute()
      ->fetchObject();

    // If we've previously tracked this thing, set its created date.
    if ($results) {
      $query = $this->database
        ->update(self::IMPORT_TRACKING_TABLE)
        ->fields($values);
      $query
        ->condition('entity_uuid', $values['entity_uuid']);
      return $query
        ->execute();
    }
    $values['first_imported'] = date('c');
    return $this->database
      ->insert(self::IMPORT_TRACKING_TABLE)
      ->fields($values)
      ->execute();
  }

  /**
   * Get a local entity by its remote uuid if hashes match.
   *
   * @param string $uuid
   *   The remote uuid of the entity to load.
   * @param string|null $hash
   *   The expected hash of the entity (Currently unused).
   *
   * @return \Drupal\Core\Entity\EntityInterface|null
   *   The loaded entity if found
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getEntityByRemoteIdAndHash($uuid, $hash = NULL) {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t', [
      'entity_type',
      'entity_id',
    ]);
    $query
      ->condition('entity_uuid', $uuid);
    if (NULL !== $hash) {
      $query
        ->condition('hash', $hash);
    }
    $result = $query
      ->execute()
      ->fetchObject();
    if ($result && $result->entity_type && $result->entity_id) {
      return \Drupal::entityTypeManager()
        ->getStorage($result->entity_type)
        ->load($result->entity_id);
    }
  }

  /**
   * Delete an entry by its uuid.
   *
   * @param string $uuid
   *   UUID of the entity.
   */
  public function delete(string $uuid) : void {
    $query = $this->database
      ->delete(self::IMPORT_TRACKING_TABLE);
    $query
      ->condition('entity_uuid', $uuid);
    $query
      ->execute();
  }

  /**
   * Get the current status of an entity by type/id.
   *
   * @param string $type
   *   The type of an entity.
   * @param string $id
   *   The id of an entity.
   *
   * @return string
   *   The status string.
   */
  public function getStatusByTypeId(string $type, string $id) {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t', [
      'status',
    ]);
    $query
      ->condition('entity_type', $type);
    $query
      ->condition('entity_id', $id);
    $result = $query
      ->execute()
      ->fetchObject();
    if ($result && $result->status) {
      return $result->status;
    }
  }

  /**
   * Get the current status of a particular uuid.
   *
   * @param string $uuid
   *   The uuid of an entity.
   *
   * @return string
   *   The status string.
   */
  public function getStatusByUuid(string $uuid) {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t', [
      'status',
    ]);
    $query
      ->condition('entity_uuid', $uuid);
    $result = $query
      ->execute()
      ->fetchObject();
    if ($result && $result->status) {
      return $result->status;
    }
  }

  /**
   * Set the status of a particular item by its uuid.
   *
   * @param string $uuid
   *   The uuid of an entity.
   * @param string $status
   *   The status to set.
   *
   * @throws \Exception
   */
  public function setStatusByUuid(string $uuid, string $status) {
    $acceptable_statuses = [
      $this::AUTO_UPDATE_DISABLED,
      $this::IMPORTED,
      $this::QUEUED,
    ];
    if (!in_array($status, $acceptable_statuses)) {
      throw new \Exception(sprintf("The '%s' status is not valid. Please pass one of the following options: '%s'", $status, implode("', '", $acceptable_statuses)));
    }
    if (!$this
      ->isTracked($uuid)) {
      return;
    }
    $query = $this->database
      ->update(self::IMPORT_TRACKING_TABLE);
    $query
      ->fields([
      'status' => $status,
    ]);
    $query
      ->condition('entity_uuid', $uuid);
    $query
      ->execute();
  }

  /**
   * Set the queue item of a particular record by its uuid.
   *
   * @param array $uuids
   *   The uuids of entities.
   * @param string $queue_id
   *   The status to set.
   *
   * @throws \Exception
   */
  public function setQueueItemByUuids(array $uuids, string $queue_id) {
    if (!$this
      ->isTracked($uuids)) {
      return;
    }
    $query = $this->database
      ->update(self::IMPORT_TRACKING_TABLE);
    $query
      ->fields([
      'queue_id' => $queue_id,
    ]);
    $query
      ->condition('entity_uuid', $uuids, 'IN');
    $query
      ->execute();
  }

  /**
   * Set the status of a particular item by its entity type and id.
   *
   * @param string $type
   *   The type of an entity.
   * @param string $id
   *   The id of an entity.
   * @param string $status
   *   The status to set.
   *
   * @throws \Exception
   */
  public function setStatusByTypeId(string $type, string $id, string $status) {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 't')
      ->fields('t', [
      'entity_uuid',
    ]);
    $query
      ->condition('entity_type', $type);
    $query
      ->condition('entity_id', $id);
    $result = $query
      ->execute()
      ->fetchObject();
    if (!(bool) $result) {
      return;
    }
    $this
      ->setStatusByUuid($result->entity_uuid, $status);
  }

  /**
   * Obtains a list of entities.
   *
   * @param string $status
   *   The status of the entities to track.
   * @param string $entity_type_id
   *   The Entity type.
   *
   * @return array
   *   An array of Tracked Entities set to reindex.
   */
  public function listTrackedEntities(string $status, $entity_type_id = '') : array {
    $query = $this->database
      ->select(self::IMPORT_TRACKING_TABLE, 'ci')
      ->fields('ci')
      ->condition('status', $status);
    if (!empty($entity_type_id)) {
      $query = $query
        ->condition('entity_type', $entity_type_id);
    }
    return $query
      ->execute()
      ->fetchAll(\PDO::FETCH_ASSOC);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AcquiaContentHubStatusMetricsTrait::$database protected property The database connection.
AcquiaContentHubStatusMetricsTrait::getMostRecentUpdateTime public function Calculates updated time of most recent published tracked entity.
AcquiaContentHubStatusMetricsTrait::getStatusMetrics public function Calculates metrics timestamped and indexed by status.
SubscriberTracker::AUTO_UPDATE_DISABLED constant The status used to indicate an entity should no longer receive updates.
SubscriberTracker::delete public function Delete an entry by its uuid.
SubscriberTracker::getEntityByRemoteIdAndHash public function Get a local entity by its remote uuid if hashes match.
SubscriberTracker::getStatusByTypeId public function Get the current status of an entity by type/id.
SubscriberTracker::getStatusByUuid public function Get the current status of a particular uuid.
SubscriberTracker::getUntracked public function Gets a list of uuids that are not yet tracked.
SubscriberTracker::IMPORTED constant The status used to indicate that a tracked item has been imported.
SubscriberTracker::IMPORT_TRACKING_TABLE constant The name of the tracking table.
SubscriberTracker::insertOrUpdate protected function Determines if an entity will be inserted or updated with a status.
SubscriberTracker::isTracked public function Checks if a particular entity uuid is tracked.
SubscriberTracker::listTrackedEntities public function Obtains a list of entities.
SubscriberTracker::queue public function Add tracking for an entity in a self::QUEUED state.
SubscriberTracker::QUEUED constant The status used to indicate that a tracked item is to be reimported.
SubscriberTracker::setQueueItemByUuids public function Set the queue item of a particular record by its uuid.
SubscriberTracker::setStatusByTypeId public function Set the status of a particular item by its entity type and id.
SubscriberTracker::setStatusByUuid public function Set the status of a particular item by its uuid.
SubscriberTracker::track public function Add tracking for an entity in a self::EXPORTED state.
SubscriberTracker::__construct public function PublisherTracker constructor.