View source
<?php
namespace Drupal\cms_content_sync\Plugin\cms_content_sync\field_handler;
use Drupal\cms_content_sync\Plugin\FieldHandlerBase;
use Drupal\cms_content_sync\PullIntent;
use Drupal\cms_content_sync\PushIntent;
use Drupal\cms_content_sync\SyncIntent;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\StreamWrapper\PublicStream;
class DefaultFormattedTextHandler extends FieldHandlerBase {
public static function supports($entity_type, $bundle, $field_name, FieldDefinitionInterface $field) {
$allowed = [
'text_with_summary',
'text_long',
];
return false !== in_array($field
->getType(), $allowed);
}
public function pull(PullIntent $intent) {
$action = $intent
->getAction();
$entity = $intent
->getEntity();
if (SyncIntent::ACTION_DELETE == $action) {
return false;
}
if ($intent
->shouldMergeChanges()) {
return false;
}
$data = $intent
->getProperty($this->fieldName);
if (empty($data)) {
$entity
->set($this->fieldName, null);
}
else {
$result = [];
foreach ($data as $item) {
if (!empty($item['value'])) {
$item['value'] = $this
->replaceEntityReferenceLinks($item['value']);
}
$result[] = $item;
}
$entity
->set($this->fieldName, $result);
}
return true;
}
public function push(PushIntent $intent) {
if (!parent::push($intent)) {
return false;
}
$entity = $intent
->getEntity();
$add_file_uri_dependency = function ($matches) use ($intent) {
$path = preg_replace('@#.*$@', '', $matches[1]);
$uri = 'public://' . urldecode($path);
$files = \Drupal::entityTypeManager()
->getStorage('file')
->loadByProperties([
'uri' => $uri,
]);
if (!count($files)) {
\Drupal::logger('cms_content_sync')
->error('Failed to push referenced file by URI in the formatted text as the file is missing on this site: @uri<br>Flow: @flow_id | Pool: @pool_id', [
'@uri' => $uri,
'@flow_id' => $intent
->getFlow()
->id(),
'@pool_id' => $intent
->getPool()
->id(),
]);
return '';
}
$file = reset($files);
$intent
->addDependency($file);
return '';
};
$base_path = PublicStream::basePath();
foreach ($entity
->get($this->fieldName)
->getValue() as $item) {
$text = $item['value'];
preg_replace_callback('@<img[^>]+src="/' . $base_path . '/([^"]+)"@', $add_file_uri_dependency, $text);
preg_replace_callback('@<a[^>]+href="/' . $base_path . '/([^"]+)"@', $add_file_uri_dependency, $text);
preg_replace_callback('@<drupal-(entity|media)[^>]+data-entity-type="([^"]+)"\\s+data-entity-uuid="([^"]+)"@', function ($matches) use ($intent) {
$type = $matches[2];
$uuid = $matches[3];
$entity = \Drupal::service('entity.repository')
->loadEntityByUuid($type, $uuid);
if (!$entity) {
return '';
}
$intent
->addDependency($entity);
return '';
}, $text);
}
return true;
}
protected function replaceEntityReferenceLinks($text) {
$entity_repository = \Drupal::service('entity.repository');
$replace_uri_callback = function ($matches) {
$path = $matches[2];
$anchor = null;
if (false !== strpos($path, '#')) {
list($path, $anchor) = explode('#', $path);
}
$parts = explode('/', $path);
$file = null;
$uri = null;
for ($i = 0; $i < count($parts); ++$i) {
$uri = 'public://' . urldecode(implode('/', array_slice($parts, $i)));
$files = \Drupal::entityTypeManager()
->getStorage('file')
->loadByProperties([
'uri' => $uri,
]);
if (count($files)) {
$file = reset($files);
break;
}
}
if (!$file) {
\Drupal::logger('cms_content_sync')
->error('Failed to replace file URI in the formatted text as the file is missing on this site: @uri', [
'@uri' => 'public://' . urldecode($path),
]);
return $matches[1] . '"/404"';
}
$url = file_url_transform_relative(file_create_url($uri));
if ($anchor) {
$url .= '#' . $anchor;
}
return $matches[1] . '"' . $url . '"';
};
$text = preg_replace_callback('@(<img[^>]+src=)"/sites/[^/]+/files/([^"]+)"@', $replace_uri_callback, $text);
$text = preg_replace_callback('@(<a[^>]+href=)"/sites/[^/]+/files/([^"]+)"@', $replace_uri_callback, $text);
return preg_replace_callback('@data-entity-uuid="([0-9a-z-]+)" href="/node/([0-9]+)"@', function ($matches) use ($entity_repository) {
$uuid = $matches[1];
$id = $matches[2];
try {
$node = $entity_repository
->loadEntityByUuid('node', $uuid);
if ($node) {
$id = $node
->id();
}
} catch (\Exception $e) {
}
return 'data-entity-uuid="' . $uuid . '" href="/node/' . $id . '"';
}, $text);
}
}