You are here

public function EntityShareClientCliService::ioPullUpdates in Entity Share 8

Same name and namespace in other branches
  1. 8.2 modules/entity_share_client/src/Service/EntityShareClientCliService.php \Drupal\entity_share_client\Service\EntityShareClientCliService::ioPullUpdates()

Handle the pull updates interaction.

Parameters

string $remote_id: The remote website id to import from.

string $channel_id: The remote channel id to import.

\Symfony\Component\Console\Style\StyleInterface|\ConfigSplitDrush8Io $io: The $io interface of the cli tool calling.

callable $t: The translation function akin to t().

File

modules/entity_share_client/src/Service/EntityShareClientCliService.php, line 150

Class

EntityShareClientCliService
Class EntityShareClientCliService.

Namespace

Drupal\entity_share_client\Service

Code

public function ioPullUpdates($remote_id, $channel_id, $io, callable $t) {
  Timer::start('io-pull-updates');
  $remotes = Remote::loadMultiple();

  // Check that the remote website exists.
  if (!isset($remotes[$remote_id])) {
    $io
      ->error($t('There is no remote website configured with the id: @remote_id.', [
      '@remote_id' => $remote_id,
    ]));
    return;
  }
  $remote = $remotes[$remote_id];
  $channel_infos = $this->remoteManager
    ->getChannelsInfos($remote);

  // Check that the channel exists.
  if (!isset($channel_infos[$channel_id])) {
    $io
      ->error($t('There is no channel configured or accessible with the id: @channel_id.', [
      '@channel_id' => $channel_id,
    ]));
    return;
  }

  // Import channel content and loop on pagination.
  $this->jsonapiHelper
    ->setRemote($remote);
  $http_client = $this->remoteManager
    ->prepareJsonApiClient($remote);
  $channel_url = $channel_infos[$channel_id]['url'];
  $storage = $this->entityTypeManager
    ->getStorage($channel_infos[$channel_id]['channel_entity_type']);
  $offset = 0;
  $update_count = 0;
  $io
    ->text($t('Looking for new content in channel @channel', [
    '@channel' => $channel_id,
  ]));
  while ($channel_url) {

    // Offset pagination.
    $parsed_url = UrlHelper::parse($channel_infos[$channel_id]['url_uuid']);
    $parsed_url['query']['page']['offset'] = $offset;
    $query = UrlHelper::buildQuery($parsed_url['query']);
    $revisions_url = $parsed_url['path'] . '?' . $query;
    $io
      ->text($t('Looking for updated content at URL: @url', [
      '@url' => $revisions_url,
    ]));

    // Get UUIDs and update timestamps from next page in a row.
    $json_response = $http_client
      ->get($revisions_url)
      ->getBody()
      ->getContents();
    $revisions_json = Json::decode($json_response);
    $uuids = [];
    foreach ($revisions_json['data'] as $row) {

      // Look for query with the same UUID and changed timestamp,
      // if that entity doesn't exist it means we need to pull it from remote channel.
      $entityChanged = $storage
        ->getQuery()
        ->condition('uuid', $row['id'])
        ->condition('changed', $row['attributes']['changed'])
        ->count()
        ->execute();
      if ($entityChanged == 0) {
        $uuids[] = $row['id'];
      }
    }
    if (!empty($uuids)) {

      // Prepare JSON filter query string.
      $filter = [
        'filter' => [
          'uuid' => [
            'path' => 'uuid',
            'value' => $uuids,
            'operator' => 'IN',
          ],
        ],
      ];

      // Call remote channel and fetch content of entities which should be updated.
      $filter_query = UrlHelper::buildQuery($filter);
      $filtered_url = $channel_infos[$channel_id]['url'] . '?' . $filter_query;
      $json_response = $http_client
        ->get($filtered_url)
        ->getBody()
        ->getContents();
      $json = Json::decode($json_response);
      $imported_entities = $this->jsonapiHelper
        ->importEntityListData($this->jsonapiHelper
        ->prepareData($json['data']));
      $io
        ->text($t('@number entities have been imported.', [
        '@number' => count($imported_entities),
      ]));
      $update_count += count($imported_entities);
    }
    if (isset($revisions_json['links']['next'])) {
      $channel_url = $revisions_json['links']['next'];
    }
    else {
      $channel_url = FALSE;
    }

    // Update page number and offset for next API call.
    $offset += 50;
  }
  Timer::stop('io-pull-updates');
  $io
    ->success($t('Channel successfully pulled. Number of updated entities: @count, execution time: @time ms', [
    '@count' => $update_count,
    '@time' => Timer::read('io-pull-updates'),
  ]));
}