View source
<?php
namespace Drupal\entity_share_client\Service;
use Drupal\Component\Serialization\Json;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\entity_share_client\Entity\Remote;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Component\Utility\Timer;
class EntityShareClientCliService {
protected $stringTranslation;
protected $remoteManager;
protected $jsonapiHelper;
protected $errors;
protected $entityTypeManager;
public function __construct(TranslationInterface $string_translation, RemoteManagerInterface $remote_manager, JsonapiHelperInterface $jsonapi_helper, EntityTypeManagerInterface $entity_type_manager) {
$this->stringTranslation = $string_translation;
$this->remoteManager = $remote_manager;
$this->jsonapiHelper = $jsonapi_helper;
$this->entityTypeManager = $entity_type_manager;
$this->errors = [];
}
public function ioPull($remote_id, $channel_id, $io, callable $t) {
Timer::start('io-pull');
$remotes = Remote::loadMultiple();
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);
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;
}
$this->jsonapiHelper
->setRemote($remote);
$http_client = $this->remoteManager
->prepareJsonApiClient($remote);
$channel_url = $channel_infos[$channel_id]['url'];
while ($channel_url) {
$io
->text($t('Beginning to import content from URL: @url', [
'@url' => $channel_url,
]));
$json_response = $http_client
->get($channel_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),
]));
if (isset($json['links']['next'])) {
$channel_url = $json['links']['next'];
}
else {
$channel_url = FALSE;
}
}
Timer::stop('io-pull');
$io
->success($t('Channel successfully pulled. Execution time @time ms.', [
'@time' => Timer::read('io-pull'),
]));
}
public function ioPullUpdates($remote_id, $channel_id, $io, callable $t) {
Timer::start('io-pull-updates');
$remotes = Remote::loadMultiple();
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);
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;
}
$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) {
$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,
]));
$json_response = $http_client
->get($revisions_url)
->getBody()
->getContents();
$revisions_json = Json::decode($json_response);
$uuids = [];
foreach ($revisions_json['data'] as $row) {
$entityChanged = $storage
->getQuery()
->condition('uuid', $row['id'])
->condition('changed', $row['attributes']['changed'])
->count()
->execute();
if ($entityChanged == 0) {
$uuids[] = $row['id'];
}
}
if (!empty($uuids)) {
$filter = [
'filter' => [
'uuid' => [
'path' => 'uuid',
'value' => $uuids,
'operator' => 'IN',
],
],
];
$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;
}
$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'),
]));
}
public function getErrors() {
return $this->errors;
}
}