epub_reader_framework-2.0.0-alpha2/src/Epub/ReaderEpubXhtmlConverter.php
src/Epub/ReaderEpubXhtmlConverter.php
<?php
namespace Drupal\epub_reader_framework\Epub;
use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\epub_reader_framework\Event\ReaderEpubXhmlConverterEvent;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Wa72\HtmlPageDom\HtmlPageCrawler;
/**
* Convert the epub xhtml to drupal nodes and paragraphs.
*/
class ReaderEpubXhtmlConverter {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher definition.
*
* @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
*/
protected $eventDispatcher;
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $eventDispatcher
* The event dispatcher.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
ContainerAwareEventDispatcher $eventDispatcher
) {
$this->entityTypeManager = $entity_type_manager;
$this->eventDispatcher = $eventDispatcher;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('event_dispatcher')
);
}
/**
* Convert the XML into chapters.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The reader publication node.
* @param string $chapter_xhtml_uri
* The path to the xhtml file.
* @param string $chapter_id
* The chapter ID from the EPUB spine.
*
* @return bool|\Drupal\node\NodeInterface
* The chapter node.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
*/
public function convertXhtmlToChapter(
NodeInterface $reader_publication,
$chapter_xhtml_uri,
$chapter_id
) {
// Set up crawler.
$crawler = FALSE;
if ($file_contents = file_get_contents($chapter_xhtml_uri)) {
$crawler = new HtmlPageCrawler($file_contents);
}
// Set up node.
$title = $chapter_id;
$reader_chapter = $this->getExistingNodeByPublicationAndChapterId(
$reader_publication,
$chapter_id
);
if (!$reader_chapter) {
$reader_chapter = $this->createNewNode(
$reader_publication,
$chapter_id,
$title
);
}
// If we have a node and the node is automated from the EPUB.
if ($reader_chapter && $reader_chapter->get('field_reader_chapter_automated')->value) {
// Instantiate our event.
if ($crawler instanceof HtmlPageCrawler) {
$event = new ReaderEpubXhmlConverterEvent(
$crawler,
$reader_publication,
$reader_chapter
);
// Get the event_dispatcher service and dispatch the event.
$event_name = ReaderEpubXhmlConverterEvent::EVENT_NAME;
$event_dispatcher = $this->eventDispatcher;
$event_dispatcher->dispatch($event, $event_name);
}
}
return $reader_chapter->id();
}
/**
* Create a new node.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The publication.
* @param string $chapter_id
* The chapter ID from the EPUB.
*
* @return \Drupal\node\NodeInterface|bool
* The existing node or false.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getExistingNodeByPublicationAndChapterId(
NodeInterface $reader_publication,
$chapter_id
) {
$query = $this->entityTypeManager->getStorage('node')->getQuery();
$existing_chapter_ids = $query
->condition('type', 'reader_chapter')
->condition('field_reader_chapter_epub_id', $chapter_id)
->condition('field_reader_publication', $reader_publication->id())
->accessCheck()
->execute();
if ($existing_chapter_ids) {
$existing_chapter_id = reset($existing_chapter_ids);
/** @var \Drupal\node\NodeInterface $node */
$node = $this->entityTypeManager->getStorage('node')
->load($existing_chapter_id);
return $node;
}
return FALSE;
}
/**
* Create a new node.
*
* @param \Drupal\node\NodeInterface $reader_publication
* The publication.
* @param string $chapter_id
* The chapter ID from the EPUB.
* @param string $title
* The title of the chapter.
*
* @return \Drupal\node\NodeInterface
* The new node.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function createNewNode(
NodeInterface $reader_publication,
$chapter_id,
$title
) {
/** @var \Drupal\node\NodeInterface $node */
$node = Node::create([
'type' => 'reader_chapter',
'title' => $title,
'field_reader_publication' => $reader_publication->id(),
'field_reader_chapter_epub_id' => $chapter_id,
'field_reader_chapter_automated' => TRUE,
]);
$node->setPublished();
$node->save();
return $node;
}
}
