Skip to content

Instantly share code, notes, and snippets.

@alexpott
Created March 23, 2017 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexpott/0930c476f078427897354cb7e0f066ac to your computer and use it in GitHub Desktop.
Save alexpott/0930c476f078427897354cb7e0f066ac to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\custom_migration\Plugin\migrate\process;
use Drupal\Component\Utility\Html;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
/**
* If any of the conditions are met, we skip the current row.
*
* @MigrateProcessPlugin(
* id = "image_insert",
* handle_multiples = TRUE
* )
*/
class ImageInsert extends ProcessPluginBase {
/**
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $fileStorage;
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
// Prevent useless processing if there are no image-insert tags at all.
if (stripos($value, 'image-insert') !== FALSE) {
$dom = Html::load($value);
$xpath = new \DOMXPath($dom);
$items = $xpath->query('//div[@class and contains(concat(\' \', normalize-space(@class), \' \'), \' image-insert \')]');
/** @var \DomNode $item */
foreach ($items as $item) {
// Get the first image.
$image = $xpath->query(".//img", $item)->item(0);
if ($image === null) {
// There's no image. Nothing to do here.
continue;
}
// Get the caption.
$caption = $xpath->query('.//div[@class and contains(concat(\' \', normalize-space(@class), \' \'), \' image-insert-caption \')]', $item);
$captions = [];
foreach ($caption as $caption_item) {
$captions[] = $caption_item->textContent;
}
// Convert html entities into UTF-8 characters so &nbsp; is trimmed.
$caption = trim(html_entity_decode(implode(' ', $captions)));
if (!preg_match('/^\W*$/', $caption)) {
$image->setAttribute('data-caption', $caption);
}
// Set the aligment.
$class = $item->getAttribute('class');
if (strpos($class, 'image-insert-left') !== FALSE) {
$image->setAttribute('data-align', 'left');
}
elseif (strpos($class, 'image-insert-right') !== FALSE) {
$image->setAttribute('data-align', 'right');
}
$image->setAttribute('data-entity-type', "file");
$src = $image->getAttribute('src');
// Make the URL relative just in case.
$http_host = 'HTTP_HOST_SHOULD_BE_CONFIGURABLE';
$src = str_replace('/sites/all/files/', '/sites/default/files/', $src);
$src = preg_replace('|^https?://' . $http_host . '|', '', $src);
$image->setAttribute('src', $src);
// Need to look up the file to add the data-entity-uuid attribute.
$src = str_replace('/sites/default/files/', 'public://', $src);
$this->fileStorage = \Drupal::entityTypeManager()->getStorage('file');
$file = $this->fileStorage->loadByProperties(['uri' => urldecode($src)]);
$file = reset($file);
if ($file) {
$image->setAttribute('data-entity-uuid', $file->uuid());
}
// If the image is wrapped in an A tag, preserve that.
$image_parent = $image->parentNode;
if ($image_parent->tagName === 'a') {
$clone = $image_parent->cloneNode(TRUE);
}
else {
$clone = $image->cloneNode(TRUE);
}
// Return the new HTML.
$item->parentNode->replaceChild($clone, $item);
}
$value = Html::serialize($dom);
}
return $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment