bridtv-8.x-1.x-dev/src/BridPlaylistSync.php
src/BridPlaylistSync.php
<?php
namespace Drupal\bridtv;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueWorkerManagerInterface;
/**
* Service class for handling synchronization of video data.
*/
class BridPlaylistSync extends BridSyncBase {
/**
* {@inheritDoc}
*/
public function __construct(ConfigFactoryInterface $config_factory, QueueFactory $queue_factory, QueueWorkerManagerInterface $worker_manager, LoggerChannelFactoryInterface $logger_factory, BridApiConsumer $consumer, BridEntityResolverInterface $entity_resolver, KeyValueFactoryInterface $kv_factory, MessengerInterface $messenger) {
parent::__construct($config_factory, $logger_factory, $consumer, $entity_resolver, $kv_factory, $messenger);
$this->queue = $queue_factory->get('bridtv_playlist_sync');
$this->worker = $worker_manager->createInstance('bridtv_playlist_sync');
}
/**
* Syncs the playerlist data.
*/
public function syncPlaylistData($id) {
if (!$this->consumer->isReady()) {
$this->logger->error($this->t('The Brid.TV API consumer is not ready. Check the module configuration to be properly set up.'));
return FALSE;
}
$entity = $this->entityResolver->getEntityForPlaylistId($id);
$is_new = FALSE;
if (!$entity) {
if ($this->autocreateEnabled()) {
$entity = $this->entityResolver->newEntity();
$is_new = TRUE;
}
else {
return TRUE;
}
}
$status = NULL;
$latest_data = $this->consumer->fetchPlaylistData($id, $status);
if ($latest_data && ($decoded = BridSerialization::decode($latest_data))) {
if (empty($decoded['data']['Playlist'])) {
$this->logger->error($this->t('Unexpected Playlist data retrieved, aborting synchronization.'));
return FALSE;
}
$playlist = $decoded['data']['Playlist'];
$items = $this->entityResolver->getFieldItemList($entity);
$new_value = [
'playlist_id' => $id,
'title' => !empty($playlist['name']) ? $playlist['name'] : NULL,
'name' => !empty($playlist['name']) ? $playlist['name'] : NULL,
'publish_date' => !empty($playlist['created']) ? $playlist['created'] : NULL,
];
if (NULL === $items || $items->isEmpty() || !($items->first()->getValue()['name'] == $new_value['title'])) {
$items->setValue([$new_value]);
$entity->set('name', $new_value['title']);
$entity->save();
if ($is_new) {
$this->logger->notice($this->t('Saved a new @type entity with ID @id for a newly added Brid.TV playlist (@playlist_id).', [
'@type' => $entity->getEntityType()
->getLabel(),
'@id' => $entity->id(),
'@playlist_id' => $id,
]));
}
else {
$this->logger->notice($this->t('Updated @type entity with ID @id to be synchronized with its remote Brid.TV playlist (@playlist_id).', [
'@type' => $entity->getEntityType()
->getLabel(),
'@id' => $entity->id(),
'@playlist_id' => $id,
]));
}
}
}
elseif (!$latest_data && !$entity->isNew() && ($status == 404) && $this->autodeleteEnabled()) {
$entity->delete();
$this->logger->notice($this->t('Deleted @type entity with ID @id, because its referenced Brid.TV does not exist anymore. To prevent automatic deletions, disable the autodelete setting at the Brid.TV module settings.', [
'@type' => $entity->getEntityType()
->getLabel(),
'@id' => $entity->id(),
]));
}
else {
return FALSE;
}
return TRUE;
}
/**
* Syncs the video data for entity.
*/
public function syncVideoDataForEntity(FieldableEntityInterface $entity) {
$field = NULL;
foreach ($entity->getFieldDefinitions() as $definition) {
if ($definition->getType() === 'bridtv') {
$field = $definition->getName();
break;
}
}
if (!$field || $entity->get($field)
->isEmpty() || !($video_id = $entity->get($field)
->first()
->get('video_id')
->getValue())) {
return FALSE;
}
$representing = $this->entityResolver->getEntityForVideoId($video_id);
if (!(($representing->getEntityTypeId() === $entity->getEntityTypeId()) && ($representing->id() === $entity->id()))) {
return FALSE;
}
return $this->syncVideoData($video_id);
}
/**
* Prepares full sync.
*/
public function prepareFullSync() {
if (!$this->consumer->isReady()) {
$this->logger->error($this->t('The Brid.TV API consumer is not ready. Check the module configuration to be properly set up.'));
return;
}
// Synchronize all player information.
$this->syncPlayersInfo();
$queue = $this->queue;
$queue->createQueue();
if ($queue->numberOfItems() > 0) {
// Queue is not empty, i.e. synchronization is already in progress.
$this->logger->info($this->t('The queue for synchronizing Brid.TV video data contains items for processing.'));
// Show warning to user, if running this manually.
if (strpos($_SERVER['REQUEST_URI'], '/batch') !== FALSE) {
$this->messenger->addWarning('The queue for synchronizing Brid.TV video data already contains items for processing. Synchronization already in progress - please try again later.');
}
return;
}
// When autodelete is enabled, we need
// to sync the other way around (from local to remote).
if ($this->autodeleteEnabled()) {
$query = $this->entityResolver->getEntityQuery();
$query->sort($this->entityResolver->getEntityTypeDefinition()
->getKey('id'), 'ASC');
$query->range(0, static::ITEMS_PER_QUEUE_ITEM);
if ($result = $query->execute()) {
$entity_ids = array_values($result);
$this->queueMultipleEntitiesItem($entity_ids, TRUE);
}
}
$this->queueRemoteListItem(1, TRUE);
$this->logger->info($this->t('The full synchronization of Brid.TV video data has been enqueued for processing.'));
}
}
