epub_reader_framework-2.0.0-alpha2/src/Entity/ReaderEntityChapterHeadingsSave.php

src/Entity/ReaderEntityChapterHeadingsSave.php
<?php

namespace Drupal\epub_reader_framework\Entity;

use Drupal\Component\Render\MarkupInterface;
use Drupal\Component\Utility\DeprecationHelper;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Wa72\HtmlPageDom\HtmlPageCrawler;

/**
 * Class ReaderEntityChapterHeadingsSave.
 */
class ReaderEntityChapterHeadingsSave {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Storage for heading order.
   *
   * @var int
   */
  protected $order = 1;

  /**
   * Storage for found headings.
   *
   * @var array
   */
  protected $headings = [];

  /**
   * 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')
    );
  }

  /**
   * Save all h2s into the reader chapter heading storage.
   *
   * @param \Drupal\node\NodeInterface $reader_publication
   *   The reader publication node.
   * @param \Drupal\node\NodeInterface $reader_chapter
   *   The reader chapter node.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Drupal\Core\Theme\MissingThemeDependencyException
   */
  public function saveHeadings(
    NodeInterface $reader_publication,
    NodeInterface $reader_chapter
  ) {
    if ($output = $this->getRenderedNodeOutput($reader_chapter)) {
      $this->determineHeadings($output, $reader_chapter);
      $this->deleteExistingHeadings($reader_publication, $reader_chapter);
      $this->saveNewHeadings($reader_publication, $reader_chapter);
    }
  }

  /**
   * Get the rendered markup for the chapter.
   *
   * @param \Drupal\node\NodeInterface $reader_chapter
   *   The reader chapter node.
   *
   * @return string
   *   The markup of the rendered node.
   *
   * @throws \Drupal\Core\Theme\MissingThemeDependencyException
   */
  protected function getRenderedNodeOutput(NodeInterface $reader_chapter) {
    $render = \Drupal::entityTypeManager()->getViewBuilder('node')->view($reader_chapter, 'full');
    /** @var \Drupal\Core\Render\Renderer $renderer */
    $renderer = \Drupal::service('renderer');

    // Set the active theme to the default theme.
    /** @var \Drupal\Core\Theme\ThemeInitialization $theme_initialization */
    $theme_initialization = \Drupal::service('theme.initialization');
    $default_theme = \Drupal::config('system.theme')->get('default');
    $original_active_theme = \Drupal::theme()->getActiveTheme();
    \Drupal::theme()->setActiveTheme($theme_initialization->getActiveThemeByName($default_theme));

    // Render the node with the default theme.
    $output = DeprecationHelper::backwardsCompatibleCall(
      \Drupal::VERSION,
      '10.3',
      fn() => $renderer->renderInIsolation($render),
      fn() => $renderer->renderPlain($render),
    );
    if ($output instanceof MarkupInterface) {
      $output = $output->__toString();
    }

    // Reset the active theme.
    \Drupal::theme()->setActiveTheme($original_active_theme);
    return (is_string($output) ? $output : '');
  }

  /**
   * Determine all h2s from the chapter.
   *
   * @param string $output
   *   The rendered markup of the chapter.
   * @param \Drupal\node\NodeInterface $reader_chapter
   *   The reader chapter node.
   */
  public function determineHeadings($output, NodeInterface $reader_chapter) {
    // Get all headings within the content area.
    $this->headings = [];
    $this->order = 1;
    $self = $this;
    $crawler = new HtmlPageCrawler($output);
    $crawler->filter('#js-epub-reader-framework-content h2')
      ->each(function (HtmlPageCrawler $node, $i) use ($self, $reader_chapter) {
        $text = $node->getCombinedText();
        $text = preg_replace('/[ ]{2,}|[\t]/', ' ', trim($text));
        $text = trim($text);
        if ($reader_chapter->label() != $text) {
          $self->headings[$self->order] = $text;
          $self->order++;
        }
      });
  }

  /**
   * Delete existing reader chapter headings for this chapter.
   *
   * @param \Drupal\node\NodeInterface $reader_publication
   *   The reader publication node.
   * @param \Drupal\node\NodeInterface $reader_chapter
   *   The reader chapter node.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function deleteExistingHeadings(
    NodeInterface $reader_publication,
    NodeInterface $reader_chapter
  ) {
    // Delete existing headings within this chapter and publication.
    $storage = $this->entityTypeManager->getStorage('reader_chapter_heading');
    $query = $storage->getQuery();
    $query->condition('reader_publication_id', $reader_publication->id());
    $query->condition('reader_chapter_id', $reader_chapter->id());
    $query->accessCheck();
    $chapter_heading_ids = $query->execute();
    if ($chapter_heading_ids && $chapter_headings = $storage->loadMultiple($chapter_heading_ids)) {
      foreach ($chapter_headings as $chapter_heading) {
        $chapter_heading->delete();
      }
    }
  }

  /**
   * Save the new h2s into the reader chapter heading storage.
   *
   * @param \Drupal\node\NodeInterface $reader_publication
   *   The reader publication node.
   * @param \Drupal\node\NodeInterface $reader_chapter
   *   The reader chapter node.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function saveNewHeadings(
    NodeInterface $reader_publication,
    NodeInterface $reader_chapter
  ) {
    // Save new headings.
    if ($this->headings) {
      $storage = $this->entityTypeManager->getStorage('reader_chapter_heading');
      foreach ($this->headings as $order => $heading) {
        $chapter_heading = $storage->create([
          'reader_publication_id' => $reader_publication->id(),
          'reader_chapter_id' => $reader_chapter->id(),
          'order' => $order,
          'heading' => $heading,
        ]);
        $chapter_heading->save();
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc