You are here

class Dom in Migrate Plus 8.5

Same name and namespace in other branches
  1. 8.4 src/Plugin/migrate/process/Dom.php \Drupal\migrate_plus\Plugin\migrate\process\Dom

Handles string to DOM and back conversions.

Available configuration keys:

  • method: Action to perform. Possible values:

    • import: string to DomDocument.
    • export: DomDocument to string.
  • non_root: (optional) Assume the passed HTML is not a complete hierarchy, but only a subset inside body element. Defaults to true.

The following keys are only used if the method is 'import':

  • log_messages: (optional) When parsing HTML, libxml may trigger warnings. If this option is set to true, it will log them as migration messages. Otherwise, it will not handle it in a special way. Defaults to true.
  • version: (optional) The version number of the document as part of the XML declaration. Defaults to '1.0'.
  • encoding: (optional) The encoding of the document as part of the XML declaration. Defaults to 'UTF-8'.

@codingStandardsIgnoreStart

Examples:


process:
  'body/value':
    -
      plugin: dom
      method: import
      source: 'body/0/value'
    -
      plugin: dom
      method: export

This example above will convert the input string to a DOMDocument object and back, with no explicit processing. It should have few noticeable effects.


process:
  'body/value':
    -
      plugin: dom
      method: import
      source: 'body/0/value'
      non_root: true
      log_messages: true
      version: '1.0'
      encoding: UTF-8
    -
      plugin: dom
      method: export
      non_root: true

This example above will have the same effect as the previous example, since it specifies the default values for all the optional parameters.

@codingStandardsIgnoreEnd

Plugin annotation


@MigrateProcessPlugin(
  id = "dom"
)

Hierarchy

Expanded class hierarchy of Dom

1 file declares its use of Dom
DomTest.php in tests/src/Unit/process/DomTest.php

File

src/Plugin/migrate/process/Dom.php, line 74

Namespace

Drupal\migrate_plus\Plugin\migrate\process
View source
class Dom extends ProcessPluginBase {

  /**
   * If parsing warnings should be logged as migrate messages.
   *
   * @var bool
   */
  protected $logMessages = TRUE;

  /**
   * The HTML contains only the piece inside the body element.
   *
   * @var bool
   */
  protected $nonRoot = TRUE;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
    if (!isset($configuration['method'])) {
      throw new \InvalidArgumentException('The "method" must be set.');
    }
    if (!in_array($configuration['method'], [
      'import',
      'export',
    ])) {
      throw new \InvalidArgumentException('The "method" must be "import" or "export".');
    }
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->configuration += $this
      ->defaultValues();
    $this->logMessages = (bool) $this->configuration['log_messages'];
    $this->nonRoot = (bool) $this->configuration['non_root'];
  }

  /**
   * Supply default values of all optional parameters.
   *
   * @return array
   *   An array with keys the optional parameters and values the corresponding
   *   defaults.
   */
  protected function defaultValues() {
    return [
      'non_root' => TRUE,
      'log_messages' => TRUE,
      'version' => '1.0',
      'encoding' => 'UTF-8',
    ];
  }

  /**
   * Converts a HTML string into a DOMDocument.
   *
   * It is not using \Drupal\Component\Utility\Html::load() because it ignores
   * all errors on import, and therefore incompatible with log_messages
   * option.
   *
   * @param mixed $value
   *   The string to be imported.
   * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable
   *   The migration in which this process is being executed.
   * @param \Drupal\migrate\Row $row
   *   The row from the source to process. Normally, just transforming the value
   *   is adequate but very rarely you might need to change two columns at the
   *   same time or something like that.
   * @param string $destination_property
   *   The destination property currently worked on. This is only used together
   *   with the $row above.
   *
   * @return \DOMDocument
   *   The document object based on the provided string.
   *
   * @throws \Drupal\migrate\MigrateException
   *   When the received $value is not a string.
   */
  public function import($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    if (!is_string($value)) {
      throw new MigrateException('Cannot import a non-string value.');
    }
    if ($this->logMessages) {
      set_error_handler(static function ($errno, $errstr) use ($migrate_executable) {
        $migrate_executable
          ->saveMessage($errstr, MigrationInterface::MESSAGE_WARNING);
      });
    }
    if ($this->nonRoot) {
      $html = $this
        ->getNonRootHtml($value);
    }
    else {
      $html = $value;
    }
    $document = new \DOMDocument($this->configuration['version'], $this->configuration['encoding']);
    $document
      ->loadHTML($html);
    if ($this->logMessages) {
      restore_error_handler();
    }
    return $document;
  }

  /**
   * Converts a DOMDocument into a HTML string.
   *
   * @param mixed $value
   *   The document to be exported.
   * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable
   *   The migration in which this process is being executed.
   * @param \Drupal\migrate\Row $row
   *   The row from the source to process. Normally, just transforming the value
   *   is adequate but very rarely you might need to change two columns at the
   *   same time or something like that.
   * @param string $destination_property
   *   The destination property currently worked on. This is only used together
   *   with the $row above.
   *
   * @return string
   *   The HTML string corresponding to the provided document object.
   *
   * @throws \Drupal\migrate\MigrateException
   *   When the received $value is not a \DOMDocument.
   */
  public function export($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    if (!$value instanceof \DOMDocument) {
      $value_description = gettype($value) == 'object' ? get_class($value) : gettype($value);
      throw new MigrateException(sprintf('Cannot export a "%s".', $value_description));
    }
    if ($this->nonRoot) {
      return Html::serialize($value);
    }
    return $value
      ->saveHTML();
  }

  /**
   * Builds an full html string based on a partial.
   *
   * @param string $partial
   *   A subset of a full html string. For instance the contents of the body
   *   element.
   */
  protected function getNonRootHtml($partial) {
    $replacements = [
      "\n" => '',
      '!encoding' => strtolower($this->configuration['encoding']),
      '!value' => $partial,
    ];

    // Prepend the html with a header using the configured source encoding.
    // By default, loadHTML() assumes ISO-8859-1.
    $html_template = <<<EOD
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=!encoding" /></head>
<body>!value</body>
</html>
EOD;
    return strtr($html_template, $replacements);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
Dom::$logMessages protected property If parsing warnings should be logged as migrate messages.
Dom::$nonRoot protected property The HTML contains only the piece inside the body element.
Dom::defaultValues protected function Supply default values of all optional parameters.
Dom::export public function Converts a DOMDocument into a HTML string.
Dom::getNonRootHtml protected function Builds an full html string based on a partial.
Dom::import public function Converts a HTML string into a DOMDocument.
Dom::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase::__construct
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
ProcessPluginBase::multiple public function Indicates whether the returned value requires multiple handling. Overrides MigrateProcessInterface::multiple 3
ProcessPluginBase::transform public function Performs the associated process. Overrides MigrateProcessInterface::transform 70
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.