ssml-1.x-dev/src/Processor.php

src/Processor.php
<?php

declare(strict_types=1);

namespace Drupal\ssml;

use Drupal\Core\Extension\ModuleExtensionList;

/**
 * Converts HTML to SSML.
 */
class Processor {

  /**
   * Creates the processor.
   *
   * @param \Drupal\Core\Extension\ModuleExtensionList $moduleExtensionList
   *   The module extension list service.
   */
  public function __construct(
    protected readonly ModuleExtensionList $moduleExtensionList,
  ) {}

  /**
   * Converts HTML to SSML.
   *
   * @param string $html
   *   The HTML.
   * @param string|null $charset
   *   An optional character set to prepend to the HTML before parsing.
   * @param array<mixed> $context
   *   An array of context. Doesn't do anything yet, but can be used to tailor
   *   output based on provider.
   *
   * @return string
   *   An SSML string.
   *
   * @throws \RuntimeException
   *   On error.
   */
  public function htmlToSsml(string $html, ?string $charset = NULL, array $context = []): string {
    // @todo: Use \Dom\HTMLDocument when we can require PHP 8.4.
    // @todo: See if we can use masterminds/html5 in the meantime?

    $old_use_errors = libxml_use_internal_errors(true);
    try {
      $xslt_processor = new \XSLTProcessor();
      $xslt = new \DOMDocument();
      $xslt->loadXML($this->getXslt());

      if ($charset) {
        $html = "<meta charset=\"$charset\">$html";
      }
      $html_doc = new \DOMDocument();
      $html_doc->loadHTML($html);

      $result = $xslt_processor->importStyleSheet($xslt);
      if (!$result) {
        $message = $this->getXmlErrorsMessage();
        throw new \RuntimeException("Unable to transform to SSML: $message");
      }

      $ssml = $xslt_processor->transformToXML($html_doc);
      if ($ssml === FALSE) {
        $message = $this->getXmlErrorsMessage();
        throw new \RuntimeException("Unable to transform to SSML: $message");
      }
      return '<speak>' . $ssml . '</speak>';
    }
    finally {
      libxml_clear_errors();
      libxml_use_internal_errors($old_use_errors);
    }
  }

  /**
   * Get the SSML transformation as an XSLT string.
   *
   * @return string
   */
  protected function getXslt(): string {
    $path = $this->moduleExtensionList->getPath('ssml') . '/xslt/default.xslt';
    return file_get_contents($path) ?: throw new \RuntimeException("Couldn't read $path.");
  }

  /**
   * Returns any XML errors as a single string.
   *
   * @return string
   */
  protected function getXmlErrorsMessage(): string {
    $messages = array_map(fn(\LibXMLError $error): string => "$error->message ($error->file:$error->line)", libxml_get_errors());
    return implode(PHP_EOL, $messages);
  }

}

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

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