You are here

class ContentHubReindex in Acquia Content Hub 8

Class for reindexing Content Hub content.

@package Drupal\acquia_contenthub\Controller

Hierarchy

Expanded class hierarchy of ContentHubReindex

2 files declare their use of ContentHubReindex
ContentHubReindexTest.php in tests/src/Unit/Controller/ContentHubReindexTest.php
ReExportEntitiesForm.php in src/Form/ReExportEntitiesForm.php
1 string reference to 'ContentHubReindex'
acquia_contenthub.services.yml in ./acquia_contenthub.services.yml
acquia_contenthub.services.yml
1 service uses ContentHubReindex
acquia_contenthub.acquia_contenthub_reindex in ./acquia_contenthub.services.yml
Drupal\acquia_contenthub\Controller\ContentHubReindex

File

src/Controller/ContentHubReindex.php, line 16

Namespace

Drupal\acquia_contenthub\Controller
View source
class ContentHubReindex extends ControllerBase {
  const REINDEXING_STATE = 'acquia_contenthub.reindexing_state';
  const REINDEX_NONE = 'reindex_none';
  const REINDEX_SENT = 'reindex_sent';
  const REINDEX_FAILED = 'reindex_failed';
  const REINDEX_FINISHED = 'reindex_finished';

  /**
   * Content Hub Client Manager.
   *
   * @var \Drupal\acquia_contenthub\Client\ClientManager
   */
  private $clientManager;

  /**
   * The Content Hub Entities Tracking Service.
   *
   * @var \Drupal\acquia_contenthub\ContentHubEntitiesTracking
   */
  private $contentHubEntitiesTracking;

  /**
   * The Reindex State.
   *
   * @var string
   */
  protected $reindexState;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  private $state;

