class DefaultFormattedTextHandler in CMS Content Sync 8
Same name and namespace in other branches
- 2.1.x src/Plugin/cms_content_sync/field_handler/DefaultFormattedTextHandler.php \Drupal\cms_content_sync\Plugin\cms_content_sync\field_handler\DefaultFormattedTextHandler
- 2.0.x src/Plugin/cms_content_sync/field_handler/DefaultFormattedTextHandler.php \Drupal\cms_content_sync\Plugin\cms_content_sync\field_handler\DefaultFormattedTextHandler
Providing a minimalistic implementation for any field type.
Plugin annotation
@FieldHandler(
id = "cms_content_sync_default_formatted_text_handler",
label = @Translation("Default Formatted Text"),
weight = 90
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\cms_content_sync\Plugin\FieldHandlerBase implements FieldHandlerInterface, ContainerFactoryPluginInterface
- class \Drupal\cms_content_sync\Plugin\cms_content_sync\field_handler\DefaultFormattedTextHandler
- class \Drupal\cms_content_sync\Plugin\FieldHandlerBase implements FieldHandlerInterface, ContainerFactoryPluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of DefaultFormattedTextHandler
File
- src/
Plugin/ cms_content_sync/ field_handler/ DefaultFormattedTextHandler.php, line 21
Namespace
Drupal\cms_content_sync\Plugin\cms_content_sync\field_handlerView source
class DefaultFormattedTextHandler extends FieldHandlerBase {
/**
* {@inheritdoc}
*/
public static function supports($entity_type, $bundle, $field_name, FieldDefinitionInterface $field) {
$allowed = [
'text_with_summary',
'text_long',
];
return false !== in_array($field
->getType(), $allowed);
}
/**
* {@inheritdoc}
*/
public function pull(PullIntent $intent) {
$action = $intent
->getAction();
/**
* @var \Drupal\Core\Entity\FieldableEntityInterface $entity
*/
$entity = $intent
->getEntity();
// Deletion doesn't require any action on field basis for static data.
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'])) {
// Replace node links correctly.
$item['value'] = $this
->replaceEntityReferenceLinks($item['value']);
}
$result[] = $item;
}
$entity
->set($this->fieldName, $result);
}
return true;
}
/**
* {@inheritdoc}
*/
public function push(PushIntent $intent) {
if (!parent::push($intent)) {
return false;
}
$entity = $intent
->getEntity();
$add_file_uri_dependency = function ($matches) use ($intent) {
// PDF files can have a #page=... anchor attached that we want to keep.
$path = preg_replace('@#.*$@', '', $matches[1]);
$uri = 'public://' . urldecode($path);
/** @var FileInterface[] $files */
$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'];
// Simple image embedding (default ckeditor + IMCE images)
preg_replace_callback('@<img[^>]+src="/' . $base_path . '/([^"]+)"@', $add_file_uri_dependency, $text);
// Other file embedding (IMCE files)
preg_replace_callback('@<a[^>]+href="/' . $base_path . '/([^"]+)"@', $add_file_uri_dependency, $text);
// Entity embedding (especially media)
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;
}
/**
* Replace all "/node/..." links with their correct ID for the current site.
*
* @todo If a new entity is added, we should scan the database for existing
* references to it that can now be resolved.
*
* @param $text
*
* @return string
*/
protected function replaceEntityReferenceLinks($text) {
$entity_repository = \Drupal::service('entity.repository');
$replace_uri_callback = function ($matches) {
$path = $matches[2];
// PDF files can have a #page=... anchor attached that we want to keep.
$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)));
/** @var FileInterface[] $files */
$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 . '"';
};
// Simple image embedding (default ckeditor + IMCE images)
$text = preg_replace_callback('@(<img[^>]+src=)"/sites/[^/]+/files/([^"]+)"@', $replace_uri_callback, $text);
// Other file embedding (IMCE files)
$text = preg_replace_callback('@(<a[^>]+href=)"/sites/[^/]+/files/([^"]+)"@', $replace_uri_callback, $text);
// Entity embedding (especially media)
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);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DefaultFormattedTextHandler:: |
public | function |
Overrides FieldHandlerBase:: |
|
DefaultFormattedTextHandler:: |
public | function |
Overrides FieldHandlerBase:: |
|
DefaultFormattedTextHandler:: |
protected | function | Replace all "/node/..." links with their correct ID for the current site. | |
DefaultFormattedTextHandler:: |
public static | function |
Check if this handler supports the given field instance. Overrides FieldHandlerInterface:: |
|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FieldHandlerBase:: |
protected | property | ||
FieldHandlerBase:: |
protected | property | ||
FieldHandlerBase:: |
protected | property | ||
FieldHandlerBase:: |
protected | property | ||
FieldHandlerBase:: |
protected | property | ||
FieldHandlerBase:: |
protected | property | A logger instance. | |
FieldHandlerBase:: |
protected | property | Additional settings as provided by { | |
FieldHandlerBase:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
FieldHandlerBase:: |
protected | function | 1 | |
FieldHandlerBase:: |
public | function |
Get the allowed pull options. Overrides FieldHandlerInterface:: |
|
FieldHandlerBase:: |
public | function |
Get the allowed push options. Overrides FieldHandlerInterface:: |
|
FieldHandlerBase:: |
public | function |
Overrides FieldHandlerInterface:: |
|
FieldHandlerBase:: |
public | function |
Get the handler settings. Overrides FieldHandlerInterface:: |
3 |
FieldHandlerBase:: |
public | function |
Validate the settings defined above. $form and $form_state are the same as
in the Form API. $settings_key is the index at $form['sync_entities'] for
this handler instance. Overrides FieldHandlerInterface:: |
1 |
FieldHandlerBase:: |
public | function |
Constructs a Drupal\rest\Plugin\ResourceBase object. Overrides PluginBase:: |
|
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |