epub_reader_framework-2.0.0-alpha2/src/Entity/ReaderEntityCrossReference.php
src/Entity/ReaderEntityCrossReference.php
<?php
namespace Drupal\epub_reader_framework\Entity;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Handle cross-references between chapter and publication.
*/
class ReaderEntityCrossReference {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager')
);
}
/**
* Cross reference the chapters from the publication.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The reader publication node.
* @param \Drupal\node\NodeInterface $reader_chapter
* The reader chapter node.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function ensureChapterIsCrossReferencedInPublication(
NodeInterface $reader_publication,
NodeInterface $reader_chapter
) {
$chapter_node_ids = $this->getExistingCrossReferences($reader_publication);
// If the chapter is not already part of the references, add it.
if (!in_array($reader_chapter->id(), $chapter_node_ids)) {
$chapter_node_ids[] = $reader_chapter->id();
$this->saveCrossReferences($reader_publication, $chapter_node_ids);
}
}
/**
* Cross reference the chapters from the publication.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The reader publication node.
* @param array $imported_chapter_nids
* An array of chapter nids that below to the publication.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function crossReferenceChaptersFromPublicationExtraction(
NodeInterface $reader_publication,
array $imported_chapter_nids
) {
$chapter_node_ids = [];
// Get list of non-automated chapters to ensure we don't delete them.
$non_automated_chapter_nids = $this->entityTypeManager->getStorage('node')->getQuery()
->condition('type', 'reader_chapter')
->condition('field_reader_publication', $reader_publication->id())
->condition('field_reader_chapter_automated', TRUE)
->accessCheck()
->execute();
$non_automated_chapter_nids = $non_automated_chapter_nids ?? [];
// Get references already on the publication.
$existing_node_ids = $this->getExistingCrossReferences($reader_publication);
foreach ($existing_node_ids as $existing_node_id) {
// Only add to list of references if it is either non-automated or
// in the list of ones automatically passed from the batch now. Anything
// else should be removed.
if (
in_array($existing_node_id, $non_automated_chapter_nids)
|| in_array($existing_node_id, $imported_chapter_nids)
) {
$chapter_node_ids[] = $existing_node_id;
}
}
// Add any new references that don't yet exist onto the end.
if ($imported_chapter_nids) {
foreach ($imported_chapter_nids as $imported_chapter_nid) {
if (!in_array($imported_chapter_nid, $chapter_node_ids)) {
$chapter_node_ids[] = $imported_chapter_nid;
}
}
}
$this->saveCrossReferences($reader_publication, $chapter_node_ids);
}
/**
* Get existing cross references.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The reader publication node.
*
* @return array
* An array of node ids for existing cross-referenced chapters.
*/
protected function getExistingCrossReferences(
NodeInterface $reader_publication
) {
$node_ids = [];
$chapter_references = $reader_publication->get('field_reader_chapters');
if ($chapter_references->count()) {
foreach ($chapter_references as $chapter_reference) {
if ($entity = $chapter_reference->entity) {
/** @var \Drupal\Core\Entity\EntityInterface $entity */
$node_ids[] = $entity->id();
}
}
}
$node_ids = array_filter($node_ids);
return array_unique($node_ids);
}
/**
* Save cross references to the node entity.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The reader publication node.
* @param array $chapter_node_ids
* An array of chapter node ids.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function saveCrossReferences(
NodeInterface $reader_publication,
array $chapter_node_ids
) {
$targets = [];
foreach ($chapter_node_ids as $chapter_node_id) {
$targets[] = [
'target_id' => $chapter_node_id,
];
}
$reader_publication->set('field_reader_chapters', $targets);
$reader_publication->setNewRevision(TRUE);
$reader_publication->save();
}
}
