rdf_sync-1.x-dev/src/RdfSyncSynchronizer.php
src/RdfSyncSynchronizer.php
<?php
declare(strict_types=1);
namespace Drupal\rdf_sync;
use Drupal\Core\DestructableInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\State\StateInterface;
use Drupal\rdf_sync\Event\RdfSyncEvent;
use Drupal\rdf_sync\Model\SyncMethod;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerInterface;
/**
* Synchronizes the RDF backend.
*/
class RdfSyncSynchronizer implements DestructableInterface {
/**
* Synchronization operations storage.
*/
protected array $stack = [];
public function __construct(
protected StateInterface $state,
protected SerializerInterface $serializer,
protected QueueFactory $queueFactory,
protected RdfSyncMapperInterface $mapper,
protected NormalizerInterface $normalizer,
protected RdfSyncConnectionInterface $rdfSyncConnection,
protected EventDispatcherInterface $eventDispatcher,
) {}
/**
* Checks whether the synchronization is enabled.
*
* @return bool
* TRUE if the synchronization is enabled.
*/
public function isSynchronizationEnabled(): bool {
return !$this->state->get('rdf_sync.synchronization_disabled', FALSE);
}
/**
* Enables synchronization.
*
* @return $this
*/
public function enableSynchronization(): self {
$this->state->delete('rdf_sync.synchronization_disabled');
return $this;
}
/**
* Disables synchronization.
*
* @return $this
*/
public function disableSynchronization(): self {
$this->state->set('rdf_sync.synchronization_disabled', TRUE);
return $this;
}
/**
* Synchronizes entities to the RDF backend.
*
* @param \Drupal\rdf_sync\Model\SyncMethod $method
* The synchronization method. See Drupal\rdf_sync\Model\SyncMethod.
* @param \Drupal\Core\Entity\ContentEntityInterface[] $entities
* The entities for which to update the RDF backend.
* @param bool $synchronize
* (optional) Overrides the stored synchronization kill-switch.
*/
public function synchronize(SyncMethod $method, array $entities, ?bool $synchronize = NULL): void {
$synchronize ??= $this->isSynchronizationEnabled();
if ($synchronize) {
// Register this synchronization to be processed on destruction.
$this->stack[] = [$method, $entities];
}
}
/**
* {@inheritdoc}
*/
public function destruct(): void {
/** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */
foreach ($this->stack as [$method, $entities]) {
$this->doSynchronize($method, $entities);
}
$this->stack = [];
}
/**
* Synchronizes the RDF backend given a list of entities.
*
* @param \Drupal\rdf_sync\Model\SyncMethod $method
* The synchronization method. See Drupal\rdf_sync\Model\SyncMethod.
* @param \Drupal\Core\Entity\ContentEntityInterface[] $entities
* The entities for which to update the RDF backend.
*/
protected function doSynchronize(SyncMethod $method, array $entities): void {
$event = new RdfSyncEvent($method, $entities);
$this->eventDispatcher->dispatch($event);
$entities = $event->getEntities();
if (in_array($method, [SyncMethod::UPDATE, SyncMethod::DELETE], TRUE)) {
$uris = array_filter(
array_map(
function (ContentEntityInterface $entity): ?string {
$fieldName = $this->mapper->getRdfUriFieldName(entity: $entity);
return $entity->get($fieldName)->value;
},
$entities,
)
);
if ($uris) {
$this->rdfSyncConnection->deleteTriples($uris);
}
}
if (in_array($method, [SyncMethod::INSERT, SyncMethod::UPDATE], TRUE)) {
$triples = [];
foreach ($entities as $entity) {
$fieldName = $this->mapper->getRdfUriFieldName(entity: $entity);
if (!$entity->get($fieldName)->isEmpty()) {
$triples += $this->normalizer->normalize($entity);
}
}
$this->rdfSyncConnection->insertTriples($triples);
}
}
}