  /**
   * Public Constructor.
   *
   * @param \Drupal\acquia_contenthub\ContentHubEntitiesTracking $contenthub_entities_tracking
   *   The table where all entities are tracked.
   * @param \Drupal\acquia_contenthub\Client\ClientManagerInterface $client_manager
   *   The client manager.
   * @param \Drupal\Core\State\StateInterface $state_service
   *   Drupal state service.
   */
  public function __construct(ContentHubEntitiesTracking $contenthub_entities_tracking, ClientManagerInterface $client_manager, StateInterface $state_service) {
    $this->clientManager = $client_manager;
    $this->contentHubEntitiesTracking = $contenthub_entities_tracking;
    $this->state = $state_service;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('acquia_contenthub.acquia_contenthub_entities_tracking'), $container
      ->get('acquia_contenthub.client_manager'), $container
      ->get('state'));
  }

  /**
   * Gets the Reindexing State from the State Variable.
   *
   * @return string
   *   The Reindexing State.
   */
  private function getReindexingState() {
    $this->reindexState = $this->state
      ->get(self::REINDEXING_STATE, self::REINDEX_NONE);
    return $this->reindexState;
  }

  /**
   * Sets a new Reindexing State.
   *
   * @param string $new_state
   *   The new Reindexing State.
   *
   * @return string
   *   The new state, if it was successfully set, the previous state otherwise.
   */
  private function setReindexingState($new_state) {
    if (in_array($new_state, [
      self::REINDEX_NONE,
      self::REINDEX_SENT,
      self::REINDEX_FAILED,
      self::REINDEX_FINISHED,
    ])) {
      $this->reindexState = $new_state;
      $this->state
        ->set(self::REINDEXING_STATE, $this->reindexState);
    }
    return $this->reindexState;
  }

  /**
   * Sets the Reindexing State as REINDEX_NONE.
   *
   * @return string
   *   The new state.
   */
  public function setReindexStateNone() {
    return $this
      ->setReindexingState(self::REINDEX_NONE);
  }

  /**
   * Checks whether the current Reindexing State is REINDEX_NONE.
   *
   * @return bool
   *   TRUE if Reindexing State is REINDEX_NONE, FALSE otherwise.
   */
  public function isReindexNone() {
    return $this
      ->getReindexingState() === self::REINDEX_NONE;
  }

  /**
   * Checks whether the current Reindexing State is REINDEX_SENT.
   *
   * @return bool
   *   TRUE if Reindexing State is REINDEX_SENT, FALSE otherwise.
   */
  public function isReindexSent() {
    return $this
      ->getReindexingState() === self::REINDEX_SENT;
  }

  /**
   * Sets the Reindexing State as REINDEX_SENT.
   *
   * @return string
   *   The new state.
   */
  public function setReindexStateSent() {
    return $this
      ->setReindexingState(self::REINDEX_SENT);
  }

  /**
   * Checks whether the current Reindexing State is REINDEX_FAILED.
   *
   * @return bool
   *   TRUE if Reindexing State is REINDEX_FAILED, FALSE otherwise.
   */
  public function isReindexFailed() {
    return $this
      ->getReindexingState() === self::REINDEX_FAILED;
  }

  /**
   * Sets the Reindexing State as REINDEX_FAILED.
   *
   * @return string
   *   The new state.
   */
  public function setReindexStateFailed() {
    return $this
      ->setReindexingState(self::REINDEX_FAILED);
  }

  /**
   * Checks whether the current Reindexing State is REINDEX_FINISHED.
   *
   * @return bool
   *   TRUE if Reindexing State is REINDEX_FINISHED, FALSE otherwise.
   */
  public function isReindexFinished() {
    return $this
      ->getReindexingState() === self::REINDEX_FINISHED;
  }

  /**
   * Sets the Reindexing State as REINDEX_FINISHED.
   *
   * @return string
   *   The new state.
   */
  public function setReindexStateFinished() {
    return $this
      ->setReindexingState(self::REINDEX_FINISHED);
  }

  /**
   * Set Exported Entities to be Re-indexed.
   *
   * @param string $entity_type_id
   *   The Entity type.
   * @param string $bundle_id
   *   The Entity bundle.
   *
   * @return bool
   *   TRUE if subscription can be re-indexed, FALSE otherwise.
   */
  public function setExportedEntitiesToReindex($entity_type_id = NULL, $bundle_id = NULL) {

    // Set exported entities with the REINDEX flag.
    $this->contentHubEntitiesTracking
      ->setExportedEntitiesForReindex($entity_type_id, $bundle_id);

    // Collect all entities that were flagged for REINDEX.
    $entities = $this->contentHubEntitiesTracking
      ->getEntitiesToReindex();
    if (count($entities) == 0) {
      $this
        ->setReindexStateNone();
      return FALSE;
    }

    // Delete all entities set to reindex from Content Hub.
    foreach ($entities as $entity) {
      $this->clientManager
        ->createRequest('deleteEntity', [
        $entity->entity_uuid,
      ]);
    }

    // We have a sent a lot of delete requests to Content Hub, wait 10 seconds
    // before proceeding to reindex the subscription.
    sleep(10);

    // Now reindex subscription.
    if ($response = $this->clientManager
      ->createRequest('reindex')) {
      if (isset($response['success']) && $response['success'] === TRUE) {

        // Saving Reindexing State.
        $this
          ->setReindexStateSent();
        return TRUE;
      }
    }

    // The reindex request has failed, then set the reindex state as failed.
    $this
      ->setReindexStateFailed();
    return FALSE;
  }

  /**
   * Obtains number of entities to re-export.
   *
   * @return int
   *   Number of entities to re-export.
   */
  public function getCountReExportEntities() {
    return $this->contentHubEntitiesTracking
      ->getCountEntitiesToReindex();
  }

  /**
   * Obtains the entities to re-export.
   *
   * @param int $offset
   *   Offset from the list.
   * @param int $limit
   *   Length of entities to take.
   *
   * @return array
   *   An array of entities to re-export.
   */
  public function getReExportEntities($offset = 0, $limit = 10) {
    $entities = $this->contentHubEntitiesTracking
      ->getEntitiesToReindex();
    return array_slice($entities, $offset, $limit);
  }

  /**
   * Obtains a list of entities exported to Content Hub not owned by this site.
   *
   * For the specific entity type, it queries Content Hub and checks if the
   * previously exported entities belong to this exporting site origin or they
   * have been exported by other sites.
   *
   * Limitation: This check uses the "listEntities" method from ContentHubClient
   * without using pagination, so it will only check for the first 1000 entities
   * returned by this list. It will need to be improved at some point to deal
   * with pagination.
   *
   * @param string|null $entity_type_id
   *   The entity type ID.
   *
   * @return array
   *   An array of exported entities not owned by this site (different origin).
   */
  public function getExportedEntitiesNotOwnedByThisSite($entity_type_id = NULL) {
    $external_ownership = [];
    $options = empty($entity_type_id) ? [] : [
      'type' => $entity_type_id,
    ];
    $list = $this->clientManager
      ->createRequest('listEntities', [
      $options,
    ]);
    if (isset($list['success']) && $list['success'] && isset($list['data']) && is_array($list['data'])) {
      $origin = $this->contentHubEntitiesTracking
        ->getSiteOrigin();
      foreach ($list['data'] as $entity) {
        if ($entity['origin'] !== $origin) {
          $external_ownership[] = $entity;
        }
      }
    }
    return $external_ownership;
  }

  /**
   * Re-export Entities.
   *
   * @param int $limit
   *   The number of entities to re-export in a single batch process.
   * @param mixed $context
   *   The context array.
   */
  public static function reExportEntities($limit, &$context) {

    // Sleep for 3 seconds before start processing.
    sleep(3);

    /** @var \Drupal\acquia_contenthub\Controller\ContentHubReindex $reindex */
    $reindex = \Drupal::service('acquia_contenthub.acquia_contenthub_reindex');
    if (empty($context['sandbox'])) {
      $context['sandbox']['progress'] = 0;
      $context['sandbox']['max'] = $reindex
        ->getCountReExportEntities();
    }

    /** @var \Drupal\acquia_contenthub\EntityManager $entity_manager */
    $entity_manager = \Drupal::service('acquia_contenthub.entity_manager');
    $entities = $reindex
      ->getReExportEntities(0, $limit);
    $messages = [];
    foreach ($entities as $entity_item) {
      $entity_type = $entity_item->entity_type;
      $entity_id = $entity_item->entity_id;
      $entity = \Drupal::entityTypeManager()
        ->getStorage($entity_type)
        ->load($entity_id);
      $entity_manager
        ->enqueueCandidateEntity($entity);

      // Storing Results and.
      $context['results'][] = $entity_id;
      $context['sandbox']['progress']++;
      $messages[] = $reindex
        ->t('(type = @type, id = @id, uuid = @uuid)', [
        '@type' => $entity_type,
        '@id' => $entity_id,
        '@uuid' => $entity_item->entity_uuid,
      ]);
    }
    $context['message'] = $reindex
      ->t('Exporting entities: @entities', [
      '@entities' => implode(',', $messages),
    ]);
    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
      $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
    }
  }

  /**
   * Implements Batch API to re-export entities after re-indexing.
   *
   * @param int $batch_size
   *   The batch size or number of entities processed in a single request.
   */
  public function reExportEntitiesAfterReindex($batch_size = 10) {
    $batch = [
      'title' => $this
        ->t("Process Content Hub Export Queue"),
      'file' => drupal_get_path('module', 'acquia_contenthub') . '/acquia_contenthub.drush.inc',
      'operations' => [
        [
          '\\Drupal\\acquia_contenthub\\Controller\\ContentHubReindex::reExportEntities',
          [
            $batch_size,
          ],
        ],
      ],
      'finished' => 'acquia_contenthub_reexport_finished',
    ];
    batch_set($batch);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ContentHubReindex::$clientManager private property Content Hub Client Manager.
ContentHubReindex::$contentHubEntitiesTracking private property The Content Hub Entities Tracking Service.
ContentHubReindex::$reindexState protected property The Reindex State.
ContentHubReindex::$state private property The state service.
ContentHubReindex::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
ContentHubReindex::getCountReExportEntities public function Obtains number of entities to re-export.
ContentHubReindex::getExportedEntitiesNotOwnedByThisSite public function Obtains a list of entities exported to Content Hub not owned by this site.
ContentHubReindex::getReExportEntities public function Obtains the entities to re-export.
ContentHubReindex::getReindexingState private function Gets the Reindexing State from the State Variable.
ContentHubReindex::isReindexFailed public function Checks whether the current Reindexing State is REINDEX_FAILED.
ContentHubReindex::isReindexFinished public function Checks whether the current Reindexing State is REINDEX_FINISHED.
ContentHubReindex::isReindexNone public function Checks whether the current Reindexing State is REINDEX_NONE.
ContentHubReindex::isReindexSent public function Checks whether the current Reindexing State is REINDEX_SENT.
ContentHubReindex::reExportEntities public static function Re-export Entities.
ContentHubReindex::reExportEntitiesAfterReindex public function Implements Batch API to re-export entities after re-indexing.
ContentHubReindex::REINDEXING_STATE constant
ContentHubReindex::REINDEX_FAILED constant
ContentHubReindex::REINDEX_FINISHED constant
ContentHubReindex::REINDEX_NONE constant
ContentHubReindex::REINDEX_SENT constant
ContentHubReindex::setExportedEntitiesToReindex public function Set Exported Entities to be Re-indexed.
ContentHubReindex::setReindexingState private function Sets a new Reindexing State.
ContentHubReindex::setReindexStateFailed public function Sets the Reindexing State as REINDEX_FAILED.
ContentHubReindex::setReindexStateFinished public function Sets the Reindexing State as REINDEX_FINISHED.
ContentHubReindex::setReindexStateNone public function Sets the Reindexing State as REINDEX_NONE.
ContentHubReindex::setReindexStateSent public function Sets the Reindexing State as REINDEX_SENT.
ContentHubReindex::__construct public function Public Constructor.
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityManager protected property The entity manager.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 2
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityManager Deprecated protected function Retrieves the entity manager service.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
ControllerBase::state protected function Returns the state storage service.
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.