class EntityShareCronService in Entity Share Cron 8
Same name and namespace in other branches
- 8.2 src/EntityShareCronService.php \Drupal\entity_share_cron\EntityShareCronService
- 3.0.x src/EntityShareCronService.php \Drupal\entity_share_cron\EntityShareCronService
Entity Share Cron service.
Hierarchy
- class \Drupal\entity_share_cron\EntityShareCronService implements EntityShareCronServiceInterface
Expanded class hierarchy of EntityShareCronService
2 files declare their use of EntityShareCronService
- EntityShareCronPending.php in src/
Plugin/ QueueWorker/ EntityShareCronPending.php - EntityShareCronServiceTest.php in tests/
src/ Unit/ EntityShareCronServiceTest.php
1 string reference to 'EntityShareCronService'
1 service uses EntityShareCronService
File
- src/
EntityShareCronService.php, line 16
Namespace
Drupal\entity_share_cronView source
class EntityShareCronService implements EntityShareCronServiceInterface {
/**
* Module configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $config;
/**
* Remote manager service.
*
* @var \Drupal\entity_share_client\Service\RemoteManagerInterface
*/
protected $remoteManager;
/**
* JSON API helper service.
*
* @var \Drupal\entity_share_client\Service\JsonapiHelperInterface
*/
protected $jsonapiHelper;
/**
* Queue service.
*
* @var \Drupal\Core\Queue\QueueFactory
*/
protected $queueFactory;
/**
* Entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructor.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* Config factory.
* @param \Drupal\entity_share_client\Service\RemoteManagerInterface $remote_manager
* Remote manager to get channels infos from.
* @param \Drupal\entity_share_client\Service\JsonapiHelperInterface $jsonapi_helper
* Helps to prepare JSON responses.
* @param \Drupal\Core\Queue\QueueFactory $queue_factory
* Queue service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(ConfigFactoryInterface $config_factory, RemoteManagerInterface $remote_manager, JsonapiHelperInterface $jsonapi_helper, QueueFactory $queue_factory, EntityTypeManagerInterface $entity_type_manager) {
$this->config = $config_factory
->get('entity_share_cron.settings');
$this->remoteManager = $remote_manager;
$this->jsonapiHelper = $jsonapi_helper;
$this->queueFactory = $queue_factory;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public function enqueue($remote_id, $channel_id, array $channel_info) {
$queue_name = EntityShareCronServiceInterface::PENDING_QUEUE_NAME;
$queue = $this->queueFactory
->get($queue_name);
$item = [
'remote_id' => $remote_id,
'channel_id' => $channel_id,
'channel_info' => $channel_info,
];
$queue
->createItem($item);
}
/**
* {@inheritdoc}
*/
public function sync($remote_id, $channel_id, array $channel_info, $page_limit = 0) {
// Collects entities to import from each page.
$data_to_import = [];
$next_page = 1;
$url = $channel_info['url'];
while ($url) {
// Performs request to get the list of entities.
$page_data = $this
->getPage($remote_id, $channel_id, $url);
$data_to_import = array_merge($data_to_import, $page_data['data']);
$next_page++;
if ($url = $page_data['next']) {
if ($page_limit != 0 && $next_page > $page_limit) {
// Enqueues the next page.
$next_info = $channel_info;
$next_info['url'] = $url;
$this
->enqueue($remote_id, $channel_id, $next_info);
$url = FALSE;
}
}
}
// Removes data to import according to enabled operations.
$channel_config = $this
->getChannelConfig($remote_id, $channel_id);
if (empty($channel_config['operations']['create'])) {
$this
->filterDataToImport($data_to_import);
}
if (empty($channel_config['operations']['update'])) {
$this
->filterDataToImport($data_to_import, FALSE);
}
// Imports the data.
return $this->jsonapiHelper
->importEntityListData($data_to_import);
}
/**
* Returns the page data to import entities.
*
* @param string $remote_id
* The ID of the remote the channel belongs to.
* @param string $channel_id
* The ID of the channel to be synchronized.
* @param string $url
* The URL of the page.
*
* @return array
* An associative array with the following keys:
* - data => parsed JSON of entities to import.
* - next => URL of the next page.
*/
protected function getPage($remote_id, $channel_id, $url) {
$data = [
'data' => [],
'next' => FALSE,
];
if ($remote = Remote::load($remote_id)) {
// Makes request to get profiles.
$this->jsonapiHelper
->setRemote($remote);
$http_client = $this->remoteManager
->prepareJsonApiClient($remote);
$json_response = $http_client
->get($url)
->getBody()
->getContents();
// Parses the JSON of entities to import.
$json = Json::decode($json_response);
$data['data'] = $this->jsonapiHelper
->prepareData($json['data']);
// Gets the URL of the next page.
$data['next'] = !empty($json['links']['next']) ? $json['links']['next'] : FALSE;
}
return $data;
}
/**
* Filters the data to import by existing or non existing entities.
*
* @param array $data
* The data to be filtered.
* @param bool $keep_existing
* Keeps only existing entities if TRUE. Otherwise, only non existing
* entities.
*/
protected function filterDataToImport(array &$data, $keep_existing = TRUE) {
// Groups entities by entity type before checking.
$uuid_by_type = [];
foreach ($data as $key => $entity_data) {
$parsed_type = explode('--', $entity_data['type']);
$entity_type = $parsed_type[0];
$uuid = $entity_data['id'];
$uuid_by_type[$entity_type][] = $uuid;
}
// Filters entities.
$existing_uuids = [];
foreach ($uuid_by_type as $entity_type => $uuids) {
$definition = $this->entityTypeManager
->getDefinition($entity_type);
$uuid_property = $definition
->getKey('uuid');
// Gets existing entities from the list.
$storage = $this->entityTypeManager
->getStorage($entity_type);
$existing_entities = $storage
->loadByProperties([
$uuid_property => $uuids,
]);
// Adds existing UUIDs to list.
foreach ($existing_entities as $entity) {
$uuid = $entity
->uuid();
$existing_uuids[$uuid] = $uuid;
}
}
// Filters data to be imported.
$data_updated = [];
foreach ($data as $entity_data) {
$uuid = $entity_data['id'];
if ($keep_existing && !empty($existing_uuids[$uuid])) {
$data_updated[] = $entity_data;
}
elseif (!$keep_existing && empty($existing_uuids[$uuid])) {
$data_updated[] = $entity_data;
}
}
$data = $data_updated;
}
/**
* Returns the settings of a channel.
*
* @param string $remote_id
* The ID of the remote the channel belongs to.
* @param string $channel_id
* The ID of the channel.
*
* @return array
* Channel settings.
*/
protected function getChannelConfig($remote_id, $channel_id) {
$settings = [];
$remotes = $this->config
->get('remotes');
if (!empty($remotes[$remote_id]['channels'][$channel_id])) {
$settings = $remotes[$remote_id]['channels'][$channel_id];
}
return $settings;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
EntityShareCronService:: |
protected | property | Module configuration. | |
EntityShareCronService:: |
protected | property | Entity type manager. | |
EntityShareCronService:: |
protected | property | JSON API helper service. | |
EntityShareCronService:: |
protected | property | Queue service. | |
EntityShareCronService:: |
protected | property | Remote manager service. | |
EntityShareCronService:: |
public | function |
Enqueues a channel for later synchronization. Overrides EntityShareCronServiceInterface:: |
|
EntityShareCronService:: |
protected | function | Filters the data to import by existing or non existing entities. | |
EntityShareCronService:: |
protected | function | Returns the settings of a channel. | |
EntityShareCronService:: |
protected | function | Returns the page data to import entities. | |
EntityShareCronService:: |
public | function |
Synchronizes entities starting from provided channel URL. Overrides EntityShareCronServiceInterface:: |
|
EntityShareCronService:: |
public | function | Constructor. | |
EntityShareCronServiceInterface:: |
constant |